功能介绍:
0.本系统采用STC89C52作为单片机
1.LCD1602液晶显示测量车速,同时串口上报速度测量结果
2.激光模块1触发,启动测速定时器,激光2触发,停止定时器,完成测速
超过60km/h,蜂鸣器报警
3.激光传感器最远支持4米的测试距离,足以满足大多数测速场景
4.采用DC002作为电源接口可直接输入5V给整个系统供电
原理图:
PCB:
主程序:
#include <reg52.h>
#include "main.h"
float speed = 0;
unsigned int speedMax = 60; //报警速度60km/h
unsigned int timeCnt = 0;
float timeH = 0;
float timeL = 0;
bit startFlag = 0;
bit oldPinState1 = 0;
bit nowPinState1 = 0;
bit oldPinState2 = 0;
bit nowPinState2 = 0;
void main()
{
unsigned char dispRow[16];
// 初始化
LCD_Init();
// 定时器初始化
Timer0_Init();
UART0_Init();
// 开机显示
LCD_DispStr(0, 0, " Welcome!!! ");
DelayS(2);
LCD_Clear();
LCD_DispStr(0, 0, " Speedometer ");
LCD_DispStr(0, 1, "Speed: 0.00km/h");
while(1)
{
nowPinState1 = INFRARED_START;
if (oldPinState1 == 1 && nowPinState1 == 0) //开始探头下降沿触发
{
LCD_DispStr(0, 1, "Speed: -.--km/h");
TR0 = 1; //打开定时器
timeCnt = 0;
TL0 = 0x66; //设置定时初始值
TH0 = 0xFC; //设置定时初始值 1ms
startFlag = 1; //启动标志
}
oldPinState1 = nowPinState1;
nowPinState2 = INFRARED_STOP;
if (startFlag == 1 && oldPinState2 == 1 && nowPinState2 == 0) //结束探头下降沿触发
{
TR0 = 0; //关闭定时器
timeH = TH0;
timeL = TL0;
speed = 3.6*1000/((float)timeCnt + (float)(65535 - (timeH*256 + timeL))/1000); //设置两个探头距离为1m
if (speed > 999) //速度误操作处理
{
speed = 999;
LCD_DispStr(0, 1, "Speed: Error ");
}
else
{
sprintf(dispRow, "Speed:%6.2fkm/h", (float)speed);
LCD_DispStr(0, 1, dispRow);
UART0_SendStr(dispRow, 16);
UART0_SendStr("\r\n", 2);
if(speed > speedMax) //超过60km/h 蜂鸣器报警3s
{
BUZZER = 0;
DelayS(3);
BUZZER = 1;
}
}
DelayS(3);
LCD_DispStr(0, 1, "Speed: 0.00km/h");
startFlag = 0; //清空启动标志
}
oldPinState2 = nowPinState2;
}
}
void Timer0_Init()
{
TMOD &= 0xF0; //Timer0 16位装载
TMOD |= 0x01;
TL0 = 0x66; //设置定时初始值
TH0 = 0xFC; //设置定时初始值 1ms
TR0 = 0; //关闭T0计时
TF0 = 0; //清除TF0标志
ET0 = 1; //打开T0中断
EA = 1; //打开总中断
}
void Timer0_Intterupt() interrupt 1
{
TL0 = 0x66; //设置定时初始值
TH0 = 0xFC; //设置定时初始值 1ms
if (timeCnt < 0xFFFF)
{
timeCnt++;
}
}
void UART0_Init()
{
SCON = 0x50;
TMOD &= 0x0F;
TMOD |= 0x20; //8位自动重装
TH1 = RH_UART;
TL1 = TH1;
ET1 = 0; //禁止T1中断
TR1 = 1; //启动T1计时
//ES = 1; //打开串口中断
EA = 1; //打开总中断
}
void UART0_SendByte(unsigned char dat) //串口发送单字节数据
{
unsigned char time_out;
time_out = 0x00;
SBUF = dat; //将数据放入SBUF中
while ((!TI) && (time_out < 100)) //检测是否发送出去
{
time_out++;
DelayUs10x(2);
} //未发送出去 进行短暂延时
TI = 0; //清除ti标志
}
void UART0_SendStr(unsigned char *str, unsigned char length) //发送定长度字符串
{
// unsigned char *tmp;
unsigned char cnt = 0;
// unsigned char length = 0;
// tmp = str;
// while (*(tmp++) != '\0')
// {
// length++;
// }
while (cnt < length) //发送长度对比
{
UART0_SendByte(*str); //发送单字节数据
str++; //指针++
cnt++; //下一个++
}
}
//void UART0_Interrupt() interrupt 4
//{
// if (RI)
// {
// RI = 0;
// }
//}