找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机手持式超声测距仪设计(TFT彩屏+US-100源码)

[复制链接]
跳转到指定楼层
楼主
      学校举行的设计大赛已经结束,虽然在这次比赛中并没有获得比较好的成绩,但总算是基本完成了设计的样品,在这里想分享下我的设计过程,希望能对一些人有所帮助,也希望能学到更多东西。
      首先是这次设计的主题,设计的是手持式超声测距仪,用到的主要硬件有51单片机、1.44寸的TFT彩屏、蜂鸣器、US-100超声波头。然后想法是想把测到的距离通过彩屏来显示。
实物部分:

代码部分:
      第一部分是启用超声波头的函数:


这里的之所以要这么多个_nop_();是因为US-100超声波头发射超声波时,Trig管脚需要接收到一个10us以上的高电平才会发射超声波,这里一个_nop_();延迟1us。
     第二部分则是对返回来的数据进行处理:


代码里面的注释写的比较清楚,这里就不详细讲。这里提一下我写的代码这个是显示两位小数,单位是M,根据超声波头的精度,是可以写到3位小数,根据资料,误差是在0.003m左右,然后这里是不用对温度进行处理,因为这个超声波头里面就自带温度检测,测出来的时间已经修正了,是按照波速340m/s来算的。
       第三部分就是TFT彩屏的初始化、写数据、写命令、读数据等函数,这里就不介绍了。
       第四部分就是TFT彩屏上显示文字和字符的函数,文字通过字模转化来显示,这里采用16*16的点阵,而字符是通过ASCII码的顺序来显示,是8*16点阵,这里显示文字和字符分开用了两种方法,详细说明在代码注释中有。
       第五部分就是加了蜂鸣器,这部分的代码也比较简单,只是让蜂鸣器在测量完成时响一声提示测距完成,所以这里也不做过多介绍。
       最后给大家提供改进的几个思路,可以考虑增加蓝牙测距的模式,通过手机打开蓝牙,写一个APP,在手机这个APP上控制测距并将数据返回到手机中,这个想法是在比赛中见到的,当然也还有很多很好的想法(这就是在比赛中被完爆的原因),像外壳加了磁体等吸附装置可以吸附在任意位置测距,超声波头装在舵机上可以旋转等,这里就不一一举出了。有问题或建议的可以提出来交流,最后希望我整理的这些能对大家有所帮助。

