27 基于51单片机的方向盘模拟系统

目录

一、主要功能

二、硬件资源

三、程序编程

四、实现现象


一、主要功能

基于STC89C52单片机,采用两个MPX4115压力传感器作为两路压力到位开关电路,
采用滑动变阻器连接数模转换器模拟重力加速度传感器电路;
一个按键控制LED灯的点亮与熄灭;两路压力值与加速度值通过LCD1602显示屏显示;
如果加速度的值3秒内没没有变化,或者两个压力传感器的差值大于50
(这里设置差值小于50表示双手同时抓住方向盘的到位开关了,如果大于50,则不是同时抓住,
因为仿真里没法同时按两个东西,所以采取差值替代。)
则蜂鸣器报价,且继电器断开,继电器控制的电机停止转动。
反之,不报警,继电器控制电机继续转动。

二、硬件资源

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

编辑

三、程序编程

复制代码
#include <REGX52.H>#include <intrins.h>#include <stdio.h>#include "Delay.h"#include "LCD1602.h"#define uchar unsigned char#define uint unsigned  intsbit beep = P2^5;			  //蜂鸣器引脚sbit CS=P1^0;                 //adc0832引脚sbit CLK=P1^1;
sbit DIO=P1^2;
sbit CS1=P1^3;                 //adc0832引脚sbit CLK1=P1^4;
sbit DIO1=P1^5;
sbit CS2   =  P1^6;        //ADC0832引脚定义sbit CLK2  =  P1^7;
sbit DIO2  =  P2^6;
sbit motor =  P2^7;
sbit key = P3^1;
sbit led = P3^0;
sbit key1 = P3^2;static int timerCount;typedef unsigned char u8;typedef unsigned int  u16;static uchar u,U,R ,u1,U1,R1,u2,U2,R2,lastResistance;      //定义变量static int number;static int resistanceChanged;static int flag = 0;void beep\_warning();void Time0\_Init()          //定时器初始化{
    TMOD = 0x01;    // 定时器0工作在模式1
    TH0 = 0xfa >> 8;
    TL0 = 0xfa & 0xFF;
    ET0 = 1;        // 开启定时器0中断
    TR0 = 1;        // 启动定时器0
    EA =0;
}void Time0_Int() interrupt 1 //中断程序{    static unsigned int timerCount = 0;
    TH0 = 0xfa >> 8;
    TL0 = 0xfa & 0xFF;
    timerCount++;    // 每隔三秒检查阻值是否发生变化
    if (timerCount >= 27)
    {
        timerCount = 0;             
		
        // 比较当前阻值与上一次的阻值是否相同
        if (R != lastResistance)
        {            // 阻值发生了变化
            resistanceChanged = 0;
        }        else
        {
            resistanceChanged = 1;
        }        // 更新上一次的阻值
        lastResistance = R;
    }
}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 beep_warning() //报警并且电机转动{
 number = R1-R2;	if(number<=0)
	{
		number = ~(number-1);
	}	if(flag==0)
	{
		EA = 0;	if(number>50)
	{
		beep = 1; //报警
		motor = 1;//断开继电器
	}	else
	{
		beep = 0;
		motor = 0;
	}
 }	
	if(flag==1)
	{	if(resistanceChanged==1)
	{
		beep = 1; //报警
		motor = 1;//断开继电器
	}	else
	{
		beep = 0; 
		motor = 0;
	}
 }	LCD_ShowNum(2,10,resistanceChanged,3);
}void main()					  //主函数{	
	beep=0;			    //蜂鸣器关掉
	motor=0;         //启动继电器
	led = 0;	LCD_Init();         //显示屏初始化
	Time0\_Init();	LCD\_ShowString(1,1,"zuo:");	LCD\_ShowString(1,10,"you:");	LCD\_ShowString(2,1,"Vt:");	while(1)
	{
		u=get\_AD\_Res();
		U=(250*u)/128;     //此处将数字信号转化为模拟信号,要根据上拉电阻阻值来确定
		R=200*U/250;	    //重力
	
	  u1=get\_AD\_Res1();
		U1=(250*u1)/128;     //此处将数字信号转化为模拟信号,要根据上拉电阻阻值来确定
		R1=200*U1/250;	   //压力右
		
		u2=get\_AD\_Res2();
		U2=(250*u2)/128;     //此处将数字信号转化为模拟信号,要根据上拉电阻阻值来确定
		R2=200*U2/250;	   //压力左
	
	
	  LCD_ShowNum(1,5,R2,3); //第一行显示左压力
		LCD_ShowNum(1,14,R1,3); //第一行显示右压力
		LCD_ShowNum(2,4,R,3);  //第二行显示重力加速度
	  beep_warning(); //压力与重力处理报警函数
		
		if(!key)
		{
			led=~led;			while(!key);
		}		
		if(~key1)
		{
			EA=1;
			flag++;
			{				if(flag>1)
				{
					flag = 0;
				}
			}			while(~key1);
		}
	}
}

四、实现现象

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

基于51单片机的方向盘模拟系统

全部资料(源程序、仿真文件、安装包、演示视频):

百度网盘分享

相关推荐
智商偏低5 小时前
单片机之helloworld
单片机·嵌入式硬件
青牛科技-Allen6 小时前
GC3910S:一款高性能双通道直流电机驱动芯片
stm32·单片机·嵌入式硬件·机器人·医疗器械·水泵、
森焱森8 小时前
无人机三轴稳定控制(2)____根据目标俯仰角,实现俯仰稳定化控制,计算出升降舵输出
c语言·单片机·算法·架构·无人机
白鱼不小白8 小时前
stm32 USART串口协议与外设(程序)——江协教程踩坑经验分享
stm32·单片机·嵌入式硬件
S,D9 小时前
MCU引脚的漏电流、灌电流、拉电流区别是什么
驱动开发·stm32·单片机·嵌入式硬件·mcu·物联网·硬件工程
芯岭技术12 小时前
PY32F002A单片机 低成本控制器解决方案,提供多种封装
单片机·嵌入式硬件
youmdt12 小时前
Arduino IDE ESP8266连接0.96寸SSD1306 IIC单色屏显示北京时间
单片机·嵌入式硬件
嘿·嘘12 小时前
第七章 STM32内部FLASH读写
stm32·单片机·嵌入式硬件
Meraki.Zhang12 小时前
【STM32实践篇】:I2C驱动编写
stm32·单片机·iic·驱动·i2c
几个几个n15 小时前
STM32-第二节-GPIO输入(按键,传感器)
单片机·嵌入式硬件