一.任务
用MCU(型号不限)做一个倒车报警系统。
二.要求
1.基本要求
(1)测量距离,并用数码管显示。
(2)设置3盏LED灯表示,设置如下:
a)大于3m,点亮第1盏LED,不闪烁;
b)大于1m,小于3m,保持第一盏LED不闪烁,同时点亮第2盏LED闪烁,时间间隔为600ms;
c)小于1m,3盏LED以200ms闪烁,同时驱动蜂鸣器发声。
(3)距离小于1m,按下按钮后蜂鸣器停止,3盏LED灯闪烁3次后停止,时间间隔为1000ms。
(4) 循环(1)(2)(3),程序无跑丢;
(5) 最终成品,不能在开发板上实现。
2.发挥部分
(1)通过串口与按下按钮,把当前距离,以文本的形式传递给PC或手机;(用了Esp8266_01s模块)
(2)使用画图工具,来制作电路板。
注意:代码中的esp8266_01s已经提前用串口助手配置好了wifi名字和密码,wifi应用模式为ap模式或ap+station模式都可以。ESP8266_01S的VCC接3.3V,GND与单片机共地,CH_PD端接3.3V(高电平使能),RXD接单片机的TXD,TXD接单片机的RXD。
下载链接:https://download.csdn.net/download/chenger_32123/10577310 里面包含keil工程和代码、Altium Designer软件画的原理图和PCB,可以直接做单层板。
软件:keil 4、stc-isp
1.原理图(ESP8266_01S没有在里面)
2.层次图
3.代码
/*******main.h****/
/*******main.h****/
#ifndef MAIN_H
#define MAIN_H
#ifndef _uchar_
#define _uchar_
typedef unsigned char uchar;
#endif
#ifndef _uint_
#define _uint_
typedef unsigned int uint;
#endif
sbit yiwei=P2^0;
sbit erwei=P2^1;
sbit sanwei=P2^2;
sbit siwei=P2^3;
sbit green_led=P1^0;
sbit yellow_led=P1^1;
sbit red_led=P1^2;
sbit fengmingqi=P1^3;
sbit K1=P1^6;
sbit K2=P1^7;
code uchar duan[12] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x7f,0xff};
// 0 1 2 3 4 5 6 7 8 9 点 关闭
void display(int);
void delay100us();
void delay1s(void);
void delay600ms(void);
void delay200ms(void);
void comint();
uchar read_key();
void key_pro(uchar);
void timer_0(void);
#endif
/**main.c**/
/**main.c**/
/*******************************************
//晶振:12MHz 1T模式:1个时钟周期做一个机器周期
//串口波特率:2400bps@12MHz
*******************************************/
#include
#include
#include"main.h"
#include"hc_sr04_p.h"
uchar i=0;
uchar key_press;
uchar key_value;
bit key_re;
bit en_flag;
bit k1_flag;
bit k2_flag;
bit flag_1;
int temp_distance;
uchar str_1[]="AT+CIPMUX=1\r\n"; //ESP8266_01S启动多连接
uchar str_2[]="AT+CIPSERVER=1,8080\r\n"; //开启server模式,端口为8080
uchar str_3[]="AT+CIPSEND=0,10\r\n"; //向连接序号为0的客户,发送长度为10个字节数据
uchar str[]="X.XXX米 ";
uchar *p;
/********************************************************/
/*延时函数,延时1S*/
/********************************************************/
void delay1s(void) //误差 0us
{
unsigned char a,b,c;
for(c=46;c>0;c--)
for(b=152;b>0;b--)
for(a=70;a>0;a--);
_nop_(); //if Keil,require use intrins.h
}
/********************************************************/
/*延时函数,延时600mS*/
/********************************************************/
void delay600ms(void) //误差 0us
{
unsigned char a,b,c;
for(c=55;c>0;c--)
for(b=82;b>0;b--)
for(a=65;a>0;a--);
}
/********************************************************/
/*延时函数,延时200mS*/
/********************************************************/
void delay200ms(void) //误差 0us
{
unsigned char a,b,c;
for(c=67;c>0;c--)
for(b=142;b>0;b--)
for(a=9;a>0;a--);
}
/********************************************************/
/*延时函数*/ //100微秒
/********************************************************/
void delay100us()
{
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
}
/********************************************************/
/*主函数*/
/********************************************************/
void main()
{
P0=0xff;
P1=0xff;
P2=0xbf;
TMOD=0x21; //定时器1为波特率发生器,定时器0为计时器
SCON=0x50;
PCON=0x00; //波特率不倍增
TH1=0xF3; //波特率为2400
TL1=0xF3;
PS=1; //串口中断优先级最高
ES=1; //串口中断打开
TH0=(65536-20000)/256;
TL0=(65536-20000)%256;
EA=1; //开总中断
// ET1=1; //允许定时器1中断
ET0=1; //允许定时器0中断
TR0=1; //启动定时器0
TR1=1;
delay600ms(); //延时
p=&str_1;
SBUF=*p;
delay600ms();
p=&str_2;
SBUF=*p;
delay200ms();
while(1)
{
while(temp_distance >= 3000) //距离大于等于3米
{
fengmingqi=1;
green_led=0;
yellow_led=1;
red_led=1;
}
while(temp_distance <3000 && temp_distance >= 1000) //距离小于3米而大于等于1米
{
fengmingqi=1;
green_led=0;
yellow_led=~yellow_led;
red_led=1;
delay600ms();
}
while(temp_distance < 1000) //距离小于1米
{
green_led=1;
yellow_led=1;
red_led=1;
en_flag=1;
while(temp_distance < 1000)
{
fengmingqi=0;
green_led=~green_led;
yellow_led=~yellow_led;
red_led=~red_led;
delay200ms();
if(k1_flag)
{
uchar b;
fengmingqi=1;
for(b=0;b<6;b++)
{
green_led=~green_led;
yellow_led=~yellow_led;
red_led=~red_led;
delay1s();
}
k1_flag=0;
}
}
en_flag=0;
}
}
}
/********************************************************/
/*定时器0中断函数*/
/********************************************************/
void timer_0(void) interrupt 1
{
uchar a;
TH0=(65536-20000)/256;
TL0=(65536-20000)%256;
a=read_key();
if(a != 0xc0)
{
key_pro(a);
}
i++;
if(i==7)
{
if(k2_flag)
{
p=&str;
SBUF=*p;
}
if(flag_1)
{
flag_1=0;
p=&str;
SBUF=*p;
}
}
if(i >= 16)
{
TR0=0;
ET0=0;
i=0;
temp_distance=read_hcsr04p();
TH0=(65536-20000)/256;
TL0=(65536-20000)%256;
ET0=1;
TR0=1;
if(k2_flag)
{
str[0]=temp_distance/1000 + '0';
str[2]=temp_distance%1000/100 + '0';
str[3]=temp_distance%1000%100/10 + '0';
str[4]=temp_distance%1000%100%10 + '0';
p=&str_3;
SBUF=*p; //发送给串口
}
}
display(temp_distance);
}
/********************************************************/
/*串口中断函数*/
/********************************************************/
void comint() interrupt 4
{
if(RI) RI=0;
if(TI)
{
TI=0;
p++;
if(*p != '\0') SBUF=*p;
}
}
/********************************************************/
/*读取键值函数*/
/********************************************************/
uchar read_key()
{
uchar key_temp;
key_temp = (P1&0xc0);
if(key_temp != 0xc0) //有按键按下
key_press++;
else
key_press = 0; //抖动
if(key_press == 2)
{
key_press = 0;
key_re = 1;
switch(key_temp)
{
case 0x80:
key_value = 1; //按下了k1
break;
case 0x40:
key_value = 2; //按下了k2
break;
}
}
//连续两次检测到按键被按下,并且该按键已经释放
if((key_re == 1) && (key_temp == 0xc0))
{
key_re = 0;
return key_value;
}
return 0xc0; //无按键按下或被按下的按键未被释放
}
/********************************************************/
/*键值处理函数*/
/********************************************************/
void key_pro(uchar key_temp)
{
switch(key_temp)
{
case 1:
if(en_flag)
{
k1_flag=1;
}
break;
case 2:
k2_flag=~k2_flag;
if(~k2_flag) flag_1=1;
break;
}
}
/********************************************************/
/*数码管显示*/
/********************************************************/
void display(int a)
{
yiwei=0;
P0=duan[a/1000];
delay100us();
P0=duan[10]; //显示数码管的dp点
delay100us();
P0=0xff; //关闭,消隐
yiwei=1;
erwei=0;
P0=duan[a%1000/100];
delay100us();
P0=0xff; //关闭,消隐
erwei=1;
sanwei=0;
P0=duan[a%1000%100/10];
delay100us();
P0=0xff; //关闭,消隐
sanwei=1;
siwei=0;
P0=duan[a%1000%100%10];
delay100us();
P0=0xff; //关闭,消隐
siwei=1;
}
/*****HC_SR04_P.H*****/
/*****HC_SR04_P.H*****/
#ifndef HC_SR04_P_H
#define HC_SR04_P_H
#ifndef _uchar_
#define _uchar_
typedef unsigned char uchar;
#endif
#ifndef _uint_
#define _uint_
typedef unsigned int uint;
#endif
sbit Trig=P2^6; //发送端
sbit Echo=P2^7; //接收端
int read_hcsr04p();
void send_high();
#endif
/*****HC_SR04_P.c*****/
/*
单片机:stc90c51
晶振:12MHZ
功能:
*/
#include
#include
#include"HC_SR04_P.h"
int read_hcsr04p()
{
int distance;
uint t;
TMOD=0x21;
TH0=0;
TL0=0;
send_high();
while(Echo==0);
TR0=1;
while((Echo==1) && (TF0==0));
TR0=0;
if(TF0==1)
{
TF0=0;
distance=9999;
return distance;
}
else
{
t = TH0;
t <<= 8;
t |= TL0;
distance = (int)(t*0.17+0.5); //计算距离,单位mm
} //音速0.34mm/uS
return distance;
}
void send_high()
{
Trig = 1;
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
//输出40微秒的高电平,触发测距
Trig = 0;
}