本文主要是介绍基于51单片机车速测量控制,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
基于51单片机车速测量控制
(仿真+程序)
功能介绍
具体功能:
1.通过L298驱动直流电机模拟转动;
2.LCD1602显示转动状态和速度;
3.按键可以控制启动/停止、加/减速、正/反转;
演示视频:
基于51单片机车速测量控制
添加图片注释,不超过 140 字(可选)
程序
#include <REG52.H>
#include <intrins.h>#define uchar unsigned char //宏定义方便以后用
#define uint unsigned int
#define ulong unsigned long
#define CLK_WISE 0//顺时针方向转动
#define INVERSE 1//逆时针方向转动
#define HIGH 2//高电平
#define LOW 1//低电平
#define NULL 0//低电平uchar levelflag=0;//高低电平标志,取值为HIGH或LOW,分别代表高电平和低电平,或为NULL
bit direction=CLK_WISE;/***方向标志,取值为CLK_WISE 或INVERSE*/
char speedcount=1;//加速标志,越大转速越快,最大到10循环。//程序中可以依据它来改变占空比
uchar highcount; //记录高电平定时次数
bit start_flag=0; //启动标志
int Motor_speed=0;//电机的速度uchar motor_time_count=0;
sbit CTRL0=P1^0;//CTRL0为高电平,CTRL1为低电平时顺时针方向转动
sbit CTRL1=P1^1;//CTRL0为低电平,CTRL1为高电平时逆时针方向转动
//定义按键的接口
sbit K1= P2^5;
sbit K2= P2^6;
sbit K3= P2^7;
sbit K4= P3^0;
sbit K5= P3^1;//LCD port
sbit LcdRs= P2^0;
sbit LcdRw= P2^1;
sbit LcdEn= P2^2;
sfr DBPort= 0x80; //P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口//向LCD写入命令或数据************************************************************
#define LCD_COMMAND 0 // Command
#define LCD_DATA 1 // Data
#define LCD_CLEAR_SCREEN 0x01 // 清屏
#define LCD_HOMING 0x02 // 光标返回原点//设置显示模式************************************************************
#define LCD_SHOW 0x04 //显示开
#define LCD_HIDE 0x00 //显示关 #define LCD_CURSOR 0x02 //显示光标
#define LCD_NO_CURSOR 0x00 //无光标 #define LCD_FLASH 0x01 //光标闪动
#define LCD_NO_FLASH 0x00 //光标不闪动
//内部等待函数**************************************************************************
unsigned char LCD_Wait(void)
{LcdRs=0;LcdRw=1; _nop_();LcdEn=1; _nop_();//while(DBPort&0x80);//在用Proteus仿真时,注意用屏蔽此语句,在调用GotoXY()时,会进入死循环,//可能在写该控制字时,该模块没有返回写入完备命令,即DBPort&0x80==0x80//实际硬件时打开此语句LcdEn=0;return DBPort;
}void LCD_Write(bit style, unsigned char input)
{LcdEn=0;LcdRs=style;LcdRw=0; _nop_();DBPort=input; _nop_();//注意顺序LcdEn=1; _nop_();//注意顺序LcdEn=0; _nop_();LCD_Wait();
}void LCD_SetDisplay(unsigned char DisplayMode)
{LCD_Write(LCD_COMMAND, 0x08|DisplayMode);
}//设置输入模式************************************************************
#define LCD_AC_UP 0x02
#define LCD_AC_DOWN 0x00 // default#define LCD_MOVE 0x01 // 画面可平移
#define LCD_NO_MOVE 0x00 //defaultvoid LCD_SetInput(unsigned char InputMode)
{LCD_Write(LCD_COMMAND, 0x04|InputMode);
}//初始化LCD************************************************************
void LCD_Initial()
{LcdEn=0;LCD_Write(LCD_COMMAND,0x38); //8位数据端口,2行显示,5*7点阵LCD_Write(LCD_COMMAND,0x38);LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR); //开启显示, 无光标LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN); //清屏LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE); //AC递增, 画面不动
}//************************************************************************
void GotoXY(unsigned char x, unsigned char y)
{if(y==0)LCD_Write(LCD_COMMAND,0x80|x);if(y==1)LCD_Write(LCD_COMMAND,0x80|(x-0x40));
}void Print(unsigned char *str) //在LCD上显示数据,内部调用
{while(*str!='\0'){LCD_Write(LCD_DATA,*str);str++;}
}void LCD_Print(unsigned char x, unsigned char y, unsigned char *str) //指定的位置打印指定数据
{GotoXY(x,y);Print(str);
}void LCD_Print_num(unsigned char x, unsigned char y,long int num) //指定的位置显示数值
{uchar temp_tab[7]=0;uchar i=0;GotoXY(x,y);if(num<0){num=0-num;LCD_Write(LCD_DATA,'-');}temp_tab[0]=num/1000000%10+0x30;temp_tab[1]=num/100000%10+0x30;temp_tab[2]=num/10000%10+0x30;temp_tab[3]=num/1000%10+0x30;temp_tab[4]=num/100%10+0x30; temp_tab[5]=num/10%10+0x30;temp_tab[6]=num%10+0x30;for(i=0;i<7;i++){if(temp_tab[i]!=0x30)break;}if(i==7){LCD_Write(LCD_DATA,0x30);}else{while(i<7){LCD_Write(LCD_DATA,temp_tab[i]);i++;}}
}/****延时****/
void delay(uint i)
{while(i--);
}/*****改变转向*****/
void run(void)
{if(direction==CLK_WISE) //顺时针转{CTRL1=0;if(levelflag==HIGH)//高电平{levelflag=NULL;CTRL0=1;}if(levelflag==LOW)//低电平{levelflag=NULL;CTRL0=0;}}if(direction==INVERSE) //逆时针转{CTRL0=0;if(levelflag==HIGH)//高电平{levelflag=NULL;CTRL1=1;}if(levelflag==LOW)//低电平{levelflag=NULL;CTRL1=0;}}}
//*********************************
//按键扫描程序
//mode:0,不支持连续按;1,支持连续按;
//*********************************
uchar KEY_Scan(uchar mode)
{ static uchar key_up=1;//按键按松开标志if(mode)key_up=1; //支持连按 if(key_up&&(K1==0||K2==0||K3==0||K4==0||K5==0)){delay(5);//去抖动 key_up=0;if(K1==0)return 1;else if(K2==0)return 2;else if(K3==0)return 3;else if(K4==0)return 4;else if(K5==0)return 5;}else if(K1==1&&K2==1&&K3==1&&K4==1&&K5==1)key_up=1; return 0;// 无按键按下
}
//******************************
//**定时器初始化
//******************************
void Time_Init(void)
{TMOD=0x15;ET0=0;//定时器0初始化TR0=1;TH1=(65536-10000)/256;//0xff;TL1=(65536-10000)%256;//0xCE;ET1=1;TR1=1;EA=1;
}
//*****************************
//**显示数据
//*****************************
void Display_data(void)
{ if(start_flag==0){LCD_Print(0,0,"Direction: STOP "); //显示正转LCD_Print(0,1,"Speed:"); //显示速度LCD_Print_num(0,2,Motor_speed);LCD_Print(0,3,"m/min ");}else{if(direction==0) //正转{LCD_Print(0,0,"Direction: FWD "); //显示正转LCD_Print(0,1,"Speed:+"); //显示速度LCD_Print_num(0,2,Motor_speed);LCD_Print(0,3,"m/min");}else{LCD_Print(0,0,"Direction: REV "); //显示反转LCD_Print(0,1,"Speed:-"); //显示速度LCD_Print_num(0,2,Motor_speed);LCD_Print(0,3,"m/min");}}
}void main()
{ uchar Key_num=0;LCD_Initial();Time_Init();LCD_Print(0,0,"Hello"); //LCD_Print(0,1,"Welcome to use!"); //显示欢迎delay(60000); //延时delay(60000);delay(60000);delay(60000);while(1){Key_num = KEY_Scan(0); //扫描按键switch(Key_num){case 1://启动start_flag=1;break;case 2://加速speedcount++;//记录加减速次数 if(speedcount>10)speedcount=10;//最大为10,然后从0开始循环。break;case 3://减速speedcount--;//记录加减速次数 if(speedcount<1)speedcount=0;//最大为10,然后从0开始循环。break;case 4: //反转direction=!direction;break;case 5: //停止start_flag=0;break;}if(start_flag) //启动{run();}else //停止{CTRL0=0;CTRL1=0;}if(motor_time_count>=30) //30*10=300ms{motor_time_count=0;Motor_speed=((TH0<<8)+TL0);//r/minMotor_speed=Motor_speed*1.9;TH0=0;TL0=0; }Display_data();}
}
硬件设计
使用元器件:
单片机:AT89C52;
(注意:单片机是通用的,无论51还是52、无论stc还是at都一样,引脚功能都一样。程序也是一样的。)
添加图片注释,不超过 140 字(可选)
设计资料
01仿真图
本设计使用proteus7.8和proteus8.9两个版本设计!具体如图!
添加图片注释,不超过 140 字(可选)
02程序
本设计使用软件keil5版本编程设计!具体如图!
添加图片注释,不超过 140 字(可选)
03设计资料
资料获取请关注同名公众号,全部资料包括仿真源文件 、程序(含注释)等。具体内容如下,全网最全! !
资料获取请观看前面演示视频!
点赞分享一起学习成长。
这篇关于基于51单片机车速测量控制的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!