全套51單片機超聲波液位儀資料,含程序、仿真、PCB文件,做出來的實物能實現功能。利用超聲波測液位,用LCD1602現實,帶溫度補償,帶報警指示。PCB蜂鳴器處忘加驅動,電流不夠,聲音不夠大,可換成燈。
初始零液位距離為15CM,報警液位為低于5CM,低于5CM時大燈點亮。
如需要校準改變零液位:
點擊設置,設置指示燈亮起
點擊液位歸零
再次點擊設置,指示燈熄滅,開始正常工作。
如需改變報警液位:
點擊設置
點擊加或者減
換位可以改變按加減時改變個位還是十分位的值,默認為十分位。
仿真說明:
仿真需要先校準歸零。
如第一次仿真失敗,方法如下:
停止仿真;
雙擊MCU,出現對話框;
點擊program file欄目后的文件夾圖標,出現文件選擇框;
選擇chengxu--output--雙擊HC-SR04.hex
點擊確定
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei.png (47.34 KB, 下載次數: 75)
下載附件
2021-8-7 15:05 上傳
Altium Designer畫的原理圖和PCB圖如下:(51hei附件中可下載工程文件)
51hei.png (19.98 KB, 下載次數: 77)
下載附件
2021-8-7 15:06 上傳
51hei.png (56.07 KB, 下載次數: 72)
下載附件
2021-8-7 15:07 上傳
單片機源程序如下:
- #include "config.h"
- #include "Lcd1602.h"
- #include "Ultrasonic.h"
- #include <reg52.h>
- uint8 flag; //定義定時標志
- uint16 set_s; //設定值
- uint16 lv_0; //零位
- uint16 length;
- uint16 lv_n;
- bit flag1s = 0; //1s定時標志
- bit fusu = 0; //1s定時標志
- bit setflag= 0; //進入設置模式標志
- bit changewei=0;
- unsigned char T0RH = 0; //T0重載值的高字節
- unsigned char T0RL = 0; //T0重載值的低字節
- //
- void ConfigTimer0(unsigned int ms);
- unsigned char IntToString(unsigned char *str, int dat);
- extern bit Start18B20();
- extern bit Get18B20Temp(int *temp);
- sbit led=P2^0;
- sbit bz=P1^5;
- sbit k3=P1^7; //更換十位和百位
- sbit k1=P3^0; //加
- sbit k2=P3^1; //減
- sbit k4=P1^6; //設置零位
- void ShowDistance();
- void ShowSets();
- void delayms(unsigned int ms);
- /* 主函數 */
- void main()
- {
- bit res;
-
- int temp; //讀取到的當前溫度值
- int intT, decT; //溫度值的整數和小數部分
- unsigned char len;
- unsigned char str[12];
- set_s=50;//mm
- lv_0=150;//mm
- EA = 1; //開啟總中斷
- TMOD &= 0Xf0;
- TMOD |= 0X01; //設置T0為方式1
- TH0 = 0xFC; //為T0賦初值0xFC67,定時1ms
- TL0 = 0x67;
- ET0 = 1; //使能T0中斷
- TR0 = 1; //啟動T0
- IT0=1; //設置外部中斷0的觸發方式為下降沿
- EX0=1; //開啟外部中斷
- InitUltrasonic(); //超聲波模塊初始化
- InitLcd1602(); //1602初始化
- Start18B20(); //啟動DS18B20
- LcdShowStr(0, 0,"SETD:"); //顯示距離單位
- LcdShowStr(0, 1,"LV:"); //顯示距離單位
- LcdShowStr(10, 1,"T:"); //顯示距離單位
- k1=1;
- while(1)
- {
- if(flag == 1)
- {
- flag = 0;
- ShowSets();
- ShowDistance();
- if (1) //每秒更新一次溫度
- {
- res = Get18B20Temp(&temp); //讀取當前溫度
- if (res) //讀取成功時,刷新當前溫度顯示
- {
- intT = temp >> 4; //分離出溫度值整數部分
- decT = temp & 0xF; //分離出溫度值小數部分
- len = IntToString(str, intT); //整數部分轉換為字符串
- str[len++] = '.'; //添加小數點
- decT = (decT*10) / 16; //二進制的小數部分轉換為1位十進制位
- str[len++] = decT + '0'; //十進制小數位再轉換為ASCII字符
- while (len < 6) //用空格補齊到6個字符長度
- {
- str[len++] = ' ';
- }
- str[len] = '\0'; //添加字符串結束符
- LcdShowStr(12, 1, str); //顯示到液晶屏上
- }
- else //讀取失敗時,提示錯誤信息
- {
- LcdShowStr(12, 1, "error!");
- }
- Start18B20(); //重新啟動下一次轉換
- }
- }
- while(setflag){//按下設置鍵,進入設置模式,循環直到再一次按下設置鍵
- if(k1==0) //檢測按鍵K1是否按下
- {
- delayms(5); //消除抖動 一般大約10ms
- if(k1==0) //再次判斷按鍵是否按下
- {
- if(changewei==0)set_s++;
- else set_s+=10;
- }
- while(!k1); //檢測按鍵是否松開
- }
- if(k2==0) //檢測按鍵K1是否按下
- {
- delayms(5); //消除抖動 一般大約10ms
- if(k2==0) //再次判斷按鍵是否按下
- {
- if(changewei==0)set_s--;
- else set_s-=10;
- }
- while(!k2); //檢測按鍵是否松開
- }
- if(k3==0) //檢測按鍵K1是否按下
- {
- delayms(5); //消除抖動 一般大約10ms
- if(k3==0) //再次判斷按鍵是否按下
- {
- changewei=~changewei;
- }
- while(!k3); //檢測按鍵是否松開
- }
- if(k4==0) //檢測按鍵K1是否按下
- {
- delayms(5); //消除抖動 一般大約10ms
- if(k4==0) //再次判斷按鍵是否按下
- {
- lv_0=length;
- }
- while(!k4); //檢測按鍵是否松開
- }
- ShowSets();
- }
- if(lv_n>set_s) bz=1;
- else bz=0;
- }
- }
- unsigned char IntToString(unsigned char *str, int dat)
- {
- signed char i = 0;
- unsigned char len = 0;
- unsigned char buf[6];
-
- if (dat < 0) //如果為負數,首先取絕對值,并在指針上添加負號
- {
- dat = -dat;
- *str++ = '-';
- len++;
- }
- do { //先轉換為低位在前的十進制數組
- buf[i++] = dat % 10;
- dat /= 10;
- } while (dat > 0);
- len += i; //i最后的值就是有效字符的個數
- while (i-- > 0) //將數組值轉換為ASCII碼反向拷貝到接收指針上
- {
- *str++ = buf[i] + '0';
- }
- *str = '\0'; //添加字符串結束符
-
- return len; //返回字符串長度
- }
- /* 執行測距并顯示結果 */
- void ShowDistance()
- {
- uint8 i;
- uint8 buff[4];
- uint8 buff2[5];
- uint16 Distance ; //暫存距離值
- Distance = GetDistance();
- length = Distance;//mm
- if (Distance < lv_0)
- {
- Distance = lv_0-Distance;
- lv_n= Distance;
- fusu=0;
- }
- else
- {
- Distance =Distance- lv_0;
- lv_n=0;
- fusu=1;
- }
- if((Distance<999)&&(fusu==0)){
- buff[3] = Distance%10 + '0'; //將數據轉換為字符形式
- buff[2] ='.';
- buff[1] = (Distance/10)%10 + '0';
- buff[0] = (Distance/100)%10 + '0';
- for(i = 0; i <= 0; i++) //整數部分高位的0轉換為空白符
- {
- if(buff[i] == '0') //判斷是不是字符0
- buff[i] = ' '; //將字符0 轉換為空格 即不顯示
- else
- break;
- }
- LcdShowStr(3, 1, &buff); //顯示距離值
- LcdShowStr(7, 1, "cm"); //顯示距離單位
- }
- if((Distance<99)&&(fusu==1)){
- buff[3] =' '; //將數據轉換為字符形式
- buff[2] =Distance%10 + '0';
- buff[1] ='.';
- buff[0] = (Distance/10)%10 + '0';
- // for(i = 0; i <= 0; i++) //整數部分高位的0轉換為空白符
- // {
- // if(buff[i] == '0') //判斷是不是字符0
- // buff[i] = ' '; //將字符0 轉換為空格 即不顯示
- // else
- // break;
- // }
- LcdShowStr(3, 1, "-"); //顯示距離單位
- LcdShowStr(4, 1, &buff); //顯示距離值
- LcdShowStr(7, 1, "cm"); //顯示距離單位
- }
- if(Distance>999||((Distance>99)&&(fusu==1))){
- LcdShowStr(3, 1, "ERROR"); //顯示距離單位
- // else {
- // buff2[4] = Distance%10 + '0'; //將數據轉換為字符形式
- // buff2[3] ='.';
- // buff2[2] = (Distance/10)%10 + '0';
- // buff2[1] = (Distance/100)%10 + '0';
- // buff2[0] = (Distance/1000)%10 + '0';
- // for(i = 0; i <= 3; i++) //整數部分高位的0轉換為空白符
- // {
- // if(buff2[i] == '0') //判斷是不是字符0
- // buff2[i] = ' '; //將字符0 轉換為空格 即不顯示
- // else
- // break;
- // }
- // LcdShowStr(3, 1, &buff2); //顯示距離值
- // LcdShowStr(8, 1, "cm"); //顯示距離單位
- // }
- }
- }
- void ShowSets()
- {
- uint8 i;
- uint8 buff[4];
- if(set_s>999)set_s=999;
- buff[3] = set_s%10 + '0'; //將數據轉換為字符形式
- buff[2] ='.';
- buff[1] = (set_s/10)%10 + '0';
- buff[0] = (set_s/100)%10 + '0';
- for(i = 0; i <= 3; i++) //整數部分高位的0轉換為空白符
- {
- if(buff[i] == '0') //判斷是不是字符0
- buff[i] = ' '; //將字符0 轉換為空格 即不顯示
- else
- break;
- }
- LcdShowStr(6, 0, &buff); //顯示距離值
- LcdShowStr(10, 0, "cm"); //顯示距離單位
- }
- /* 定時器0中斷服務函數 */
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
51hei.png (11.52 KB, 下載次數: 67)
下載附件
2021-8-7 15:19 上傳
所有資料51hei附件下載:
超聲波液位儀.7z
(131.92 KB, 下載次數: 131)
2021-8-7 15:20 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|