找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2005|回复: 0
收起左侧

带温度补偿的超声波单片机控制程序

[复制链接]
ID:321563 发表于 2019-5-10 12:26 | 显示全部楼层 |阅读模式
单片机控制超声波电路原理图如下:
QQ截图20190510122343.jpg QQ截图20190510122410.jpg

单片机源程序如下:
  1. #include <reg52.H>                //器件配置文件
  2. #include <intrins.h>
  3. #include "ds18b20.h"
  4. sbit  RX = P1^5;
  5. sbit  TX = P1^4;
  6. sbit  BEEP = P3^4;
  7. sbit LCM_RW = P3^6; //定义LCD引脚
  8. sbit LCM_RS = P3^7;
  9. sbit LCM_E  = P3^5;
  10. #define LCM_Data P2


  11. #define Busy    0x80 //用于检测LCM状态字中的Busy标识

  12. void LCMInit(void);
  13. void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
  14. void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);
  15. void Delay5Ms(void);
  16. void Delay400Ms(void);
  17. void Decode(unsigned char ScanCode);
  18. void WriteDataLCM(unsigned char WDLCM);
  19. void WriteCommandLCM(unsigned char WCLCM,BuysC);

  20. unsigned char ReadDataLCM(void);
  21. unsigned char ReadStatusLCM(void);

  22. unsigned char code Cls[] =      {"                "};
  23. unsigned char code ASCII[16] =    {'0','1','2','3','4','5','6','7','8','9','.','-','M','C',' '};

  24. static unsigned char DisNum = 0; //显示用指针                                  
  25.        unsigned int  time=0;
  26.            unsigned long S=0;
  27.            bit      flag =0;
  28.            unsigned char disbuff[4]           ={ 0,0,0,0,};


  29. //写数据
  30. void WriteDataLCM(unsigned char WDLCM)
  31. {
  32.         ReadStatusLCM(); //检测忙
  33.         LCM_Data = WDLCM;
  34.         LCM_RS = 1;
  35.         LCM_RW = 0;
  36.         LCM_E = 0; //若晶振速度太高可以在这后加小的延时
  37.         LCM_E = 0; //延时
  38.         LCM_E = 1;
  39. }

  40. //写指令
  41. void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测
  42. {
  43.         if (BuysC) ReadStatusLCM(); //根据需要检测忙
  44.         LCM_Data = WCLCM;
  45.         LCM_RS = 0;
  46.         LCM_RW = 0;       
  47.         LCM_E = 0;
  48.         LCM_E = 0;
  49.         LCM_E = 1;       
  50. }

  51. //读数据
  52. unsigned char ReadDataLCM(void)
  53. {
  54.         LCM_RS = 1;
  55.         LCM_RW = 1;
  56.         LCM_E = 0;
  57.         LCM_E = 0;
  58.         LCM_E = 1;
  59.         return(LCM_Data);
  60. }

  61. //读状态
  62. unsigned char ReadStatusLCM(void)
  63. {
  64.         LCM_Data = 0xFF;
  65.         LCM_RS = 0;
  66.         LCM_RW = 1;
  67.         LCM_E = 0;
  68.         LCM_E = 0;
  69.         LCM_E = 1;
  70.         while (LCM_Data & Busy); //检测忙信号
  71.         return(LCM_Data);
  72. }

  73. void LCMInit(void) //LCM初始化
  74. {
  75.         LCM_Data = 0;
  76.         WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
  77.         Delay5Ms();
  78.         WriteCommandLCM(0x38,0);
  79.         Delay5Ms();
  80.         WriteCommandLCM(0x38,0);
  81.         Delay5Ms();

  82.         WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
  83.         WriteCommandLCM(0x08,1); //关闭显示
  84.         WriteCommandLCM(0x01,1); //显示清屏
  85.         WriteCommandLCM(0x06,1); // 显示光标移动设置
  86.         WriteCommandLCM(0x0F,1); // 显示开及光标设置
  87. }

  88. //按指定位置显示一个字符
  89. void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
  90. {
  91.         Y &= 0x1;
  92.         X &= 0xF; //限制X不能大于15,Y不能大于1
  93.         if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
  94.         X |= 0x80; //算出指令码
  95.         WriteCommandLCM(X, 1); //发命令字
  96.         WriteDataLCM(DData); //发数据
  97. }

  98. //按指定位置显示一串字符
  99. void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
  100. {
  101.         unsigned char ListLength;

  102.   ListLength = 0;
  103.         Y &= 0x1;
  104.         X &= 0xF; //限制X不能大于15,Y不能大于1
  105.         while (DData[ListLength]>0x19) //若到达字串尾则退出
  106.                 {
  107.                         if (X <= 0xF) //X坐标应小于0xF
  108.                                 {
  109.                                         DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
  110.                                         ListLength++;
  111.                                         X++;
  112.                                 }
  113.                 }
  114. }

  115. //5ms延时
  116. void Delay5Ms(void)
  117. {
  118.         unsigned int TempCyc = 5552;
  119.         while(TempCyc--);
  120. }

  121. //400ms延时
  122. void Delay400Ms(void)
  123. {
  124.         unsigned char TempCycA = 5;
  125.         unsigned int TempCycB;
  126.         while(TempCycA--)
  127.                 {
  128.                         TempCycB=7269;
  129.                         while(TempCycB--);
  130.                 };
  131. }
  132. /********************************************************/
  133.     void Conut(void)
  134.         {
  135.                 int TEMP;
  136.          time=TH0*256+TL0;
  137.          TH0=0;
  138.          TL0=0;
  139.          TEMP=ReadTemperature();
  140.          S=(time/2.0*(331.45+0.61*TEMP/10))/1000.0;     //算出来是MM
  141.          if((S>=7000)||flag==1) //超出测量范围显示“-”
  142.          {         
  143.           flag=0;
  144.          
  145.           DisplayOneChar(0, 0, ASCII[11]);
  146.           DisplayOneChar(1, 0, ASCII[10]);        //显示点
  147.           DisplayOneChar(2, 0, ASCII[11]);
  148.           DisplayOneChar(3, 0, ASCII[11]);
  149.           DisplayOneChar(4, 0, ASCII[11]);
  150.           DisplayOneChar(5, 0, ASCII[12]);        //显示M
  151.          }
  152.          else
  153.          {
  154.                  if(S<1000)
  155.                          BEEP=1;
  156.                  else
  157.                         BEEP=0;
  158.                
  159.           disbuff[0]=S/1000;
  160.           disbuff[1]=S/100%10;
  161.           disbuff[2]=S/10%10;
  162.           disbuff[3]=S%10;
  163.           DisplayOneChar(0, 0, ASCII[disbuff[0]]);
  164.           DisplayOneChar(1, 0, ASCII[10]);        //显示点
  165.           DisplayOneChar(2, 0, ASCII[disbuff[1]]);
  166.           DisplayOneChar(3, 0, ASCII[disbuff[2]]);
  167.           DisplayOneChar(4, 0, ASCII[disbuff[3]]);
  168.           DisplayOneChar(5, 0, ASCII[12]);        //显示M
  169.                  
  170.       DisplayOneChar(6, 0, ASCII[14]);
  171.       DisplayOneChar(7, 0, ASCII[TEMP/100]);
  172.       DisplayOneChar(8, 0, ASCII[(TEMP/10)%10]);
  173.       DisplayOneChar(9, 0, ASCII[10]);
  174.       DisplayOneChar(10, 0, ASCII[TEMP%10]);
  175.       DisplayOneChar(11, 0, ASCII[13]);                 
  176.          }
  177.          
  178.          
  179.         }
  180. /********************************************************/
  181.      void zd0() interrupt 1                  //T0中断用来计数器溢出,超过测距范围
  182.   {
  183.     flag=1;                                                         //中断溢出标志
  184.         RX=0;
  185.   }
  186. /********************************************************/
  187.      void  StartModule()                          //启动模块
  188.   {
  189.           TX=1;                                             //启动一次模块
  190.           _nop_();
  191.           _nop_();
  192.           _nop_();
  193.           _nop_();
  194.           _nop_();
  195.           _nop_();
  196.           _nop_();
  197.           _nop_();
  198.           _nop_();
  199.           _nop_();
  200.           _nop_();
  201.           _nop_();
  202.           _nop_();
  203.           _nop_();
  204.           _nop_();
  205.           _nop_();
  206.           _nop_();
  207.           _nop_();
  208.           _nop_();
  209.           _nop_();
  210.           _nop_();
  211.           TX=0;
  212.   }
  213. void Timer_Count(void)
  214. {
  215.                  TR0=1;                            //开启计数
  216.              while(RX);                        //当RX为1计数并等待
  217.              TR0=0;                                //关闭计数
  218.          Conut();                        //计算

  219. }

  220. /********************************************************/
  221. void delayms(unsigned int ms)
  222. {
  223.         unsigned char i=100,j;
  224.         for(;ms;ms--)
  225.         {
  226.                 while(--i)
  227.                 {
  228.                         j=10;
  229.                         while(--j);
  230.                 }
  231.         }
  232. }
  233. /*********************************************************/
  234. void main(void)
  235. {
  236.     unsigned int valA;
  237.         //unsigned char TempCyc;
  238.         BEEP=0;
  239.         Delay400Ms(); //启动等待,等LCM讲入工作状态
  240.         LCMInit(); //LCM初始化
  241.         Delay5Ms(); //延时片刻(可不要)
  242.         ReadDataLCM();//测试用句无意义
  243.         DisplayListChar(0, 1, Cls);       
  244.          TMOD=0x01;                   //设T0为方式1,GATE=1;
  245.          TH0=0;
  246.          TL0=0;         
  247.          ET0=1;             //允许T0中断
  248.          EA=1;                           //开启总中断                       
  249.        
  250.         while(1)
  251.           {
  252.                 delayms(60);
  253.                 RX=1;
  254.             StartModule();
  255.         for(valA=7510;valA>0;valA--)
  256.             {
  257.                if(RX==1)
  258.                    {
  259.            Timer_Count();
  260.                    }
  261.              }
  262.           }
  263. }
复制代码

所有资料51hei提供下载:
超声波_LCD_51_温度补偿.7z (2.64 MB, 下载次数: 22)

评分

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

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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