找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 4550|回復(fù): 4
打印 上一主題 下一主題
收起左側(cè)

51單片機(jī)超聲波液位儀Proteus仿真原理圖程序PCB文件 帶溫度補(bǔ)償

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
全套51單片機(jī)超聲波液位儀資料,含程序、仿真、PCB文件,做出來(lái)的實(shí)物能實(shí)現(xiàn)功能。利用超聲波測(cè)液位,用LCD1602現(xiàn)實(shí),帶溫度補(bǔ)償,帶報(bào)警指示。PCB蜂鳴器處忘加驅(qū)動(dòng),電流不夠,聲音不夠大,可換成燈。
初始零液位距離為15CM,報(bào)警液位為低于5CM,低于5CM時(shí)大燈點(diǎn)亮。
如需要校準(zhǔn)改變零液位:
點(diǎn)擊設(shè)置,設(shè)置指示燈亮起
點(diǎn)擊液位歸零
再次點(diǎn)擊設(shè)置,指示燈熄滅,開始正常工作。
如需改變報(bào)警液位:
點(diǎn)擊設(shè)置
點(diǎn)擊加或者減
換位可以改變按加減時(shí)改變個(gè)位還是十分位的值,默認(rèn)為十分位。
仿真說(shuō)明:
仿真需要先校準(zhǔn)歸零。
如第一次仿真失敗,方法如下:
停止仿真;
雙擊MCU,出現(xiàn)對(duì)話框;
點(diǎn)擊program file欄目后的文件夾圖標(biāo),出現(xiàn)文件選擇框;
選擇chengxu--output--雙擊HC-SR04.hex
點(diǎn)擊確定

仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)


Altium Designer畫的原理圖和PCB圖如下:(51hei附件中可下載工程文件)


