基于51单片机车速测量控制
(仿真+程序)
功能介绍
具体功能:
1.通过L298驱动直流电机模拟转动;
2.LCD1602显示转动状态和速度;
3.按键可以控制启动/停止、加/减速、正/反转;
演示视频:
<iframe allowfullscreen="true" data-mediaembed="bilibili" frameborder="0" id="H7vJdHSY-1717641914137" src="https://player.bilibili.com/player.html?aid=1605429221"></iframe>基于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 //default
void 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/min
Motor_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设计资料
资料获取请关注同名公众号,全部资料包括仿真源文件 、程序(含注释)等。具体内容如下,全网最全! !
资料获取请观看前面演示视频!
点赞分享一起学习成长。
标签:Write,51,unsigned,车速,char,单片机,LCD,sbit,define From: https://blog.csdn.net/2401_82402501/article/details/139521816