基于51单片机的汽车超声波防撞声光报警系统proteus仿真原理图PCB

功能介绍:
0.本系统采用STC89C52作为单片机
1.LCD1602液晶实时距离阈值/测试距离
2.低于距离阈值将声光报警
3.按键可更改距离阈值

原理图:
在这里插入图片描述

PCB:
在这里插入图片描述

主程序:

#include <reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include <stdio.h>
#include "lcd1602.h"
#include "delay.h"
#include "math.h"

//管脚定义
sbit KEY_ADD = P3^4;
sbit KEY_SUB = P3^6;

sbit ECHO = P2^5; //超声波引脚定义
sbit TRIG = P2^4;

sbit BUZZER = P2^2;

//变量定义
unsigned char dis0[16] = "DisLimit:     mm";	 //显示数组
unsigned char dis1[16] = "Distance:     mm";	 //显示数组

float f_distance;		 //距离
float f_distanceLimit = 300; //限制500mm
long g_cnt = 0; //定时器计数
bit g_dispFlag = 0;
bit g_refreshFlag = 0;
unsigned char cnt = 0;

//函数声明
void DispDis();
void KeyScan();
void Timer1_Init();

void main(void)
{
	unsigned char testTime = 0;
	float f_distanceBuf = 0;
    
    TRIG = 0;
	TMOD |= 0x01; //设T0为方式1,GATE=1;
	TH0 = 0;
	TL0 = 0;
//	ET0=1;             //允许T0中断
	EA = 1; //开启总中断

	Timer1_Init();
	LCD_Init();	 //初始化液晶
	DelayMs(20); //延时有助于稳定
	LCD_Clear();

	while (1) //主循环
	{
		if (g_refreshFlag == 1)
		{
			g_refreshFlag = 0;
			if (testTime >= 10)
			{
				testTime = 0;
				f_distance = f_distanceBuf / 10; //计算10次平均值
				f_distanceBuf = 0;
			}
			else
			{
				TR1 = 0;
				TRIG = 1; //启动一次模块		//不可以使用其他终端 容易造成死循环
				DelayUs10x(1);
				TRIG = 0;
				while (!ECHO)
					;	 //当RX为零时等待
				TR0 = 1; //开启计数
				while (ECHO)
					; //当RX为1计数并等待
				TR0 = 0;
				TR1 = 1;
				g_cnt = (long)(TH0 * 256 + TL0);
				TH0 = 0;
				TL0 = 0;
				f_distanceBuf = f_distanceBuf + (float)(g_cnt * 17) / 100.0 * 1.102; //算出来是mm (g_cnt * 340 / 2) / 1000.0 * 1.102;系数
				testTime++;
			}
		}

		if ((g_cnt > 0) && (f_distance > 0))
		{
			if (f_distance > f_distanceLimit) //距离对比
			{
				BUZZER = 1;
			} //不报警 指示灯正常
			else
			{
				BUZZER = 0;

			} //报警 指示灯异常
		}

		if (g_dispFlag == 1) //刷新液晶
		{
			TR1 = 0;
			DispDis();
			TR1 = 1;
			g_dispFlag = 0;
		}

        KeyScan();
	}
}

void DispDis()
{
	dis0[9]  = '0' +  (int)f_distanceLimit / 10000;
	dis0[10]  = '0' + (int)f_distanceLimit / 1000 % 10;
	dis0[11]  = '0' + (int)f_distanceLimit / 100 % 10;
	dis0[12]  = '0' + (int)f_distanceLimit / 10 % 10;
	dis0[13]  = '0' + (int)f_distanceLimit % 10;

	DispStr(0, 0, dis0); //显示距离阈值

	dis1[9]  = '0' + (int)f_distance / 10000;
	dis1[10]  = '0' + (int)f_distance / 1000 % 10;
	dis1[11]  = '0' + (int)f_distance / 100 % 10;
	dis1[12]  = '0' + (int)f_distance / 10 % 10;
	dis1[13]  = '0' + (int)f_distance % 10;

	DispStr(0, 1, dis1); //显示距离
}

void KeyScan()
{

	if (!KEY_ADD) //加键按下
	{
		DelayMs(200);
		if (!KEY_ADD) //再次确认加键是否按下
		{
            f_distanceLimit = f_distanceLimit + 10;
			if (f_distanceLimit > 3000)
			{
				f_distanceLimit = 200;
			}
            DispDis();
		}
		//while (!KEY_ADD);
	}

	if (!KEY_SUB)//减键按下
	{
		DelayMs(200); 
		if (!KEY_SUB) //再次确认减键是否按下
		{
            f_distanceLimit = f_distanceLimit - 10;
			if (f_distanceLimit < 200)
			{
				f_distanceLimit = 3000;
			}
            DispDis();
        }    
		//while (!KEY_SUB);
	}

}

//定时器1初始化
void Timer1_Init()
{
	TMOD &= 0x0F;
	TMOD |= 0x10; //16位定时器
	TH1 = (65536 - 18432) / 256; //20ms定时
	TL1 = (65536 - 18432) % 256; //20ms定时
	TR1 = 1;
	ET1 = 1;
	EA = 1;
}

//定时器1的中断
void Timer1_INT() interrupt 3
{

	TH1 = (65536 - 18432) / 256; //20ms定时
	TL1 = (65536 - 18432) % 256;

	if (cnt >= 25)
	{
		g_dispFlag = 1;
		cnt = 0;
	}
	else
	{
		cnt++;
	}

	if (cnt % 5 == 0)
	{
		g_refreshFlag = 1;
	}
}

仿真演示视频:
https://www.bilibili.com/video/BV1iY411F7hj/

实物演示视频:
https://www.bilibili.com/video/BV1JR4y1w78M/

  • 0
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值