毕业设计 基于51单片机的汽车倒车防撞报警系统 (源码+硬件+论文)

本文主要是介绍毕业设计 基于51单片机的汽车倒车防撞报警系统 (源码+硬件+论文),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 0 前言
  • 1 主要功能
  • 2 硬件设计(原理图)
  • 3 核心软件设计
  • 4 实现效果
  • 5 最后


0 前言

🔥
这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。

为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是

🚩 毕业设计 基于51单片机的汽车倒车防撞报警系统 (源码+硬件+论文)

🥇学长这里给一个题目综合评分(每项满分5分)

  • 难度系数:3分
  • 工作量:3分
  • 创新点:4分

🧿 项目分享:

https://gitee.com/sinonfin/sharing

在这里插入图片描述

1 主要功能

系统硬件结构框图,主要为STC89C52单片机最小系统,LCD1602显示器集成电路,HC-SR04超声波测距模块,蜂鸣器报警集成电路和按键电路。由图1-1可确定其功能模块的具体设计情况与逻辑关联。
接入5V直流稳压电流,按动自锁按钮给硬件系统上电,首先由超声波测距模块测量距离,单片机将所测的距离数值处理之后显示在LCD1602上。利用按键装置调整报警距离上限,若测量距离小于预先设定值,蜂鸣器发声报警、LED灯闪烁。

在这里插入图片描述

2 硬件设计(原理图)

在这里插入图片描述

在这里插入图片描述

3 核心软件设计

由上文分析论述可知,超声波传感器基于超声波传播与返回时间实现距离测定功能。在明确时间数据的基础上,结合超声波在空气中的传播速度对距离参数进行计算。其具体的技术原理详见图2-8所示。实现思路:第一种,直接给trig高电平,然后读取ECHO引脚是否为高电平,若为高电平,则开启定时器,然后继续检测等待其为低电平的时候,获取计数器值,然后进行计算。第二种,开启外部中断,先将ECHO配置上升沿中断,当中断来临的时候,在中断函数里面开启定时器,再将其配置为下降沿中断,等待下降沿中断来临的时候,获取计数器值。
其实上面的两种方法,其思路都是通过计算定时器的counter值,来计算距离。

第三种是让定时器一路PWM控制触发以及触发周期,超声波返回信号高电平时间用定时器通道捕捉功能获取。

在这里插入图片描述

基于上述工作原理,超声波将由发射装置发出长约6mm和频率为40kHz的超声波信号并经目标对象反射之后返回至传感器接收装置进行识别和确定,在此基础上可确定超声波往返一次所需时间。该时间的1/2即超声波在传感器与目标对象之间的传播时间,进而可计算相应的距离数据。

主程序具体负责相关数据的处理和分析工作,并为各个功能模块的正常运行提供必要的程序指令支持和保障。该程序的技术流程详见图

在这里插入图片描述

关键代码

