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单片机的方向盘模拟系统

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

百度网盘分享

相关推荐
清风6666669 小时前
基于单片机与DAC0832的双路波形信号发生系统设计
单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
azwsm10 小时前
电路元器件和GPIO控制器
单片机·嵌入式硬件
kebidaixu13 小时前
FreeRTOS 移植到 STM32F407VETX 记录(一)
stm32·单片机·嵌入式硬件
CSDN官方博客14 小时前
「谁说嵌入式只是调包和焊板子?」—— 2026嵌入式全栈技术征锋令
嵌入式硬件·物联网·embedding
点灯小铭14 小时前
基于单片机的数码管定时插座设计与定时开关功能实现
单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
云栖梦泽15 小时前
玩转RK3506SDK
linux·嵌入式硬件
数智工坊16 小时前
机器人四大主控板系统分层选型指南:树莓派、ESP32、STM32与Arduino的能力边界与实战定位
stm32·嵌入式硬件·机器人
进击的小头17 小时前
第8篇:IGBT 从零到精通:核心原理、关键参数、选型指南与工业级应用要点
经验分享·嵌入式硬件·学习
点灯小铭17 小时前
基于单片机的多模式智能洗衣机设计
单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
项目題供诗17 小时前
STM32-AD单通道&AD多通道(十九)
stm32·单片机·嵌入式硬件