欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 资讯 > 【Proteus51单片机仿真】基于51单片机的汽车电动助力转向系统(包括代码讲解视频电流传感器、车速传感器、扭矩传感器、LCD12864显示模块)

【Proteus51单片机仿真】基于51单片机的汽车电动助力转向系统(包括代码讲解视频电流传感器、车速传感器、扭矩传感器、LCD12864显示模块)

2025/5/7 23:37:16 来源:https://blog.csdn.net/weixin_70360261/article/details/142311561  浏览:    关键词:【Proteus51单片机仿真】基于51单片机的汽车电动助力转向系统(包括代码讲解视频电流传感器、车速传感器、扭矩传感器、LCD12864显示模块)

目录

一、主要功能

二、硬件资源

三、程序编程

四、实现现象


一、主要功能

基于51单片机,三个电阻传感器链接ADC0832数模转换器分别代表扭矩、车速、电流。
如果扭矩不变,车速变小,L298N驱动电机速度加快,PWM调速
如果车速不变,扭矩越大,L298N驱动电机速度加快,PWM调速
如果扭矩方向发生变化,则电机方向发生改变
如果扭矩小于1N或车速大于90,电机不转
如果电流超过程序设置好的额定值,电机不转蜂鸣器报警
同时,扭矩,车速和电流通过LCD12864显示屏实时显示

仿真图:

编辑

二、硬件资源

基于KEIL5编写C++代码,PROTEUS8.15进行仿真,全部资源在页尾,提供安装包。

本系统由51单片机、电流传感器、车速传感器、扭矩传感器、报警系统、L298N驱动电机模块、按键模块、LCD12864显示模块组成。

51单片机是一种非常常用的单片机系列,其主要硬件组成如下:

1. 中央处理器(CPU):51单片机的CPU采用哈佛架构,包括一个8位的ALU(算术逻辑单元)、8位的寄存器、PC(程序计数器)以及其他控制逻辑。它能够执行单片机上的指令和进行算术和逻辑运算。

2. 存储器:51单片机通常包含两种主要的存储器,即ROM(只读存储器)和RAM(随机访问存储器)。ROM用于存储程序代码和常量数据,它是只读的,不可修改。RAM用于存储临时数据和变量。

3. 输入输出(I/O)口:51单片机通常包含多个I/O口,用于与外部设备进行数据的输入和输出。每个I/O口都可以配置为输入或输出模式,并且可以通过读写寄存器来控制和访问。

4. 定时器和计数器:51单片机通常包含多个定时器和计数器,用于生成精准的时间延迟和定期中断。这些定时器和计数器可以用于测量时间、计数脉冲和生成脉冲。

5. 中断系统:51单片机通常支持中断功能,用于响应外部事件或特定条件的发生。当中断事件发生时,CPU将会中断当前的执行,转而执行相应的中断服务程序。中断能够提高系统的响应速度和效率。

6. 时钟:51单片机通常需要外部时钟源来提供基本的时钟信号,以驱动CPU执行指令。时钟信号的频率决定了单片机的工作速度和性能。

以上是51单片机的主要硬件组成,通过这些组件的协作,单片机能够完成各种任务,包括控制和处理数据、驱动外部设备、读写存储器等。

三、程序编程

