找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1018|回复: 6
打印 上一主题 下一主题
收起左侧

Proteus仿真单片机超声波检测 要加一个报警电路,小于40cm报警,程序不知道怎么写

[复制链接]
跳转到指定楼层
楼主
ID:985137 发表于 2022-3-27 17:26 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include<reg51.h>
#include<intrins.h>
#define uint  unsigned int
#define uchar unsigned char
#define NOP() {_nop_();_nop_();_nop_();_nop_();}

//------LCD引脚------
sbit lcd_rs=P2^0;
sbit lcd_en=P2^2;

//------超声波引脚-------
sbit TR=P3^2;                //回响信号输出
sbit ECHO=P3^3;              //触发控制信号输入
uchar code table[]={" Distance Test:"};                //LCD第一行显示
uchar temp_dis[]= {"    000.0 cm"};                    //LCD第二行
long int t,distance;
uchar cache[4]={0,0,0,0};

//--------延时-------
void delay(uint ms)
{
        uint t;
        while(ms--)
        for(t=0;t<30;t++);
}

void write_com(uchar com);//init_lcd()函数需要用到,所以先提前声明

//************LCD1602初始化函数************************
void init_lcd()
{
        write_com(0x38);           //设置16*2显示,5*7点阵,8位数据接口
        write_com(0x08);           //写一个字符后地址指针加1
        write_com(0x01);           //显示清零,数据指针清零
        write_com(0x06);           //写一个字符后地址指针加1
        write_com(0x0c);           //关显示,光标不显示不闪烁
}

//************LCD1602写指令函数************************
void write_com(uchar com)   //lcd1602写指令:rs低电平,rw低电平,en从高电平变为低电平
{
        delay(5);
        lcd_rs = 0;                           // 选择写指令
        lcd_en = 0;                           // 将使能端置0
        P0 = com;                           // 将要写的命令送到数据总线上
        delay(5);                           // 延时5ms,待数据稳定
        lcd_en = 1;                           // 由于初始化已将lcd_en置为0,使能端给一个高脉冲,
        delay(5);                           // 延时5ms,待数据稳定
        lcd_en = 0;                           // 将使能端置0以完成脉冲
}

//************LCD1602写数据函数************************
void write_data(uchar date)//lcd1602写数据:rs高电平,rw低电平,en从高电平变低电平
{
        delay(5);
        lcd_rs = 1;                           // 选择写数据
        lcd_en = 0;                           // 将使能端置0
        P0 = date;                           // 将要写的数据送到数据总线上
        delay(5);                           // 延时5ms,待数据稳定
        lcd_en = 1;                           // 由于初始化已将lcd_en置为0,使能端给一个高脉冲,
        delay(5);                           // 延时5ms,待数据稳定
        lcd_en = 0;                           // 将使能端置0以完成脉冲
}

//************LCD1602显示函数******************
void lcd1602_display(uchar *q,uchar *p)//*通过指针p和q分别指向两个数组的第一个数,然后进行数组扫描显示,一次性显示两行字符
{
        write_com(0x80);             // 现将数据指针定位到第一行第一个字处
        while(*q!='\0')
        {
                write_data(*q);
                q++;
                delay(1);      
        }
        write_com(0xc0);           // 现将数据指针定位到第二行第一个字处
        while(*p!='\0')
        {
                write_data(*p);
                p++;
                delay(1);      
        }
}

//************LCD1602显示欢迎函数******************
void HC05_Init()                          //超声波模块初始化函数
{
        ECHO=1;                                 //触发脉冲
        NOP();NOP();NOP();NOP();
        ECHO=0;
        distance=0.1725*t;                       //距离计算
}

void distance_convert(long int dat)             //距离计算函数
{
        cache[0]=dat/1000;
        cache[1]=dat/100%10;
        cache[2]=dat/10%10;
        cache[3]=dat%10;
        temp_dis[4]=cache[0]+'0';
        temp_dis[5]=cache[1]+'0';
        temp_dis[6]=cache[2]+'0';
        temp_dis[8]=cache[3]+'0';
}                                 

//------------主程序-----------
void main()
{              
        init_lcd();
        delay(5);
        TMOD=0x09;        //定时器T0工作方式1  GATE0=1
        EA=1;                        //开总中断
        TR0=1;                        //启动定时器
        EX0=1;                        //开外部中断
        IT0=1;                        //设置为下降沿中断方式
        while(1)
        {                              
                HC05_Init();
                distance_convert(distance);
                lcd1602_display(table,temp_dis);               
        }
}

//外部中断0
void int0() interrupt 0
{
        t=(TH0*256+TL0);  //计算高电平持续的时间,上升沿到来时候开始计时,下降沿到来进入外部中断,关闭计时器,停止计时
        TH0=0;
        TL0=0;
}


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:688692 发表于 2022-3-28 08:54 | 只看该作者
        while(1)
        {                              
                HC05_Init();
                distance_convert(distance);
                lcd1602_display(table,temp_dis);
                if(distance<40){蜂鸣器管脚=0;}else{蜂鸣器管脚=1;}
        }
回复

使用道具 举报

板凳
ID:123289 发表于 2022-3-28 11:01 | 只看该作者
要先画逻辑图,逻辑图走通了,再写程序。
回复

使用道具 举报

地板
ID:121859 发表于 2022-3-28 13:46 | 只看该作者
先发送启动信号,等待回馈信号变高,立即启动定时器0开始计时。等待回馈信号变低,立即暂停定时器0停止计时,读取定时器0的计时时间,按声速*时间计算出距离。
回复

使用道具 举报

5#
ID:985137 发表于 2022-3-28 16:56 | 只看该作者
cnos 发表于 2022-3-28 08:54
while(1)
        {                              
                HC05_Init();

写过这个程序,没用
回复

使用道具 举报

6#
ID:123289 发表于 2022-3-29 08:22 | 只看该作者
听我的话,没错,就怕你做不了。
回复

使用道具 举报

7#
ID:1014303 发表于 2022-3-31 02:43 来自手机 | 只看该作者
你可以找一找别人的改一下就好了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表