找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 7411|回复: 3
收起左侧

基于51单片机的超声波测距设计程序+Proteus仿真图

  [复制链接]
ID:264608 发表于 2018-7-3 17:57 | 显示全部楼层 |阅读模式
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
51hei.gif

单片机源程序如下:
  1. #include<reg52.h>
  2. #include<intrins.h>             //声明void _nop_(void);
  3. #defineuint  unsigned int
  4. #defineuchar unsigned char
  5. #defineNOP() {_nop_();_nop_();_nop_();_nop_();}
  6. sbit PL=P1^0;
  7. //------LCD引脚-----
  8. sbit LCD_RS=P2^6;                //将P2.6引脚定义为LCD寄存器选择
  9. sbitLCD_RW=P2^5;               //将P2.5引脚定义为LCD读写信号线
  10. sbitLCD_EN=P2^7;                 //将P2.7引脚定义为LCD使能端
  11. //------超声波引脚-------
  12. sbitTx=P3^3;                            //触发控制信号输入
  13. sbit Rx=P3^2;                           //回响信号输出
  14. ucharcode table[]={"Distance Test:"};         //LCD第一行显示
  15. uchartemp_dis[]= {"000.0 cm"};                        //LCD第二行
  16. longint t,distance;
  17. ucharcache[4]={0,0,0,0};
  18. //--------延时-------
  19. voiddelay(uint ms)
  20. {
  21.        uint t;
  22.        while(ms--)
  23.               for(t=0;t<120;t++);
  24. }
  25. //-------读LCD状态-------
  26. ucharread_lcd_state()
  27. {
  28.        uchar state;
  29.        LCD_RS=0;              //LCD选择指令寄存器
  30.        LCD_RW=1;             //LCD进行读操作
  31.        LCD_EN=1;                                                      //LCD使能端为高电平
  32.        _nop_();                 // 产生一条NOP指令
  33.        state=P0;
  34.        LCD_EN=0;             //LCD使能端为低电平
  35.        _nop_();
  36.        returnstate;                                 //返回函数
  37. }
  38. //-------忙等待------
  39. voidlcd_busy_wait()
  40. {
  41.        while((read_lcd_state() &0x80)==0x80);
  42.        NOP();
  43. }
  44. //----------LCD写指令----------
  45. voidlcd_write_com(uchar com)
  46. {
  47.        lcd_busy_wait();
  48.        LCD_RS=0;               //RS为0时,写指令,RS为1时,写数据
  49.        LCD_RW=0;          //LCD进行写操作
  50.        P0=com;              //把命令字送入P0
  51.        NOP();                               //延时一个机器周期1us
  52.        LCD_EN=1;
  53.        NOP();
  54.        LCD_EN=0;
  55. }
  56. //----------LCD写数据----------
  57. voidlcd_write_data(uchar dat)
  58. {
  59.        lcd_busy_wait();
  60.        LCD_RS=1;
  61.        LCD_RW=0;
  62.        P0=dat;                   //把要显示的数据送入P0
  63.        NOP();                              
  64.        LCD_EN=1;
  65.        NOP();
  66.        LCD_EN=0;
  67. }
  68. //-------LCD初始化-------
  69. voidlcd_init()
  70. {
  71.        LCD_EN=0;
  72.        lcd_write_com(0x38);                     //LCD显示模式设置
  73.        lcd_write_com(0x0c);                     //LCD显示开/关及光标设置
  74.        lcd_write_com(0x06);                     //当写一个字符后地址指针加1,且光标加1
  75.        lcd_write_com(0x01);                     //显示清屏
  76. }
  77. //---------设置液晶显示位置-----------
  78. voidset_lcd_pos(uchar p)
  79. {
  80.        lcd_write_com(p|0x80);
  81. }
  82. //---------液晶显示程序----------
  83. voidlcd_print(uchar p,uchar *s,uint low)
  84. {
  85.        uint num;
  86.        set_lcd_pos(p);
  87.        for(num=0;num<low;num++)         
  88.        {
  89.               lcd_write_data(s[num]);
  90.               delay(1);      
  91.        }
  92. }
  93. voidHC05_Init()
  94. {
  95.        Tx=1;                                        //触发脉冲
  96.        NOP();NOP();NOP();NOP();
  97.        Tx=0;
  98.        distance=0.1725*t;                  //距离计算
  99. }
  100. voiddistance_convert(long int dat)
  101. {
  102.        cache[0]=dat/1000;
  103.        cache[1]=dat/100%10;
  104.        cache[2]=dat/10%10;
  105.        cache[3]=dat%10;
  106.        temp_dis[0]=cache[0]+'0';
  107.        temp_dis[1]=cache[1]+'0';
  108.        temp_dis[2]=cache[2]+'0';
  109.        temp_dis[4]=cache[3]+'0';
  110. }
  111. //------------主程序-----------
  112. voidmain()
  113. {
  114.        PL=1;
  115.        delay(20);
  116.        PL=1;
  117.        delay(1000);
  118.        PL=0;
  119.       
  120.        lcd_init();
  121.        delay(5);
  122.        TMOD=0x19;
  123.        EA=1;                 //开总中断
  124.        TR0=1;                //启动定时器
  125.        EX0=1;               //开外部中断
  126.        IT0=1;                 //设置为下降沿中断方式
  127.        while(1)
  128.        {
  129.               HC05_Init();
  130.               distance_convert(distance);
  131.               lcd_print(0x01,table,14);
  132.               lcd_print(0x44,temp_dis,8);
  133.        }
  134. }
  135. //外部中断0
  136. voidint0() interrupt 0
  137. {
  138.        t=(TH0*256+TL0);    //计算高电平持续的时间,上升沿到来时候开始计时,下降沿到来进入外部中断,关闭计时器,停止计时
  139.        TH0=0;
  140.        TL0=0;
  141. }
复制代码
51hei.png

Keil代码与Proteus仿真下载: 基于单片机超声波测距系统 语音提示 程序hex 原理图.zip (60.45 KB, 下载次数: 162)
回复

使用道具 举报

ID:901776 发表于 2022-3-23 15:30 | 显示全部楼层
作者你好图呢
回复

使用道具 举报

ID:1015031 发表于 2022-4-3 15:19 | 显示全部楼层
你好,请教一下,这个可以通过修改程序,连接两个超声波传感器测两个距离,然后用垂直距离比上两个水平距离之差,从而求出坡度吗?   坡度也在1602上显示出来
回复

使用道具 举报

ID:1015031 发表于 2022-4-3 16:09 | 显示全部楼层
请问36行的返回函数是没有的吗?为什么编译程序一直出错呢?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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