基于51单片机车速测量控制

2024-06-08 02:20

本文主要是介绍基于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单片机车速测量控制的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1040963

相关文章

用js控制视频播放进度基本示例代码

《用js控制视频播放进度基本示例代码》写前端的时候,很多的时候是需要支持要网页视频播放的功能,下面这篇文章主要给大家介绍了关于用js控制视频播放进度的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言html部分:JavaScript部分:注意:总结前言在javascript中控制视频播放

Python异步编程中asyncio.gather的并发控制详解

《Python异步编程中asyncio.gather的并发控制详解》在Python异步编程生态中,asyncio.gather是并发任务调度的核心工具,本文将通过实际场景和代码示例,展示如何结合信号量... 目录一、asyncio.gather的原始行为解析二、信号量控制法:给并发装上"节流阀"三、进阶控制

使用DrissionPage控制360浏览器的完美解决方案

《使用DrissionPage控制360浏览器的完美解决方案》在网页自动化领域,经常遇到需要保持登录状态、保留Cookie等场景,今天要分享的方案可以完美解决这个问题:使用DrissionPage直接... 目录完整代码引言为什么要使用已有用户数据?核心代码实现1. 导入必要模块2. 关键配置(重点!)3.

SpringSecurity 认证、注销、权限控制功能(注销、记住密码、自定义登入页)

《SpringSecurity认证、注销、权限控制功能(注销、记住密码、自定义登入页)》SpringSecurity是一个强大的Java框架,用于保护应用程序的安全性,它提供了一套全面的安全解决方案... 目录简介认识Spring Security“认证”(Authentication)“授权” (Auth

python之流程控制语句match-case详解

《python之流程控制语句match-case详解》:本文主要介绍python之流程控制语句match-case使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录match-case 语法详解与实战一、基础值匹配(类似 switch-case)二、数据结构解构匹

Spring Security注解方式权限控制过程

《SpringSecurity注解方式权限控制过程》:本文主要介绍SpringSecurity注解方式权限控制过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、摘要二、实现步骤2.1 在配置类中添加权限注解的支持2.2 创建Controller类2.3 Us

Python中如何控制小数点精度与对齐方式

《Python中如何控制小数点精度与对齐方式》在Python编程中,数据输出格式化是一个常见的需求,尤其是在涉及到小数点精度和对齐方式时,下面小编就来为大家介绍一下如何在Python中实现这些功能吧... 目录一、控制小数点精度1. 使用 round() 函数2. 使用字符串格式化二、控制对齐方式1. 使用

Springboot控制反转与Bean对象的方法

《Springboot控制反转与Bean对象的方法》文章介绍了SpringBoot中的控制反转(IoC)概念,描述了IoC容器如何管理Bean的生命周期和依赖关系,它详细讲解了Bean的注册过程,包括... 目录1 控制反转1.1 什么是控制反转1.2 SpringBoot中的控制反转2 Ioc容器对Bea

浅析如何使用Swagger生成带权限控制的API文档

《浅析如何使用Swagger生成带权限控制的API文档》当涉及到权限控制时,如何生成既安全又详细的API文档就成了一个关键问题,所以这篇文章小编就来和大家好好聊聊如何用Swagger来生成带有... 目录准备工作配置 Swagger权限控制给 API 加上权限注解查看文档注意事项在咱们的开发工作里,API

Spring IOC控制反转的实现解析

《SpringIOC控制反转的实现解析》:本文主要介绍SpringIOC控制反转的实现,IOC是Spring的核心思想之一,它通过将对象的创建、依赖注入和生命周期管理交给容器来实现解耦,使开发者... 目录1. IOC的基本概念1.1 什么是IOC1.2 IOC与DI的关系2. IOC的设计目标3. IOC