單片機(jī)源程序如下:
  1. #include "config.h"
  2. #include "Lcd1602.h"
  3. #include "Ultrasonic.h"
  4. #include <reg52.h>

  5. uint8 flag;   //定義定時(shí)標(biāo)志
  6. uint16 set_s;  //設(shè)定值
  7. uint16 lv_0;   //零位
  8. uint16 length;
  9. uint16 lv_n;

  10. bit flag1s = 0;          //1s定時(shí)標(biāo)志
  11. bit fusu = 0;          //1s定時(shí)標(biāo)志
  12. bit setflag= 0;          //進(jìn)入設(shè)置模式標(biāo)志
  13. bit changewei=0;
  14. unsigned char T0RH = 0;  //T0重載值的高字節(jié)
  15. unsigned char T0RL = 0;  //T0重載值的低字節(jié)
  16. //
  17. void ConfigTimer0(unsigned int ms);
  18. unsigned char IntToString(unsigned char *str, int dat);
  19. extern bit Start18B20();
  20. extern bit Get18B20Temp(int *temp);

  21. sbit led=P2^0;
  22. sbit bz=P1^5;
  23. sbit k3=P1^7;         //更換十位和百位
  24. sbit k1=P3^0;         //加
  25. sbit k2=P3^1;         //減
  26. sbit k4=P1^6;         //設(shè)置零位
  27. void ShowDistance();
  28. void ShowSets();
  29. void delayms(unsigned int ms);

  30. /* 主函數(shù) */
  31. void main()
  32. {        
  33.            bit res;
  34.                
  35.     int temp;        //讀取到的當(dāng)前溫度值
  36.     int intT, decT;  //溫度值的整數(shù)和小數(shù)部分
  37.     unsigned char len;
  38.     unsigned char str[12];
  39.     set_s=50;//mm
  40.         lv_0=150;//mm
  41.     EA = 1;            //開啟總中斷
  42.     TMOD &= 0Xf0;
  43.     TMOD |= 0X01;      //設(shè)置T0為方式1
  44.     TH0 = 0xFC;        //為T0賦初值0xFC67,定時(shí)1ms
  45.     TL0 = 0x67;
  46.     ET0 = 1;           //使能T0中斷
  47.     TR0 = 1;           //啟動(dòng)T0
  48.         IT0=1;        //設(shè)置外部中斷0的觸發(fā)方式為下降沿
  49.         EX0=1;        //開啟外部中斷
  50.     InitUltrasonic();  //超聲波模塊初始化
  51.     InitLcd1602();     //1602初始化
  52.         Start18B20();      //啟動(dòng)DS18B20
  53.         LcdShowStr(0, 0,"SETD:");  //顯示距離單位
  54.         LcdShowStr(0, 1,"LV:");  //顯示距離單位
  55.         LcdShowStr(10, 1,"T:");  //顯示距離單位
  56.         k1=1;

  57.     while(1)
  58.     {
  59.         if(flag == 1)
  60.         {
  61.             flag = 0;
  62.                         ShowSets();
  63.             ShowDistance();
  64.                     if (1)  //每秒更新一次溫度
  65.         {
  66.             res = Get18B20Temp(&temp);  //讀取當(dāng)前溫度
  67.             if (res)                    //讀取成功時(shí),刷新當(dāng)前溫度顯示
  68.             {
  69.                 intT = temp >> 4;             //分離出溫度值整數(shù)部分
  70.                 decT = temp & 0xF;            //分離出溫度值小數(shù)部分
  71.                 len = IntToString(str, intT); //整數(shù)部分轉(zhuǎn)換為字符串
  72.                 str[len++] = '.';             //添加小數(shù)點(diǎn)
  73.                 decT = (decT*10) / 16;        //二進(jìn)制的小數(shù)部分轉(zhuǎn)換為1位十進(jìn)制位
  74.                 str[len++] = decT + '0';      //十進(jìn)制小數(shù)位再轉(zhuǎn)換為ASCII字符
  75.                 while (len < 6)               //用空格補(bǔ)齊到6個(gè)字符長(zhǎng)度
  76.                 {
  77.                     str[len++] = ' ';
  78.                 }
  79.                 str[len] = '\0';              //添加字符串結(jié)束符
  80.                 LcdShowStr(12, 1, str);        //顯示到液晶屏上
  81.             }
  82.             else                        //讀取失敗時(shí),提示錯(cuò)誤信息
  83.             {
  84.                 LcdShowStr(12, 1, "error!");
  85.             }
  86.             Start18B20();               //重新啟動(dòng)下一次轉(zhuǎn)換
  87.         }
  88.         }
  89.                 while(setflag){//按下設(shè)置鍵,進(jìn)入設(shè)置模式,循環(huán)直到再一次按下設(shè)置鍵

  90.                         if(k1==0)                  //檢測(cè)按鍵K1是否按下
  91.                                 {        
  92.                                         delayms(5);   //消除抖動(dòng) 一般大約10ms
  93.                                         if(k1==0)         //再次判斷按鍵是否按下
  94.                                         {  
  95.                                                 if(changewei==0)set_s++;
  96.                                                 else set_s+=10;
  97.                                         }
  98.                                         while(!k1);         //檢測(cè)按鍵是否松開
  99.                                 }
  100.                         if(k2==0)                  //檢測(cè)按鍵K1是否按下
  101.                                 {        
  102.                                         delayms(5);   //消除抖動(dòng) 一般大約10ms
  103.                                         if(k2==0)         //再次判斷按鍵是否按下
  104.                                         {
  105.                                                 if(changewei==0)set_s--;
  106.                                                         else set_s-=10;
  107.                                         }
  108.                                         while(!k2);         //檢測(cè)按鍵是否松開
  109.                                 }
  110.                         if(k3==0)                  //檢測(cè)按鍵K1是否按下
  111.                                 {        
  112.                                         delayms(5);   //消除抖動(dòng) 一般大約10ms
  113.                                         if(k3==0)         //再次判斷按鍵是否按下
  114.                                         {
  115.                                                 changewei=~changewei;
  116.                                         }
  117.                                         while(!k3);         //檢測(cè)按鍵是否松開
  118.                                 }
  119.                         if(k4==0)                  //檢測(cè)按鍵K1是否按下
  120.                                 {        
  121.                                         delayms(5);   //消除抖動(dòng) 一般大約10ms
  122.                                         if(k4==0)         //再次判斷按鍵是否按下
  123.                                         {
  124.                                          lv_0=length;
  125.                                         }
  126.                                         while(!k4);         //檢測(cè)按鍵是否松開
  127.                                 }
  128.                                 ShowSets();
  129.                 }
  130.                 if(lv_n>set_s) bz=1;
  131.                 else bz=0;
  132.     }
  133. }
  134. unsigned char IntToString(unsigned char *str, int dat)
  135. {
  136.     signed char i = 0;
  137.     unsigned char len = 0;
  138.     unsigned char buf[6];
  139.    
  140.     if (dat < 0)  //如果為負(fù)數(shù),首先取絕對(duì)值,并在指針上添加負(fù)號(hào)
  141.     {
  142.         dat = -dat;
  143.         *str++ = '-';
  144.         len++;
  145.     }
  146.     do {          //先轉(zhuǎn)換為低位在前的十進(jìn)制數(shù)組
  147.         buf[i++] = dat % 10;
  148.         dat /= 10;
  149.     } while (dat > 0);
  150.     len += i;     //i最后的值就是有效字符的個(gè)數(shù)
  151.     while (i-- > 0)   //將數(shù)組值轉(zhuǎn)換為ASCII碼反向拷貝到接收指針上
  152.     {
  153.         *str++ = buf[i] + '0';
  154.     }
  155.     *str = '\0';  //添加字符串結(jié)束符
  156.    
  157.     return len;   //返回字符串長(zhǎng)度
  158. }




  159. /* 執(zhí)行測(cè)距并顯示結(jié)果 */
  160. void ShowDistance()
  161. {   
  162.     uint8 i;
  163.     uint8 buff[4];
  164.         uint8 buff2[5];
  165.     uint16 Distance ;   //暫存距離值
  166.     Distance = GetDistance();
  167.         length = Distance;//mm
  168.         if (Distance < lv_0)
  169.                 {
  170.                 Distance = lv_0-Distance;
  171.                 lv_n= Distance;
  172.                 fusu=0;
  173.                 }
  174.         else
  175.          {
  176.                  Distance =Distance- lv_0;
  177.                  lv_n=0;
  178.                  fusu=1;
  179.          }
  180.         if((Distance<999)&&(fusu==0)){
  181.             buff[3] = Distance%10 + '0';   //將數(shù)據(jù)轉(zhuǎn)換為字符形式
  182.             buff[2] ='.';
  183.             buff[1] = (Distance/10)%10 + '0';
  184.             buff[0] = (Distance/100)%10 + '0';
  185.             for(i = 0; i <= 0; i++)  //整數(shù)部分高位的0轉(zhuǎn)換為空白符
  186.             {
  187.                 if(buff[i] == '0')   //判斷是不是字符0
  188.                     buff[i] = ' ';   //將字符0 轉(zhuǎn)換為空格 即不顯示
  189.                 else
  190.                     break;
  191.             }
  192.             LcdShowStr(3, 1, &buff); //顯示距離值
  193.             LcdShowStr(7, 1, "cm");  //顯示距離單位
  194.         }
  195.                 if((Distance<99)&&(fusu==1)){
  196.             buff[3] =' ';   //將數(shù)據(jù)轉(zhuǎn)換為字符形式
  197.             buff[2] =Distance%10 + '0';
  198.             buff[1] ='.';
  199.             buff[0] = (Distance/10)%10 + '0';
  200. //            for(i = 0; i <= 0; i++)  //整數(shù)部分高位的0轉(zhuǎn)換為空白符
  201. //            {
  202. //                if(buff[i] == '0')   //判斷是不是字符0
  203. //                    buff[i] = ' ';   //將字符0 轉(zhuǎn)換為空格 即不顯示
  204. //                else
  205. //                    break;
  206. //            }
  207.                         LcdShowStr(3, 1, "-");  //顯示距離單位
  208.             LcdShowStr(4, 1, &buff); //顯示距離值
  209.             LcdShowStr(7, 1, "cm");  //顯示距離單位
  210.         }
  211.         if(Distance>999||((Distance>99)&&(fusu==1))){
  212.                 LcdShowStr(3, 1, "ERROR");  //顯示距離單位
  213. //            else {
  214. //                        buff2[4] = Distance%10 + '0';   //將數(shù)據(jù)轉(zhuǎn)換為字符形式
  215. //                    buff2[3] ='.';
  216. //                    buff2[2] = (Distance/10)%10 + '0';
  217. //                    buff2[1] = (Distance/100)%10 + '0';
  218. //                        buff2[0] = (Distance/1000)%10 + '0';
  219. //                    for(i = 0; i <= 3; i++)  //整數(shù)部分高位的0轉(zhuǎn)換為空白符
  220. //                    {
  221. //                        if(buff2[i] == '0')   //判斷是不是字符0
  222. //                            buff2[i] = ' ';   //將字符0 轉(zhuǎn)換為空格 即不顯示
  223. //                        else
  224. //                            break;
  225. //                    }
  226. //                    LcdShowStr(3, 1, &buff2); //顯示距離值
  227. //                    LcdShowStr(8, 1, "cm");  //顯示距離單位
  228.         //        }
  229.         }
  230. }
  231. void ShowSets()
  232. {   
  233.     uint8 i;
  234.     uint8 buff[4];

  235.         if(set_s>999)set_s=999;
  236.     buff[3] = set_s%10 + '0';   //將數(shù)據(jù)轉(zhuǎn)換為字符形式
  237.     buff[2] ='.';
  238.     buff[1] = (set_s/10)%10 + '0';
  239.     buff[0] = (set_s/100)%10 + '0';
  240.     for(i = 0; i <= 3; i++)  //整數(shù)部分高位的0轉(zhuǎn)換為空白符
  241.     {
  242.         if(buff[i] == '0')   //判斷是不是字符0
  243.             buff[i] = ' ';   //將字符0 轉(zhuǎn)換為空格 即不顯示
  244.         else
  245.             break;
  246.     }
  247.     LcdShowStr(6, 0, &buff); //顯示距離值
  248.     LcdShowStr(10, 0, "cm");  //顯示距離單位
  249. }

  250. /* 定時(shí)器0中斷服務(wù)函數(shù) */
  251. ……………………

  252. …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼

所有資料51hei附件下載:
超聲波液位儀.7z (131.92 KB, 下載次數(shù): 131)

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏4 分享淘帖 頂1 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:328014 發(fā)表于 2021-8-7 16:18 | 只看該作者
好資料,51黑有你更精彩!!!
回復(fù)

使用道具 舉報(bào)

板凳
ID:66328 發(fā)表于 2021-8-9 13:11 | 只看該作者
大神牛啊,那個(gè)超聲波的仿真模塊在哪里下的
回復(fù)

使用道具 舉報(bào)

地板
ID:1076417 發(fā)表于 2023-5-9 19:30 | 只看該作者
hnqylgq 發(fā)表于 2021-8-9 13:11
大神牛啊,那個(gè)超聲波的仿真模塊在哪里下的

Proteus8.9里面自帶
回復(fù)

使用道具 舉報(bào)

5#
ID:1113285 發(fā)表于 2024-3-20 14:50 | 只看該作者
好資料,加個(gè)電機(jī)驅(qū)動(dòng)就完美了
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表