找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机超声波测距,用的HC-SR04 下面程序显示的三位测距结果,我想显示四位该怎么...

[复制链接]
跳转到指定楼层
楼主
ID:756037 发表于 2020-5-19 21:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
能否直接添加  dis_smg[3] = smg_du[set_d / 1000] & 0xdf;

单片机源程序如下:
  1. #include <reg52.h>
  2. #include <intrins.h>
  3. #include "eepom52.h"
  4. #define uchar unsigned char
  5. #define uint  unsigned int</div><div>//数码管段选定义      0     1    2    3    4    5              6              7                8                 9            
  6. uchar code smg_du[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
  7.                                                                         0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff};              //断码
  8. //数码管位选定义
  9. uchar code smg_we[]={0xe0,0xd0,0xb0,0x70};
  10. uchar dis_smg[8]   ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8};</div><div>sbit smg_we1 = P3^4;                //数码管位选定义
  11. sbit smg_we2 = P3^5;
  12. sbit smg_we3 = P3^6;
  13. sbit smg_we4 = P3^7;</div><div>sbit c_send   = P3^2;                            //超声波发射
  14. sbit c_recive = P3^3;                            //超声波接收
  15. uchar flag_hc_value;        //超声波中间变量</div><div>sbit beep = P2^3;   //蜂鸣器IO口定义
  16. bit flag_key_b_en,flag_key_set_en;   //按键蜂鸣器使能</div><div>
  17. uchar smg_i = 3;    //显示数码管的个位数
  18. bit flag_300ms ;</div><div>bit key_500ms  ;</div><div>
  19. long distance;                      //距离
  20. uint set_d;                          //距离
  21. bit flag_csb_juli;        //超声波超出量程
  22. uint  flag_time0;     //用来保存定时器0的时候的</div><div>//  按键的IO变量的定义
  23. uchar key_can;                            //按键值的变量
  24. uchar zd_break_en,zd_break_value;   //自动退出设置界面
  25. uchar menu_shudu = 10;  //用来控制连加的速度
  26. bit flag_lj_en;                            //按键连加使能
  27. bit flag_lj_3_en;              //按键连3次连加后使能 加的数就越大了
  28. uchar key_time,flag_value;      //用做连加的中间变量
  29. uchar menu_1;        //菜单设计的变量
  30. uchar a_a;</div><div>
  31. /***********************1ms延时函数*****************************/
  32. void delay_1ms(uint q)
  33. {
  34.               uint i,j;
  35.               for(i=0;i<q;i++)
  36.                             for(j=0;j<120;j++);
  37. }</div><div>/***********************处理距离函数****************************/
  38. void smg_display()
  39. {
  40.               dis_smg[0] = smg_du[distance % 10];
  41.               dis_smg[1] = smg_du[distance / 10 % 10];
  42.               dis_smg[2] = smg_du[distance / 100 % 10] & 0x7f;            
  43. }</div><div>/******************把数据保存到单片机内部eepom中******************/
  44. void write_eepom()
  45. {
  46.               SectorErase(0x2000);
  47.               byte_write(0x2000, set_d % 256);
  48.               byte_write(0x2001, set_d / 256);
  49.               byte_write(0x2058, a_a);            
  50. }</div><div>/******************把数据从单片机内部eepom中读出来*****************/
  51. void read_eepom()
  52. {
  53.               set_d  = byte_read(0x2001);
  54.               set_d <<= 8;
  55.               set_d  |= byte_read(0x2000);
  56.               a_a      = byte_read(0x2058);
  57. }</div><div>/**************开机自检eepom初始化*****************/
  58. void init_eepom()
  59. {
  60.               read_eepom();                            //先读
  61.               if(a_a != 1)                            //新的单片机初始单片机内问EEPOM
  62.               {
  63.                             set_d = 100;
  64.                             a_a = 1;
  65.                             write_eepom();
  66.               }            
  67. }
  68. /****************独立按键处理函数********************/
  69. void key()
  70. {
  71.               static uchar key_new = 0,key_old = 0,key_value = 0;
  72.               if(key_new == 0)                                         
  73.               {                                                                                       //按键松开的时候做松手检测
  74.                             if((P2 & 0x07) == 0x07)
  75.                                           key_value ++;
  76.                             else
  77.                                           key_value = 0;
  78.                             if(key_value >= 5)
  79.                             {
  80.                                           key_value = 0;
  81.                                           key_new = 1;
  82.                                           flag_lj_en = 0;                            //关闭连加使能
  83.                                           flag_lj_3_en = 0;              //关闭3秒后使能
  84.                                           flag_value = 0;                            //清零
  85.                                           key_time = 0;
  86.                                           write_eepom();
  87.                             }
  88.               }
  89.               else
  90.               {
  91.                             if((P2 & 0x07) != 0x07)
  92.                                           key_value ++;  //按键按下的时候
  93.                             else
  94.                                           key_value = 0;
  95.                             if(key_value >= 5)
  96.                             {
  97.                                           key_value = 0;
  98.                                           key_new = 0;
  99.                                           flag_lj_en = 1;              //连加使能
  100.                                           zd_break_en = 1; //自动退出设置界使能
  101.                                           zd_break_value = 0; //自动退出设置界变量清零
  102.                                           flag_key_b_en = 1;  //按键蜂鸣器使能
  103.                             }
  104.               }
  105.               key_can = 20;
  106.               if(key_500ms == 1)              //连加
  107.               {
  108.                             key_500ms = 0;
  109.                             key_new = 0;
  110.                             key_old = 1;
  111.                             zd_break_value = 0;
  112.               }
  113.               if((key_new == 0) && (key_old == 1))
  114.               {
  115.                             switch(P2 & 0x07)
  116.                             {
  117.                                           case 0x06: key_can = 3; break;                 //得到k2键值
  118.                                           case 0x05: key_can = 2; break;                 //得到k3键值
  119.                                           case 0x03: key_can = 1; break;                 //得到k4键值
  120.                             }
  121. //                            dis_smg[3] = smg_du[key_can % 10];</div><div>              }                                         
  122.               key_old = key_new;            
  123. }</div><div>
  124. void smg_we_switch(uchar i)
  125. {
  126.               switch(i)
  127.               {
  128.                             case 0: smg_we1 = 0;  smg_we2 = 1; smg_we3 = 1;  smg_we4 = 1; break;
  129.                             case 1: smg_we1 = 1;  smg_we2 = 0; smg_we3 = 1;  smg_we4 = 1; break;
  130.                             case 2: smg_we1 = 1;  smg_we2 = 1; smg_we3 = 0;  smg_we4 = 1; break;
  131.                             case 3: smg_we1 = 1;  smg_we2 = 1; smg_we3 = 1;  smg_we4 = 0; break;
  132.               }            
  133. }</div><div>/***********************数码显示函数*****************************/
  134. void display()
  135. {
  136.               static uchar i;  
  137.               i++;
  138.               if(i >= smg_i)
  139.               i = 0;            
  140. //              P1 = 0xff;                            //段选                  
  141. //              P3 = 0xf0 | (P3 & 0x0f); //位选
  142. //              P3 = smg_we[i] | (P3 & 0x0f); //位选
  143.               smg_we_switch(i);
  144.               P1 = dis_smg[i];                            //段选                  </div><div>}</div><div>void delay()
  145. {
  146.               _nop_();                                        //执行一条_nop_()指令就是1us
  147.               _nop_();
  148.               _nop_();
  149.               _nop_();
  150.               _nop_();
  151.               _nop_();
  152.               _nop_();
  153. }</div><div>
  154. /*********************超声波测距程序*****************************/
  155. void send_wave()
  156. {
  157.               c_send = 1;                                       //10us的高电平触发
  158.               delay();
  159.               c_send = 0;            
  160.               TH0 = 0;                                      //给定时器0清零
  161.               TL0 = 0;
  162.               TR0 = 0;                                                          //关定时器0定时
  163.               flag_hc_value = 0;
  164.               while(!c_recive);                              //当c_recive为零时等待
  165.               TR0=1;
  166.               while(c_recive)                                  //当c_recive为1计数并等待
  167.               {
  168.                             flag_time0 = TH0 * 256 + TL0;
  169.                             if((flag_hc_value > 1) || (flag_time0 > 65000))      //当超声波超过测量范围时,显示3个888
  170.                             {
  171.                                           TR0 = 0;
  172.                                           flag_csb_juli = 2;
  173.                                           distance = 888;
  174.                                           flag_hc_value = 0;
  175.                                           break ;                           
  176.                             }
  177.                             else
  178.                             {
  179.                                           flag_csb_juli = 1;            
  180.                             }
  181.               }
  182.               if(flag_csb_juli == 1)
  183.               {            
  184.                             TR0=0;                                                                                                  //关定时器0定时
  185.                             distance = TH0;                                                             //读出定时器0的时间
  186.                             distance = distance * 256 + TL0;
  187.                             distance +=( flag_hc_value * 65536);//算出超声波测距的时间              得到单位是ms
  188.                             distance *= 0.017;               // 0.017 = 340M / 2 = 170M = 0.017M 算出来是米
  189.                             if(distance > 350)                                                        //距离 = 速度 * 时间
  190.                             {            
  191.                                           distance = 888;                                                        //如果大于3.8m就超出超声波的量程
  192.                             }
  193.               }
  194. }</div><div>
  195. /*********************定时器0、定时器1初始化******************/
  196. void time_init()               
  197. {
  198.               EA  = 1;                              //开总中断
  199.               TMOD = 0X11;                //定时器0、定时器1工作方式1
  200.               ET0 = 1;                              //开定时器0中断
  201.               TR0 = 1;                              //允许定时器0定时
  202.               ET1 = 1;                              //开定时器1中断
  203.               TR1 = 1;                              //允许定时器1定时            
  204. }</div><div>/****************按键处理数码管显示函数***************/
  205. void key_with()
  206. {
  207.               if(key_can == 1)
  208.               {
  209.                             menu_1 ++;
  210.                             if(menu_1 >= 2)
  211.                             {
  212.                                           menu_1 = 0;
  213.                             }
  214.                             if(menu_1 == 0)
  215.                             {
  216.                                           menu_shudu = 20;
  217.                                           dis_smg[0] = smg_du[distance % 10];            
  218.                                           dis_smg[1] = smg_du[distance / 10 % 10] ;
  219.                                           dis_smg[2] = smg_du[distance / 100 % 10] & 0x7f;               
  220.                                           smg_i = 3;
  221.                             }
  222.                             if(menu_1 == 1)
  223.                             {
  224.                                           menu_shudu = 1;
  225.                                           dis_smg[0] = smg_du[set_d % 10];                        
  226.                                           dis_smg[1] = smg_du[set_d / 10 % 10];
  227.                                           dis_smg[2] = smg_du[set_d / 100 % 10] & 0x7f ;               
  228.                                           dis_smg[3] = 0x88;            
  229.                                           smg_i = 4;
  230.                             }
  231.               }
  232.               if(menu_1 == 1)                                          //设置高温报警
  233.               {
  234.                             if(flag_lj_3_en == 0)  //三次连加之后速度加快
  235.                                           menu_shudu = 10 ;  //500ms               加减一次
  236.                             else
  237.                                           menu_shudu = 1;  //250ms 加减一次
  238.                             if(key_can == 2)
  239.                             {
  240.                                           set_d ++ ;                            //按键按下未松开自动加三次            
  241.                                           if(set_d > 350)
  242.                                                         set_d = 350;
  243.                                           dis_smg[0] = smg_du[set_d % 10];                         //取小数显示
  244.                                           dis_smg[1] = smg_du[set_d / 10 % 10] ;         //取个位显示
  245.                                           dis_smg[2] = smg_du[set_d / 100 % 10] & 0x7f;  //取十位显示
  246.                                           dis_smg[3] = 0x88;              //a
  247.                             }
  248.                             if(key_can == 3)
  249.                             {
  250.                                           set_d -- ;                            //按键按下未松开自动加三次            
  251.                                           if(set_d <= 1)
  252.                                                         set_d = 1;
  253.                                           dis_smg[0] = smg_du[set_d % 10];                         //取小数显示
  254.                                           dis_smg[1] = smg_du[set_d / 10 % 10] ;  //取个位显示
  255.                                           dis_smg[2] = smg_du[set_d / 100 % 10] & 0x7f ;                 //取十位显示
  256.                                           dis_smg[3] = 0x88;              //a
  257.                             }
  258. //                            write_eepom();
  259.               }            
  260. } </div><div>/****************报警函数***************/
  261. void clock_h_l()
  262. {
  263.               static uchar value;
  264.               if(distance <= set_d)
  265.               {
  266.                             value ++;  //消除实际距离在设定距离左右变化时的干扰
  267.                             if(value >= 5)
  268.                             {
  269.                                           beep = ~beep;                 //蜂鸣器报警                                         
  270.                             }
  271.               }
  272.               else
  273.               {
  274.                             value = 0;
  275.                             beep = 1;                            //取消报警
  276.               }            
  277. }</div><div>/****************按键按下蜂鸣器响下**********************/               
  278. void key_beep()
  279. {
  280.               static uint value;            
  281.               if((flag_key_b_en == 1) && (flag_key_set_en == 1))
  282.               {
  283.                             beep = 0;    //打开蜂鸣器               
  284.                             value ++;
  285.                             if(value > 800)
  286.                             {
  287.                                           value = 0;
  288.                                           flag_key_b_en = 0;
  289.                                           beep = 1;//关闭蜂鸣器
  290.                             }
  291.               }            
  292. }</div><div>
  293. void main()
  294. {
  295.               send_wave();              //测距离函数
  296.               smg_display();              //处理距离显示函数
  297.               time_init();
  298.               init_eepom();  //读eepom数据
  299.               while(1)
  300.               {
  301.                             if(flag_300ms == 1)
  302.                             {
  303.                                           flag_300ms = 0;
  304.                                           clock_h_l();    //报警函数
  305.                                           send_wave();              //测距离函数
  306.                                           if(menu_1 == 0)
  307.                                                         smg_display();              //处理距离显示函数
  308.                                           if(zd_break_en == 1)              //自动退出设置界面程序
  309.                                           {
  310.                                                         zd_break_value ++;  //每300ms加一次
  311.                                                         if(zd_break_value > 100)   //30秒后自动退出设置界面
  312.                                                         {
  313.                                                                       menu_1 = 0;                                            //
  314.                                                                       smg_i = 3;
  315.                                                                       zd_break_en = 0;
  316.                                                                       zd_break_value = 0;
  317.                                                         }                           
  318.                                           }
  319.                             }
  320.                             key();                                                                      //按键函数
  321.                             if(key_can < 10)
  322.                             {
  323.                                           key_with();                                          //按键处理函数
  324.                             }
  325.               }
  326. }</div><div>
  327. /*********************定时器0中断服务程序 用做超声波测距的************************/
  328. void time0_int() interrupt 1
  329. {                                                                                      
  330.               set_d ++;                            //              TH0 TL0 到65536后溢出中断
  331. }                             </div><div>/*********************定时器0中断服务程序************************/
  332. void time1_int() interrupt 3
  333. {            
  334.               static uchar value;                                          //定时10ms中断一次
  335.               TH1 = 0xf8;
  336.               TL1 = 0x30;     //2ms
  337.               display();                            //数码管显示函数
  338.               value++;
  339.               if(value >= 150)
  340.               {
  341.                             value = 0;
  342.                             flag_300ms = 1;
  343.               }
  344.               if(value % 25 == 0)
  345.               {
  346.                             if(flag_lj_en == 1)                 //按下按键使能  50ms
  347.                             {
  348.                                           key_time ++;
  349.                                           if(key_time >= menu_shudu) //500ms
  350.                                           {
  351.                                                         key_time = 0;
  352.                                                         key_500ms = 1; //500ms
  353.                                                         flag_value ++;
  354.                                                         if(flag_value >= 3)
  355.                                                         {
  356.                                                                       flag_value = 10;
  357.                                                                       flag_lj_3_en = 1; //3次后1.5秒后连加大些
  358.                                                         }                                                                                   
  359.                                           }
  360.                             }
  361.               }
  362. }
复制代码


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

使用道具 举报

沙发
ID:584814 发表于 2020-5-20 10:47 | 只看该作者
第一位显示 0 就可以,想这个东东测 1 公里以上的距离还是求世界和平更现实。
回复

使用道具 举报

板凳
ID:282850 发表于 2020-5-20 14:42 | 只看该作者
看到long distance; 按你方法显示4位是可以的。但是这个3元的模块精度没那么牛,距离没那么远。
回复

使用道具 举报

地板
ID:756037 发表于 2020-5-20 23:07 | 只看该作者
man1234567 发表于 2020-5-20 10:47
第一位显示 0 就可以,想这个东东测 1 公里以上的距离还是求世界和平更现实。

哈哈,没有,我只是想到毫米
回复

使用道具 举报

5#
ID:756037 发表于 2020-5-20 23:15 | 只看该作者
f556 发表于 2020-5-20 14:42
看到long distance; 按你方法显示4位是可以的。但是这个3元的模块精度没那么牛,距离没那么远。

我看这个模块说可以达到0.3mm,所以想试试能不能显示第四位,就相当于把之前的数值往前移一位。所以,如果只改那个计算的地方,知道能不能实现。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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