|
程序出问题了,电机转不了,显示也出不来。单片机新手,看不出哪儿出了问题。麻烦论坛里能帮忙朋友们帮我看看,谢谢
#include"reg51.h"
#define uchar unsigned char
#define uint unsigned int
sbit k1=P1^0; //启停按键K1
sbit k2=P3^2; //正反转按键K2
sbit up=P1^2; //加速按键up
sbit down=P1^3; //减速按键down
sbit in1=P1^5; //正反转输入口
sbit in2=P1^6;
sbit ENA=P1^7; //PWM信号输入口
sbit LED1=P2^3; //绿灯正转
sbit LED2=P2^4; //红灯反转
uchar a=0;
uchar count=48; //速度上限
uchar t=0;
char speed=20; //初始速度
uint qt;
/*-----------------------端口命名------------------------*/
sbit rs=P2^0; //LCD的数据/命令选择端
sbit rw=P2^1; //LCD的读写选择端
sbit e=P2^2; //LCD的使能信号端
/*-------------------------------------------------------*/
/*-----------------------定义参数------------------------*/
uint i,z,count,zhuan,msec; //定义参数
uchar display[]={" speed= r/min "}; //定义显示参数
/*-------------------------------------------------------*/
/*-----------------------正反转延时函数------------------*/
viod delay(void)
{
uchar i,j,k;
for(i=50;i>0;i--)
{
for(j=200;j>0;j--)
for(k=230;k>0;k--)
}
}
/*------------------------------------------------------*/
/*-----------------------启停函数------------------------*/
void qiting(uint b) //b为启停标志
{
if(k1==0)
{
ENA=1;
b=1;
}
else
{
ENA=0;
b=0;
}
return b;
}
/*-------------------------------------------------------*/
/*-----------------------正反转函数----------------------*/
void INTT0_zhengfan() interrupt 2
{
a++;
if(a==1) //正转
{
LED1=1;
LED2=0;
ENA=0;
delay();
ENA=1;
in1=1;
in2=0;
}
else //反转
{
LED1=0;
LED2=1;
ENA=0;
delay();
ENA=1;
in1=0;
in2=1;
}
if(a>=2)
{
a=0;
}
}
/*--------------------------------------------------------*/
/*-----------------------增减速函数-----------------------*/
void speed_control()
{
if(up==0) //增速
{
speed++;
while(up==0) //即时对计满数的speed值控制在设定范围之内
if(speed>count)speed=count;
}
if(down==0) //减速
{
speed--;
while(down==0)
if(speed<0)speed=0;
}
}
/*----------------------------------------------------------------------------*/
/*-------输出PWM的定时器中断(与增减函数配合输出PWM信号)---------------------*/
void timer0_PWM() interrupt 3 //计满1ms跳一次,有speed个之后PWM跳变
{
if(t<speed) ENA=1;
else ENA=0;
t++;
if(t>=count)t=0;
}
/*-------------------------------------------------------*/
/*-----------------------毫秒延时------------------------*/
void delay1(uint ms)
{
uint i,j; //为延时引入i,j两参数
for (j=0;j<ms;j++) //延时第一循环
for (i=0;i<120;i++); //延时第二循环
}
/*-------------------------------------------------------*/
/*--------------------向LCD1602写命令--------------------*/
void write_command(uchar command)
{
rs=0; //数据、命令选择端0为命令
rw=0; //读、写选择端0为写
P0=command; //向LCD写命令
delay1(5); //稍做延迟,代替检测忙状态
e=1; //信号使能端高电平
delay1(5); //稍做延迟,代替检测忙状态
e=0; //信号使能端低电平
}
/*-------------------------------------------------------*/
/*--------------------向LCD1602写数据--------------------*/
void write_data(uchar data0)
{
rs=1; //数据、命令选择端 1为数据
rw=0; //读、写选择端0为写
P0=data0; //向LCD写数据
delay1(5); //稍做延迟,代替检测忙状态
e=1; //信号使能端高电平
delay1(5); //稍做延迟,代替检测忙状态
e=0; //信号使能端低电平
}
/*-------------------------------------------------------*/
/*-------------------外部中断0计数程序-------------------*/
void counter(void) interrupt 0
{
count++;
if(count==2) //2次循环为发动机转一圈
{
count=0; //初始化计数
z++; //转圈计数加1
}
}
/*-------------------------------------------------------*/
/*------------------------LCD显示------------------------*/
void displaytolcd()
{
write_command(0x80); //向LCD1602写命令80H
for (i=0;i<sizeof(display)-1;i++) //循环要传输的字符个数次,每一次传一个字符
{
write_data(display);
delay(5);
}
}
/*-------------------------------------------------------*/
/*-----------------内部中断0计时计数程序-----------------*/
void Timer_0(void) interrupt 1
{
TH0=0x3c; //50ms定时
TL0=0xb0;
msec++;
if(msec==20) //50*20=1S
{
msec=0;
zhuan=60*z; //每分钟转速
displaytolcd();
count=0;
z=0;
}
}
/*-------------------------------------------------------*/
/*----------------------端口初始化-----------------------*/
void int_all()
{
z=0; //初始化z的值
count=0; //初始化count的值
zhuan=0; //初始化转的值
rw=0; //选择LCD写数据指令
delay1(15); //延时15ms
write_command(0x38); //向LCD1602写命令38H
delay1(5); //延时5ms
write_command(0x0e); //向LCD1602写命令0EH
delay1(5); //延时5ms
write_command(0x06); //向LCD1602写命令06H
TMOD=0x21; //内部中断定时器选择;定时器0工作在方式1,定时器1工作在方式2
TH0=0x3c; //50ms定时
TL0=0xb0;
TH1=0xF7; //
TL1=0xF7;
EA=1; //开中断总开关
IT0=1; //外部中断0为下降沿触发
ET0=1; //开内部中断0
TR0=1; //计时器开始工作
EX0=1; //开外部中断0
IT1=1; //外部中断1为下降沿触发
ET1=1;
TR1=1;
EX1=1;
}
/*-------------------------------------------------------*/
/*-----------------------数据处理------------------------*/
void disp_count()
{
display[9]=(zhuan/1000+'0'); //转换转速的千位
display[10]=(zhuan/100%10+'0'); //转换转速的百位
display[11]=(zhuan/10%10+'0'); //转换转速的十位
display[12]=(zhuan%10+'0'); //转换转速的个位
}
void main()
{
int_all();
while(1)
{
qiting(qt);
if(qt==1)
{
speed_control();
}
disp_count(); //数据处理
displaytolcd(); //LCD显示
}
}
|
-
1.jpg
(124.67 KB, 下载次数: 119)
这是仿真的图
|