单片机源程序:
  1. #include<reg51.h>
  2. #include<absacc.h>
  3. #include<intrins.h>
  4. #include<string.h>
  5. #include<tft.h>

  6. sbit Trig = P3^1;        //定义超声波引脚
  7. sbit Echo = P3^0;
  8.                                  
  9. unsigned int  time=0;
  10. unsigned long S=0;
  11. bit      flag =0;
  12. unsigned char disbuff[4]           ={ 0,0,0,0,};


  13. void fengmingqi()                //蜂鸣器加启用超声波函数
  14. {                        
  15.        u8 i,j=100;
  16.            while(j)         
  17.            {
  18.            for (i=0;i<80;i++)
  19.            {
  20.               beep=1;
  21.                   delay(1);
  22.                   beep=0;
  23.                   delay(1);
  24.            }
  25.                 for (i=0;i<100;i++)
  26.            {
  27.               beep=1;
  28.                   delay(2);
  29.                   beep=0;
  30.                   delay(2);
  31.            }
  32.            j--;
  33.            }
  34.                 StartModule();
  35.              while(!Echo);               
  36.              TR0=1;                           
  37.              while(Echo);               
  38.              TR0=0;                                
  39.          Conut();

  40.            while(1){         //让蜂鸣器响一下
  41.            beep=1;
  42.            }
  43.                
  44. }


  45. void Conut(void)                                         //计算距离
  46.         {                                                                 //通过计时器计算,计时器的单位是1us,所以下面S是=(time*340)/2/10000(单位是cm)
  47.          time=TH0*256+TL0;
  48.          TH0=0;
  49.          TL0=0;
  50.          S=(time*1.7)/100;     //算出来是CM
  51.          if((S>=450)||(S<2)||flag==1) //超出测量范围显示“-”
  52.          {         
  53.           flag=0;
  54.          
  55.           Fast_DrawFont_GBK16(40,70,RED,WHITE,"超出范围");
  56.          }
  57.          else
  58.          {

  59.           disbuff[0]=S%1000/100;
  60.           disbuff[1]=S%1000%100/10;
  61.           disbuff[2]=S%1000%10 %10;                                                         //这里可以通过fmod函数计算第三位小数,然后自行添加就好
  62.           switch (disbuff[0])                                                                 //通过switch给出数值
  63.           {
  64.               case (0):        Display_ASCII8X16(40, 70,"0"); break;
  65.                   case (1):        Display_ASCII8X16(40, 70,"1"); break;
  66.                   case (2):        Display_ASCII8X16(40, 70,"2"); break;
  67.                   case (3):        Display_ASCII8X16(40, 70,"3"); break;
  68.                   case (4):        Display_ASCII8X16(40, 70,"4"); break;
  69.           };
  70.           Display_ASCII8X16(50, 70,".");
  71.           switch (disbuff[1])
  72.           {
  73.               case (0):        Display_ASCII8X16(60, 70,"0"); break;
  74.                   case (1):        Display_ASCII8X16(60, 70,"1"); break;
  75.                   case (2):        Display_ASCII8X16(60, 70,"2"); break;
  76.                   case (3):        Display_ASCII8X16(60, 70,"3"); break;
  77.                   case (4):        Display_ASCII8X16(60, 70,"4"); break;
  78.                   case (5):        Display_ASCII8X16(60, 70,"5"); break;
  79.                   case (6):        Display_ASCII8X16(60, 70,"6"); break;
  80.                   case (7):        Display_ASCII8X16(60, 70,"7"); break;
  81.                   case (8):        Display_ASCII8X16(60, 70,"8"); break;
  82.                   case (9):        Display_ASCII8X16(60, 70,"9"); break;
  83.           };
  84.           switch (disbuff[2])
  85.           {
  86.               case (0):        Display_ASCII8X16(70, 70,"0"); break;
  87.                   case (1):        Display_ASCII8X16(70, 70,"1"); break;
  88.                   case (2):        Display_ASCII8X16(70, 70,"2"); break;
  89.                   case (3):        Display_ASCII8X16(70, 70,"3"); break;
  90.                   case (4):        Display_ASCII8X16(70, 70,"4"); break;
  91.                   case (5):        Display_ASCII8X16(70, 70,"5"); break;
  92.                   case (6):        Display_ASCII8X16(70, 70,"6"); break;
  93.                   case (7):        Display_ASCII8X16(70, 70,"7"); break;
  94.                   case (8):        Display_ASCII8X16(70, 70,"8"); break;
  95.                   case (9):        Display_ASCII8X16(70, 70,"9"); break;
  96.           };
  97.            Display_ASCII8X16(80, 70,"M");

  98.          }
  99.         }

  100. void zd0() interrupt 1                  //T0中断用来计数器溢出,超过测距范围
  101.   {
  102.     flag=1;                                                         //中断溢出标志
  103.   }

  104. void  StartModule()                          //启动模块
  105.   {
  106.           Trig=1;                                             //启动一次模块
  107.           _nop_();
  108.           _nop_();
  109.           _nop_();
  110.           _nop_();
  111.           _nop_();
  112.           _nop_();
  113.           _nop_();
  114.           _nop_();
  115.           _nop_();
  116.           _nop_();
  117.           _nop_();
  118.           _nop_();
  119.           _nop_();
  120.           _nop_();
  121.           _nop_();
  122.           _nop_();
  123.           _nop_();
  124.           _nop_();
  125.           _nop_();
  126.           _nop_();
  127.           _nop_();
  128.           Trig=0;
  129.   }





  130. void Font_Test(void)                //显示文字
  131. {
  132.         LCD_Clear(WHITE);
  133.         Fast_DrawFont_GBK16(24,20,BLACK,WHITE,        "洞穴测距仪");
  134.         delay(1000);        
  135. }



  136. void main()                           //主函数
  137. {
  138. #ifdef MCU_STC12
  139.         P3M1 &= ~(1<<2),        P3M0 |=  (1<<2);        //P3.2 set as push-pull output mode
  140. #endif
  141.            lcd_initial();
  142.            LCD_Clear(WHITE);
  143.            bl=1;
  144.        TMOD=0x01;                  
  145.            TH0=0;
  146.            TL0=0;         
  147.            ET0=1;            
  148.            EA=1;                                   
  149.            Font_Test();
  150.            daoshu3s();
  151.            fengmingqi();
  152. }

  153. uchar code Zk_ASCII8X16[]=
  154. {
  155.   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,// .
  156.   0x00,0x00,0x00,0x02,0x06,0x0c,0x18,0x30,0x60,0xc0,0x80,0x00,0x00,0x00,0x00,0x00,// /
  157. ……………………

  158. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码




全部资料51hei下载地址:
手持式超声测距仪.zip (678.51 KB, 下载次数: 28)


评分

参与人数 1黑币 +100 收起 理由
admin + 100 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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