找回密码
 立即注册

QQ登录

只需一步,快速开始

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

超声波测距+1602显示 单片机程序

[复制链接]
跳转到指定楼层
楼主
ID:380156 发表于 2019-7-20 09:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本人亲自看视频一手敲出来的   实测能用    代码比较规范好看点

单片机源程序如下:
  1. #include <reg52.h>
  2. #include <intrins.h>

  3. #define uint unsigned  int
  4. #define uchar unsigned char

  5. sbit in=P1^1;   //超声波接收            就是ECHO
  6. sbit out=P1^0; // 发射                 就是TRIG

  7. //lcd1602端口定义

  8. sbit RS= P3^5;       //寄存器选择位
  9. sbit RW = P3^6;        //读写选择位
  10. sbit E = P3^4;        //使能
  11. sbit BF=P0^7;          //忙碌标志

  12. #define LCD1602data P0


  13.   uint time;              //无符号整型
  14. unsigned  long s=0;                 //无符号长整型
  15. bit flag;                    //超声波超出量程标志位
  16.   uint s1,s2,s3;



  17. //  1602模块语句

  18. //延时一毫秒

  19. void delay1ms()
  20. {
  21.          unsigned char i,j;
  22.          for(i=0;i<10;i++)
  23.          for(j=0;j<33;j++);
  24.          
  25. }

  26. //延时若干毫秒    入口参数N

  27. void delay(unsigned int n)
  28. {

  29. unsigned int i;
  30.          for(i=0;i<n;i++)
  31.    delay1ms();
  32.          
  33. }

  34. //判断液晶忙碌状态   
  35. // 返回值  result  result=1 忙碌   result=0 不忙

  36. bit BusyTest(void)
  37. {

  38.      bit result;      //为位类型    长度0或1
  39.             RS=0;
  40.             RW=1;        ///RS=0  RW=1   读状态
  41.             E=1;     //  e=1  允许读写
  42.            _nop_();    // kong操作
  43.      _nop_();
  44.            _nop_();
  45.            _nop_();
  46.            result=BF;    //将忙碌电平给RESULT
  47.              E=0;
  48.            return result;
  49.          
  50. }
  51.          

  52. //  将模式指令 显示地址写入液晶
  53. // 入口参数 dictate

  54.         void Write_com (unsigned char  dictate)     //写命令字   lcd_w_cmd
  55.         {
  56.        
  57.         while(BusyTest()==1);   //忙碌等待
  58.      RS=0;            //RS RW同时为0 才能写入指令
  59.      RW=0;
  60.      E=0;                   //先置零  01跳变
  61.                
  62.                 _nop_();
  63.                 _nop_();             //空操作  硬件反应
  64.                 LCD1602data=dictate;    //将数据送入P0口  写入指令或地址
  65.                 _nop_();
  66.                 _nop_();
  67.                 _nop_();
  68.                 _nop_();
  69.            E=1;  
  70.      _nop_();
  71.      _nop_();               
  72.            _nop_();
  73.                  _nop_();
  74.             E=0;
  75.        
  76.         }
  77.   
  78. //指定字符显示实际地址   入口参数x
  79.        
  80.         void WriteAddress(unsigned char x)

  81. {  
  82.     Write_com(x|0x80);        //显示位置确定为80+地址码X
  83.        
  84. }


  85.   //将字符写入液晶    入口参数Y

  86. void WriteData(unsigned char y)       //lcd_w_dat

  87. {

  88.    while (BusyTest()==1);
  89.    RS=1;
  90.          RW=0;
  91.          E=0;       
  92.    LCD1602data=y;  // 将数据送入P0口   即将数据写入液晶模块
  93.          _nop_();
  94.          _nop_();
  95.          _nop_();
  96.          _nop_();
  97.           E=1;
  98.          _nop_();
  99.          _nop_();
  100.          _nop_();
  101.          _nop_();
  102.          
  103.          E=0;        //液晶模块执行命令
  104.          
  105.          }

  106. // LCD初始化
  107.          
  108.          void LcdInt(void)
  109.          {
  110.          
  111.          delay(15);
  112.                  Write_com(0x38);     //显示模式设置  16*2 5*7点阵  8位数据口
  113.                  delay(5);
  114.                  Write_com(0x38);
  115.                  delay(5);
  116.                  Write_com(0x38);
  117.                  delay(5);              //3次写设置模式
  118.         //write_com(0x0f);   显示模式设置  显示开  有光标  光标闪烁
  119. //  delay(5);                 
  120.          

  121.     Write_com(0x0c);     //  显示开    不显示光标
  122.          delay(5);
  123.    
  124.     Write_com(0x06);     //  显示模式设置     光标右移 字符不移
  125.          delay(5);


  126.      Write_com(0x01);     //     清屏指令  以前内容清楚
  127.          delay(5);

  128.          }

  129.          
  130.         //  ADD为显示字符位置  在第二行显示  X为显示字符
  131.          //  调用函数注意  函数为显示数字  display(10,9);  display(10,a)
  132.          //分别表示第二行第十位显示数字9和A代表的数字
  133.          //  如果想把此函数改写成显示字母的
  134.          //  只需把最writedata(0x30+x)中的0x30+去掉
  135.          

  136.     display(unsigned char add , unsigned char x)
  137.   {
  138.      WriteAddress(0x00);
  139.     delay(5);

  140.     Write_com(0x80+0x40+add) ;
  141.    
  142.     WriteData(0x30+x);
  143. return 0;
  144.         }  

  145. LCD1602()//1602初显示
  146.                 {
  147.                   LcdInt();
  148.                           delay(10);
  149.                          Write_com(0x01);  //清屏
  150.                           delay(5);
  151.                        
  152.                         WriteAddress(0x00);   //设置显示地址为第一行第一个字   可以不写  默认也是第一行第一个字
  153.                        
  154.                         delay(5);
  155.                        
  156.         //第一行显示  DISTANCE

  157.      WriteData('D');                       
  158.                  WriteData('i');
  159.                  WriteData('s');
  160.                  WriteData('t');
  161.                  WriteData('a');
  162.                  WriteData('n');
  163.                  WriteData('c');
  164.                  WriteData('e');
  165.                  WriteData(':');
  166. return 0;       
  167.                 }
  168.                

  169.    //以上1602模块语句
  170.                
  171.                 void FS()      //  发送超声波
  172.         {
  173.                
  174.             out=1;
  175.                         _nop_();
  176.                   _nop_();
  177.                         _nop_();
  178.                         _nop_();
  179.                         _nop_();
  180.                         _nop_();
  181.                         _nop_();
  182.                         _nop_();
  183.                         _nop_();
  184.                         _nop_();
  185.                         _nop_();
  186.                         _nop_();
  187.                         _nop_();
  188.                         _nop_();
  189.                         _nop_();
  190.                         _nop_();
  191.                         _nop_();
  192.                         _nop_();
  193.                         _nop_();
  194.                         _nop_();
  195.                        
  196.                         out=0;
  197.   }

  198. void count(void)//  计算并显示超声波测到距离

  199. {

  200.         time=TH0*256+TL0;
  201.                TH0=0;
  202.                TL0=0;
  203.          
  204.               s=(time*1.7)/100;      //算出来单位为CM
  205.             if ((s>700)||flag==1)    //超出测量范围显示ERROR
  206.                         {

  207.                                 flag=0;
  208.                                
  209.                                 Write_com(0x80+0x40+11);
  210.                         WriteData('E');   delay(5);
  211.                         WriteData('R');   delay(5);
  212.       WriteData('R');   delay(5);
  213.                         WriteData('O') ;  delay(5);
  214.                         WriteData('R') ;  delay(5);
  215.                   delay(500);
  216.                
  217.                          }
  218.    else
  219.          {
  220.                  s1=s%1000/100;
  221.                  s2=s%1000%100/10;
  222.                  s3=s%1000%10%10;
  223.       display(11,s1);            //s1  为上面的X     11为上面的Y
  224.                  WriteData('.');
  225.                    display(13,s2);
  226.                  display(14,s3);
  227.                  WriteData('m');
  228.                  delay(500);
  229.          }
  230.                
  231. }
  232.                
  233.                 void zd0() interrupt 1     //t0中断用来计数器溢出   超过测量范围
  234.                        
  235. {
  236.     flag=1;

  237. }
  238.                
  239. int main()
  240. {
  241.     LCD1602();
  242.         //while (1)
  243.    
  244.         TMOD=0X01;     //设置T0为方式1   GATE=0;
  245.         TH0=0;
  246.         TL0=0;
  247.         ET0=1;         //  允许T0中断
  248.         EA=1;
  249.            while(1)
  250.                  {
  251.                     FS();
  252.                          while(!in);
  253.                          TR0=1;
  254.                          while (in);
  255.                           TR0=0;
  256.                          count();
  257.                
  258.                  }
  259.        
  260.         }
复制代码

所有资料51hei提供下载:
超声波测距22.zip (45.26 KB, 下载次数: 90)


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

使用道具 举报

沙发
ID:580104 发表于 2019-7-23 12:44 | 只看该作者
谢谢楼主。
回复

使用道具 举报

板凳
ID:643576 发表于 2019-11-29 20:31 | 只看该作者
好评,看的很清楚,能不能给加个报警器,求程序
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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