功能:
0.本系统采用STC89C52作为单片机
1.该系统采用的是两个USB小灯作为模拟汽车远光灯和近光灯
2.采用HC-SR04超声波模块模拟汽车障碍物检测系统
3.采用光敏电阻来检测环境光,汽车灯光根据环境光的情况来开启或则关闭车灯
4.采用DC002作为电源接口可直接输入5V给整个系统供电
原理图:
PCB :
主程序:
#include <reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include <stdio.h>
#include "delay.h"
//#include "math.h"
#define MANUAL 0
#define AUTO 1
sbit TRIG = P1^0; //出发放超声波
sbit ECHO = P1^1; //检测反馈
sbit LIGHT_FLAG = P1^2;
sbit HIGH_BEAM = P2^2; //远光灯
sbit LOW_BEAM = P2^3; //近光灯
sbit LED_MANUAL = P2^0; //手动模式指示灯
sbit LED_AUTO = P2^1; //自动模式指示灯
sbit KEY_CHANGE = P3^7; //远近光灯切换按键
sbit KEY_SWITCH = P3^6; //关灯按键
sbit KEY_MODE = P3^2; //自动手动切换
bit TrigFlag = 0; //触发标志
unsigned char LEDFlag = 0; //远近光灯标志
float distance = 0; //实际测试距离
bit modeFlag = 0; //手动自动模式变量
bit switchFlag = 0;
bit rekey0;
bit rekey1;
bit rekey2; //按键防止重复变量
void Timer0_Init(); //函数声明
void Timer1_Init();
void KeyProcess();
void main()
{
TRIG = 0;
Timer0_Init(); //定时器0初始化
Timer1_Init();
HIGH_BEAM = 0; //远光灯
LOW_BEAM = 0; //近光灯
LED_MANUAL = 0; //手动指示灯
LED_AUTO = 0; //自动指示灯
DelayS(1);
HIGH_BEAM = 1; //远光灯
LOW_BEAM = 1; //近光灯
LED_MANUAL = 1; //手动灯
LED_AUTO = 1; //自动灯
while (1) //主循环
{
if (TrigFlag == 1)
{
TR0 = 0;
TrigFlag = 0;
TRIG = 1; //启动一次模块 //不可以使用其他终端 容易造成死循环
DelayUs10x(1);
TRIG = 0;
while (!ECHO)
; //当RX为零时等待
TR1 = 1; //开启计数
while (ECHO)
; //当RX为1计数并等待
TR1 = 0;
distance = 1.12 * ((float)TH1 * 256 + TL1) * 17 / 100; //算出来是mm,1.12为系数
TH1 = 0;
TL1 = 0;
TH0 = (65536 - 18432) / 256; //重新赋值 20ms
TL0 = (65536 - 18432) % 256;
TR0 = 1;
}
if (switchFlag == 1)
{
if (modeFlag == AUTO) //自动模式下
{
LED_MANUAL = 1;
LED_AUTO = 0;
if (LIGHT_FLAG == 1) //光照暗
{
if (distance < 300)
{
LOW_BEAM = 0; //近光灯开
HIGH_BEAM = 1; //远光灯关
}
else
{
LOW_BEAM = 1; //近光灯关
HIGH_BEAM = 0; //远光灯开
}
}
else
{
LOW_BEAM = 1; //近光灯关
HIGH_BEAM = 1; //远光灯关
}
}
else
{
LED_MANUAL = 0;
LED_AUTO = 1;
if (LEDFlag == 0)
{
LOW_BEAM = 1; //近光灯关
HIGH_BEAM = 1; //远光灯关
}
else if (LEDFlag == 1)
{
LOW_BEAM = 0; //近光灯开
HIGH_BEAM = 1; //远光灯关
}
else
{
LOW_BEAM = 1; //近光灯关
HIGH_BEAM = 0; //远光灯开
}
}
}
else
{
LOW_BEAM = 1; //近光灯关
HIGH_BEAM = 1; //远光灯关
//指示灯闪烁,有助于判断程序是否运行
LED_MANUAL = 1;
LED_AUTO = 1;
DelayMs(250);
DelayMs(250);
LED_MANUAL = 0;
LED_AUTO = 0;
DelayMs(250);
DelayMs(250);
}
KeyProcess();
}
}
void KeyProcess()
{
if (switchFlag == 1)
{
if (KEY_MODE == 0) //手动自动切换
{
DelayMs(10);
if (KEY_MODE == 0 && rekey0 == 0)
{
rekey0 = 1;
modeFlag = ~modeFlag;
}
} //切换置位对应灯亮
else
{
rekey0 = 0;
}
if (modeFlag == MANUAL) //手动模式下
{
if (KEY_CHANGE == 0) //远光灯切换按键
{
DelayMs(10);
if (KEY_CHANGE == 0 && rekey1 == 0) //远光灯切换按键
{
rekey1 = 1;
if (LEDFlag >= 2)
{
LEDFlag = 1;
}
else
{
LEDFlag++;
}
}
}
else
{
rekey1 = 0;
}
}
}
if (KEY_SWITCH == 0) //切换按键
{
DelayMs(10);
if (KEY_SWITCH == 0 && rekey2 == 0) //切换按键
{
rekey2 = 1;
switchFlag = ~switchFlag;
}
}
else
{
rekey2 = 0;
}
}
void Timer0_Init()
{
TMOD &= 0xF0;
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
TH0 = (65536 - 18432) / 256; //重新赋值 20ms
TL0 = (65536 - 18432) % 256;
EA = 1; //总中断打开
ET0 = 1; //定时器中断打开
TR0 = 1; //定时器开关打开
}
void Timer1_Init()
{
TMOD &= 0x0F;
TMOD |= 0x10; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
TH1 = 0;
TL1 = 0;
EA = 1; //总中断打开
ET1 = 1; //定时器中断打开
TR1 = 0; //定时器开关关闭
}
void Timer0_Interrupt() interrupt 1
{
static unsigned int cnt = 0;
TH0 = (65536 - 18432) / 256; //重新赋值 20ms
TL0 = (65536 - 18432) % 256;
cnt++;
if (cnt > 50) //1s定时发出超声波
{
TrigFlag = 1;
cnt = 0;
}
}
void Timer1_Interrupt() interrupt 3
{
TH1 = 0;
TL1 = 0;
}