/*全部代码看页尾*/
#include <REGX52.H>
#include<intrins.h>
#include<stdio.h>
#include < character.h >
#include < lcd.h >
#define uchar unsigned char
#define uint unsigned  int
typedef unsigned char u8;
typedef unsigned int  u16;
typedef unsigned char uint8;
typedef unsigned int uint16;
typedef unsigned long uint32;
sbit CS  = P1^0;        //扭矩
sbit CLK = P1^1;
sbit DIO = P1^2;
sbit CS1  = P3^5;        //电流
sbit CLK1 = P3^6;
sbit DIO1 = P3^7;
sbit CS2  = P1^3;        //车速
sbit CLK2 = P1^4;
sbit DIO2 = P1^5;
sbit Motor1_EN  = P0^3;
sbit Motor1_IN1 = P0^0;
sbit Motor1_IN2 = P0^1;
sbit BEEP = P0^3;
sbit key = P1^6;/*变量定义*/
static int number= 0 ,fz=0,flag=0,flag1=0;				
static 	char dl,cs;
static signed int nj;
uchar count,a=0,b,c;/*函数定义*/
void dlpd();
void cspd();
void njpd();
void ajpd();
/*
扭矩:
车速
电流
*/void jiemian1(void)			  
{				   Lcd\_Character\_16X16( 1, 0, 0 , function_logo\[0\]);  // 扭Lcd\_Character\_16X16( 1, 0, 16 ,function_logo\[1\]);  // 矩Lcd\_Character\_16X8 ( 1, 0,32,letter_logo\[nj/100\]);Lcd\_Character\_16X8 ( 1, 0,40,letter_logo\[(nj/10)%10\]);Lcd\_Character\_16X8 ( 1, 0,48,letter_logo\[nj%10\]);Lcd\_Character\_16X16( 1, 2, 0 , function_logo\[2\]);  // 车Lcd\_Character\_16X16( 1, 2, 16, function_logo\[3\]);  //速Lcd\_Character\_16X8 ( 1, 2,32,letter_logo\[cs/100\]);Lcd\_Character\_16X8 ( 1, 2,40,letter_logo\[(cs/10)%10\]);Lcd\_Character\_16X8 ( 1, 2,48,letter_logo\[cs%10\]);Lcd\_Character\_16X16( 1, 4, 0 , function_logo\[4\]);  // 电Lcd\_Character\_16X16( 1, 4, 16, function_logo\[5\]); // 流Lcd\_Character\_16X8 ( 1, 4,32,letter_logo\[dl/100\]);Lcd\_Character\_16X8 ( 1, 4,40,letter_logo\[(dl/10)%10\]);Lcd\_Character\_16X8 ( 1, 4,48,letter_logo\[dl%10\]);
}void Timer0_Init(void)		//200微秒@11.0592MHz
{//AUXR &= 0x7F;		//定时器时钟12T模式TMOD &= 0xF0;		//设置定时器模式TMOD |= 0x01;		//设置定时器模式TL0 = 0x48;		//设置定时初值TH0 = 0xFF;		//设置定时初值TF0 = 0;		//清除TF0标志TR0 = 1;		//定时器0开始计时ET0 = 1;
}void Car_Move(uchar speed)	 //电机转动
{uchar Car_Speed = speed;count++;	if(count <= Car_Speed){Motor1_IN1 = 1;}else{Motor1_IN1 = 0;}if(count >= 100){count = 0;}	
}void Car_Move1(uchar speed)	 //电机转动
{uchar Car_Speed = speed;count++;	if(count <= Car_Speed){Motor1_IN2 = 1;}else{Motor1_IN2 = 0;}if(count >= 100){count = 0;}	
}void Timer0_isr(void) interrupt 1
{TL0 = 0x48;		//设置定时初值TH0 = 0xFF;		//设置定时初值if(flag1 == 0){switch(a){case 0:Motor1_IN1 = 0;break;case 1:Car_Move(30);break;	 	 //电机低速前进case 2:Car_Move(60);break;	 	 //电机高速前进case 3:Car_Move(90);break;	 	 //电机高速前进case 4:Car_Move(120);break;	 	 //电机高速前进case 5:Car_Move(150);break;	 	 //电机高速前进case 6:Car_Move(180);break;	 	 //电机高速前进default:break;}} else if(flag1 == 1){switch(a){case 0:Motor1_IN2 = 0;break;case 1:Car_Move1(30);break;	 	 //电机低速前进case 2:Car_Move1(60);break;	 	 //电机高速前进case 3:Car_Move1(90);break;	 	 //电机高速前进case 4:Car_Move1(120);break;	 	 //电机高速前进case 5:Car_Move1(150);break;	 	 //电机高速前进case 6:Car_Move1(180);break;	 	 //电机高速前进default:break;}}
}uchar get\_AD\_Res()          //ADC0832启动读取扭矩的值
{uchar i, data1=0, data2=0;CS=0;CLK=0;DIO=1;\_nop\_();CLK=1;\_nop\_();CLK=0;DIO=1;\_nop\_(); CLK=1;\_nop\_();CLK=0;DIO=0;\_nop\_();CLK=1;\_nop\_();CLK=0;DIO=1;\_nop\_(); for(i=0; i<8; i++){CLK=1;\_nop\_();CLK=0;\_nop\_();data1=(data1<<1)|(uchar)DIO; }for(i=0; i<8; i++){data2=data2|(uchar)DIO<<i;CLK=1;\_nop\_();CLK=0;\_nop\_();}CS=1;return(data1 == data2)?data1:0;
}uchar get\_AD\_Res1()          //ADC0832启动读取电流值
{uchar i, data1=0, data2=0;CS1=0;CLK1=0;DIO1=1;\_nop\_();CLK1=1;\_nop\_();CLK1=0;DIO1=1;\_nop\_(); CLK1=1;\_nop\_();CLK1=0;DIO1=0;\_nop\_();CLK1=1;\_nop\_();CLK1=0;DIO1=1;\_nop\_(); for(i=0; i<8; i++){CLK1=1;\_nop\_();CLK1=0;\_nop\_();data1=(data1<<1)|(uchar)DIO1; }for(i=0; i<8; i++){data2=data2|(uchar)DIO1<<i;CLK1=1;\_nop\_();CLK1=0;\_nop\_();}CS1=1;return(data1 == data2)?data1:0;
}uchar get\_AD\_Res2()          //ADC0832启动读取车速值
{uchar i, data1=0, data2=0;CS2=0;CLK2=0;DIO2=1;\_nop\_();CLK2=1;\_nop\_();CLK2=0;DIO2=1;\_nop\_(); CLK2=1;\_nop\_();CLK2=0;DIO2=0;\_nop\_();CLK2=1;\_nop\_();CLK2=0;DIO2=1;\_nop\_(); for(i=0; i<8; i++){CLK2=1;\_nop\_();CLK2=0;\_nop\_();data1=(data1<<1)|(uchar)DIO2; }for(i=0; i<8; i++){data2=data2|(uchar)DIO2<<i;CLK2=1;\_nop\_();CLK2=0;\_nop\_();}CS2=1;return(data1 == data2)?data1:0;
}void Time1Init()
{TMOD |= 0x10;TH1   = (65536-57567)/256;TL1   = (65536-57567)%256;EA    = 1;ET1   = 1;TR1   = 1;
}void Time1Start() interrupt 3
{static	u16 count1 = 0;      //定义计数变量TH1   = (65536-57567)/256;TL1   = (65536-57567)%256;count1++;if(count1 == 1)//达到1s{count1 = 0; ajpd();}
}void main()					  //主函数
{	Timer0_Init();Time1Init();        //定时器1初始化Lcd_Initial();     //LCD初始化Lcd\_Display\_On();	//启动屏幕jiemian1();Motor1_IN1=0;Motor1_IN2=0;while(1){nj=get\_AD\_Res();	dl=get\_AD\_Res1();	cs=get\_AD\_Res2();	nj-=26;nj=nj/4;if( nj<1){nj=0;}dlpd(); //电流判断cspd();//车速判断njpd(); //扭矩判断jiemian1();	if(flag == 0){a=b*c;}}}void dlpd()
{if(dl>100){BEEP = 1;a= 0;flag = 1;}else {BEEP = 0;flag = 0;}
}void cspd()
{if(cs>90){b=0;}else if(cs>0 && cs <30){b=3;}else if(cs>30 && cs <60){b=2;}else if(cs>60 && cs <90){b=1;}}void njpd()
{if(nj==0){c=0;}else if(nj>=1 && nj <15){c=1;}else if(nj>15 && nj <25){c=2;}
}void ajpd()
{if(key==0){Delay(50);if(key == 0){flag1++;if(flag1>1){flag1 = 0;}}}
}

四、实现现象

具体动态效果看B站演示视频:

基于51单片机的汽车电动助力转向系统_哔哩哔哩_bilibili

全部资料(源程序、仿真文件、安装包、演示视频、流程图、代码讲解):

链接:https://pan.baidu.com/s/1AFNrIABmiHdw1RSl5rGisg 
提取码:ms6z 
–来自百度网盘超级会员V4的分享

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词