基于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

相关文章

浅析如何使用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

Python实现局域网远程控制电脑

《Python实现局域网远程控制电脑》这篇文章主要为大家详细介绍了如何利用Python编写一个工具,可以实现远程控制局域网电脑关机,重启,注销等功能,感兴趣的小伙伴可以参考一下... 目录1.简介2. 运行效果3. 1.0版本相关源码服务端server.py客户端client.py4. 2.0版本相关源码1

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

day-51 合并零之间的节点

思路 直接遍历链表即可,遇到val=0跳过,val非零则加在一起,最后返回即可 解题过程 返回链表可以有头结点,方便插入,返回head.next Code /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}*

基于51单片机的自动转向修复系统的设计与实现

文章目录 前言资料获取设计介绍功能介绍设计清单具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订阅👇🏻 单片机

控制反转 的种类

之前对控制反转的定义和解释都不是很清晰。最近翻书发现在《Pro Spring 5》(免费电子版在文章最后)有一段非常不错的解释。记录一下,有道翻译贴出来方便查看。如有请直接跳过中文,看后面的原文。 控制反转的类型 控制反转的类型您可能想知道为什么有两种类型的IoC,以及为什么这些类型被进一步划分为不同的实现。这个问题似乎没有明确的答案;当然,不同的类型提供了一定程度的灵活性,但

单片机毕业设计基于单片机的智能门禁系统的设计与实现

文章目录 前言资料获取设计介绍功能介绍程序代码部分参考 设计清单具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订

深入解析秒杀业务中的核心问题 —— 从并发控制到事务管理

深入解析秒杀业务中的核心问题 —— 从并发控制到事务管理 秒杀系统是应对高并发、高压力下的典型业务场景,涉及到并发控制、库存管理、事务管理等多个关键技术点。本文将深入剖析秒杀商品业务中常见的几个核心问题,包括 AOP 事务管理、同步锁机制、乐观锁、CAS 操作,以及用户限购策略。通过这些技术的结合,确保秒杀系统在高并发场景下的稳定性和一致性。 1. AOP 代理对象与事务管理 在秒杀商品

PostgreSQL中的多版本并发控制(MVCC)深入解析

引言 PostgreSQL作为一款强大的开源关系数据库管理系统,以其高性能、高可靠性和丰富的功能特性而广受欢迎。在并发控制方面,PostgreSQL采用了多版本并发控制(MVCC)机制,该机制为数据库提供了高效的数据访问和更新能力,同时保证了数据的一致性和隔离性。本文将深入解析PostgreSQL中的MVCC功能,探讨其工作原理、使用场景,并通过具体SQL示例来展示其在实际应用中的表现。 一、