#include <reg52.h>
#include <intrins.h>#include <stdio.h>#define uchar unsigned char	
#define uint  unsigned int	sfr ISP_DATA  = 0xe2;			
sfr ISP_ADDRH = 0xe3;			
sfr ISP_ADDRL = 0xe4;			
sfr ISP_CMD   = 0xe5;			
sfr ISP_TRIG  = 0xe6;			
sfr ISP_CONTR = 0xe7;			sbit LcdRs_P   = P2^7;		    
sbit LcdRw_P   = P2^6;		 
sbit LcdEn_P   = P2^5;		
sbit Trig_P    = P2^2;		
sbit Echo_P    = P2^3;		 
sbit KeySet_P  = P3^2;		
sbit KeyDown_P = P3^3;		
sbit KeyUp_P   = P3^4;		
sbit Buzzer_P  = P2^1;	
sbit Led_P     = P2^0;		uint gAlarm;							// 单片机内部EEPROM不使能
void ISP_Disable()
{ISP_CONTR = 0;ISP_ADDRH = 0;ISP_ADDRL = 0;
}// 从单片机内部EEPROM读一个字节,从0x2000地址开始unsigned char EEPROM_Read(unsigned int add)
{ISP_DATA  = 0x00;ISP_CONTR = 0x83;ISP_CMD   = 0x01;ISP_ADDRH = (unsigned char)(add>>8);ISP_ADDRL = (unsigned char)(add&0xff);// 对STC89C51系列来说,每次要写入0x46,再写入0xB9,ISP/IAP才会生效ISP_TRIG  = 0x46;	   ISP_TRIG  = 0xB9;_nop_();ISP_Disable();return (ISP_DATA);
}// 往单片机内部EEPROM写一个字节,从0x2000地址开始void EEPROM_Write(unsigned int add,unsigned char ch)
{ISP_CONTR = 0x83;ISP_CMD   = 0x02;ISP_ADDRH = (unsigned char)(add>>8);ISP_ADDRL = (unsigned char)(add&0xff);ISP_DATA  = ch;ISP_TRIG  = 0x46;ISP_TRIG  = 0xB9;_nop_();ISP_Disable();
}// 擦除单片机内部EEPROM的一个扇区
// 写8个扇区中随便一个的地址,便擦除该扇区,写入前要先擦除void Sector_Erase(unsigned int add)	  
{ISP_CONTR = 0x83;ISP_CMD   = 0x03;ISP_ADDRH = (unsigned char)(add>>8);ISP_ADDRL = (unsigned char)(add&0xff);ISP_TRIG  = 0x46;ISP_TRIG  = 0xB9;_nop_();ISP_Disable();
}// 毫秒级的延时函数,time是要延时的毫秒数void DelayMs(uint time)
{uint i,j;for(i=0;i<time;i++)for(j=0;j<112;j++);
}// 1602液晶写命令函数,cmd就是要写入的命令void LcdWriteCmd(uchar cmd)
{ LcdRs_P = 0;LcdRw_P = 0;LcdEn_P = 0;P0=cmd;DelayMs(2);LcdEn_P = 1;    DelayMs(2);LcdEn_P = 0;	
}// 1602液晶写数据函数,dat就是要写入的命令void LcdWriteData(uchar dat)
{LcdRs_P = 1; LcdRw_P = 0;LcdEn_P = 0;P0=dat;DelayMs(2);LcdEn_P = 1;    DelayMs(2);LcdEn_P = 0;
}// 1602液晶初始化函数void LcdInit()
{LcdWriteCmd(0x38);        // 16*2显示,5*7点阵,8位数据口LcdWriteCmd(0x0C);        // 开显示,不显示光标LcdWriteCmd(0x06);        // 地址加1,当写入数据后光标右移LcdWriteCmd(0x01);        // 清屏
}// 液晶光标定位函数void LcdGotoXY(uchar line,uchar column)
{// 第一行if(line==0)        LcdWriteCmd(0x80+column); // 第二行if(line==1)        LcdWriteCmd(0x80+0x40+column); 
}// 液晶输出字符串函数void LcdPrintStr(uchar *str)
{while(*str!='\0')LcdWriteData(*str++);
}// 液晶输出数字void LcdPrintNum(uint num)
{LcdWriteData(num/100+0x30);				// 百位LcdWriteData(num%100/10+0x30);		// 十位LcdWriteData(num%10+0x30);				// 个位
}// 计算测到的距离uint GetDistance(void)
{uint ss;					// 用于记录测得的距离TH0=0;TL0=0;Trig_P=1;					// 给超声波模块一个开始脉冲DelayMs(1);Trig_P=0;while(!Echo_P);		TR0=1;						while(Echo_P);		TR0=0;						ss=((TH0*256+TL0)*0.034)/2;		// 距离cm=(时间us * 速度cm/us)/2return ss;
}// 按键扫描void KeyScanf()
{uchar i;uchar dat1,dat2;if(KeySet_P==0)					// 判断是否有按键按下{DelayMs(10);								// 消除按键按下的抖动while(!KeySet_P);						// 等待按键释放DelayMs(10);								// 消除按键松开的抖动LcdGotoXY(1,2);							// 液晶第二行刷新显示LcdPrintStr("alarm=   cm");LcdGotoXY(1,8);							LcdPrintNum(gAlarm);				i=1;while(i){							  if(KeyDown_P==0)		// 报警值减的处理{DelayMs(300);if(gAlarm>2)gAlarm--;LcdGotoXY(1,8);LcdPrintNum(gAlarm);	}if(KeyUp_P==0)			// 报警值加的处理{DelayMs(300);if(gAlarm<400)gAlarm++;LcdGotoXY(1,8);LcdPrintNum(gAlarm);}if(KeySet_P==0)			// 再次按下设置键的判断{DelayMs(10);		  			while(!KeySet_P);				DelayMs(10);		  				LcdGotoXY(1,0);						LcdPrintStr("     S=   cm    ");i=0;}			   }dat1=gAlarm/100;dat2=gAlarm%100;Sector_Erase(0x2000);EEPROM_Write(0x2000,dat1);EEPROM_Write(0x2001,dat2);}	
}// 报警判断void AlarmJudge(uint ss)
{uchar i;float alr1,alr2,alr3,alr4;alr1=gAlarm/4.00*1;alr2=gAlarm/4.00*2;alr3=gAlarm/4.00*3;alr4=gAlarm/4.00*4;// 报警频率最快if(ss<alr1)			{for(i=0;i<10;i++){Led_P=0;Buzzer_P=0;DelayMs(50);Led_P=1;Buzzer_P=1;DelayMs(50);KeyScanf();}}// 报警频率第二快else if(ss<alr2)		{for(i=0;i<5;i++){Led_P=0;Buzzer_P=0;DelayMs(100);Led_P=1;Buzzer_P=1;DelayMs(100);KeyScanf();}	}// 报警频率第三快else if(ss<alr3) 	{for(i=0;i<2;i++){Led_P=0;Buzzer_P=0;DelayMs(200);Led_P=1;Buzzer_P=1;DelayMs(200);KeyScanf();}	}// 报警频率最慢else if(ss<alr4)	{for(i=0;i<2;i++){Led_P=0;Buzzer_P=0;DelayMs(300);Led_P=1;Buzzer_P=1;DelayMs(300);KeyScanf();}	}// 不报警else{Led_P=1;Buzzer_P=1;for(i=0;i<100;i++){KeyScanf();DelayMs(10);}	}
}bit busy = 0;void Uart_Isr() interrupt 4 using 1
{if (RI){RI = 0;             //Clear receive interrupt flag}
//    if (TI)
//    {
//        TI = 0;             //Clear transmit interrupt flag
//        busy = 0;           //Clear transmit busy flag
//    }
}void Delay150us()		//@11.0592MHz
{unsigned char i, j;_nop_();_nop_();_nop_();i = 2;j = 153;do{while (--j);} while (--i);
}/*----------------------------
Send a byte data to UART
Input: dat (data to be sent)
Output:None
----------------------------*/
void SendData(unsigned char dat)
{// while (busy);           //Wait for the completion of the previous data is sent// ACC = dat;              //// busy = 1;// TI = 0;SBUF = dat;             //Send data to UART buffer//Delay150us();while(!TI);TI = 0;
}/*----------------------------
Send a string to UART
Input: s (address of string)
Output:None
----------------------------*/
void SendString(char *s)
{while (*s)              //Check the end of the string{SendData(*s++);     //Send current char and increment string ptr}
}#define FOSC 11059200L      //System frequency
#define BAUD 9600       //UART baudratevolatile unsigned char Dat[16];// 主函数void main()
{uchar dat1,dat2;uint dist;
unsigned short Cnt = 0;LcdInit();												// 执行液晶初始化TMOD = 0x01;											// 选择定时器0,并且确定是工作方式1(为了超声波模块测量距离计时用的)LcdGotoXY(0,0);	    							// 定位到第0行第0列LcdPrintStr(" HC-SR04 System ");	// 第0行显示“HC-SR04 System”LcdGotoXY(1,0);	    							// 定位到第1行第0列LcdPrintStr("     S=   cm    ");	// 第1行显示“S=   cm”dat1=EEPROM_Read(0x2000);					// 从EEPROM读取报警值dat2=EEPROM_Read(0x2001);gAlarm=dat1*100+dat2;if((gAlarm==0)||(gAlarm>400))			// 如果读取到的报警值异常{gAlarm=25;											// 重新赋值报警值为25}//	SCON = 0x50;
//	TL2 = RCAP2L = (65536-(FOSC/32/BAUD)); //Set auto-reload vaule
//  TH2 = RCAP2H = (65536-(FOSC/32/BAUD)) >> 8;
//  T2CON = 0x34;           //Timer2 start run
//  ES = 0;                 //Enable UART interrupt
//  EA =1;
//	//PCON &= 0x7F;		//波特率不倍速SCON = 0x50;		//8位数据,可变波特率//AUXR &= 0xBF;		//定时器1时钟为Fosc/12,即12T//AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器TMOD &= 0x0F;		//清除定时器1模式位TMOD |= 0x20;		//设定定时器1为8位自动重装方式TL1 = 0xFD;		//设定定时初值TH1 = 0xFD;		//设定定时器重装值ET1 = 0;		//禁止定时器1中断TR1 = 1;		//启动定时器1//SendData(0XA5);while(1){dist=GetDistance();							// 通过超声波模块获取距离LcdGotoXY(1,7);	    						// 定位到第1行第7列LcdPrintNum(dist);							// 将获取到的距离在液晶上面显示if(++Cnt>=1){Cnt = 0;sprintf(Dat,"S=%d cm\r\n",(uint) dist);SendString(Dat);}AlarmJudge(dist);								}
}

4 实现效果

在这里插入图片描述

5 最后

包含内容

在这里插入图片描述

🧿 项目分享:

https://gitee.com/sinonfin/sharing

这篇关于毕业设计 基于51单片机的汽车倒车防撞报警系统 (源码+硬件+论文)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Java汇编源码如何查看环境搭建

《Java汇编源码如何查看环境搭建》:本文主要介绍如何在IntelliJIDEA开发环境中搭建字节码和汇编环境,以便更好地进行代码调优和JVM学习,首先,介绍了如何配置IntelliJIDEA以方... 目录一、简介二、在IDEA开发环境中搭建汇编环境2.1 在IDEA中搭建字节码查看环境2.1.1 搭建步

什么是cron? Linux系统下Cron定时任务使用指南

《什么是cron?Linux系统下Cron定时任务使用指南》在日常的Linux系统管理和维护中,定时执行任务是非常常见的需求,你可能需要每天执行备份任务、清理系统日志或运行特定的脚本,而不想每天... 在管理 linux 服务器的过程中,总有一些任务需要我们定期或重复执行。就比如备份任务,通常会选在服务器资

如何安装HWE内核? Ubuntu安装hwe内核解决硬件太新的问题

《如何安装HWE内核?Ubuntu安装hwe内核解决硬件太新的问题》今天的主角就是hwe内核(hardwareenablementkernel),一般安装的Ubuntu都是初始内核,不能很好地支... 对于追求系统稳定性,又想充分利用最新硬件特性的 Ubuntu 用户来说,HWEXBQgUbdlna(Har

TP-LINK/水星和hasivo交换机怎么选? 三款网管交换机系统功能对比

《TP-LINK/水星和hasivo交换机怎么选?三款网管交换机系统功能对比》今天选了三款都是”8+1″的2.5G网管交换机,分别是TP-LINK水星和hasivo交换机,该怎么选呢?这些交换机功... TP-LINK、水星和hasivo这三台交换机都是”8+1″的2.5G网管交换机,我手里的China编程has

基于Qt实现系统主题感知功能

《基于Qt实现系统主题感知功能》在现代桌面应用程序开发中,系统主题感知是一项重要的功能,它使得应用程序能够根据用户的系统主题设置(如深色模式或浅色模式)自动调整其外观,Qt作为一个跨平台的C++图形用... 目录【正文开始】一、使用效果二、系统主题感知助手类(SystemThemeHelper)三、实现细节

CentOS系统使用yum命令报错问题及解决

《CentOS系统使用yum命令报错问题及解决》文章主要讲述了在CentOS系统中使用yum命令时遇到的错误,并提供了个人解决方法,希望对大家有所帮助,并鼓励大家支持脚本之家... 目录Centos系统使用yum命令报错找到文件替换源文件为总结CentOS系统使用yum命令报错http://www.cppc

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

基于人工智能的图像分类系统

目录 引言项目背景环境准备 硬件要求软件安装与配置系统设计 系统架构关键技术代码示例 数据预处理模型训练模型预测应用场景结论 1. 引言 图像分类是计算机视觉中的一个重要任务,目标是自动识别图像中的对象类别。通过卷积神经网络(CNN)等深度学习技术,我们可以构建高效的图像分类系统,广泛应用于自动驾驶、医疗影像诊断、监控分析等领域。本文将介绍如何构建一个基于人工智能的图像分类系统,包括环境

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设