51单片机学习--倒车报警、超声波测距

一.任务
    用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没有在里面)

51单片机学习--倒车报警、超声波测距_第1张图片

51单片机学习--倒车报警、超声波测距_第2张图片

 

2.层次图

51单片机学习--倒车报警、超声波测距_第3张图片

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;
}




 

 

 

 

 

 

 

你可能感兴趣的:(倒车报警系统,超声波测距,单片机)