可以設定超聲波測距的報警范圍,顯示超聲波距離
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei.gif (175.41 KB, 下載次數: 43)
下載附件
2023-6-9 22:21 上傳
1686306919055.png (108.96 KB, 下載次數: 51)
下載附件
2023-6-9 18:35 上傳
797ff8e68af890891a871f23264c2ce.png (94.99 KB, 下載次數: 43)
下載附件
2023-6-9 18:33 上傳
單片機源程序如下:
- #include <REGX52.H>
- #include "LCD1602.h" //LCD1602頭文件
- #include "Delay.h" //延時
- #include "Timer0.h" //定時0頭文件
- #include "Timer1.h" //定時1頭文件
- //定義各種參數
- unsigned short Distance;
- unsigned char i;
- unsigned long DisH,DisL;
- unsigned int T0Count;
- unsigned char Time;
- unsigned int a,b;
- sbit Trig = P3^6; //定義兩個超聲波管腳
- sbit Echo = P3^7;
- sbit set = P3^0; //切換模式
- sbit up = P3^1; //加
- sbit down = P3^2; //減
- sbit yled = P2^1;
- sbit gled = P2^2;
- sbit rled = P2^3;
- sbit beep = P3^5;
- unsigned char Flag;//測量標志位0.5秒觸發一次
- unsigned char nodis;//超出量程
- unsigned int mode;
- unsigned int change;
- unsigned int waring;
- unsigned int upper = 120;//上限
- unsigned int lower = 50;//下限
- //超聲波初始化
- void Super_Wave_Init()
- {
- Trig = 0;
- Echo = 0;
- }
- //
- /**************************************************
- 距離測量
- **************************************************/
- void Measure(void)
- {
- unsigned char Err; //錯誤標記
- unsigned long distance,pTime;//距離,時間變量
- Err=0;
- Trig=1; //TR保持10us高電平觸發模塊測距
- Delay10Us();
- Trig=0;
- TH0=0;
- TL0=0;
- while(Echo==0);//等待ECHO變為高
- TR0=1; //啟動定時器,外部高電平觸發
- while(Echo==1)//等待超聲波回應獲超時
- {
- pTime=TH0*256+TL0;
- if(pTime>40000)//時間超時
- {
- Err=1;
- break;
- }
- }
- TR0=0;//關閉定時器
- pTime=TH0*256+TL0; //獲取時間
-
- if(Err==0)
- {
-
- distance=(pTime*173)/1000;//;pTime*346/1000000/2=pTime*0.0173 仿真的環境溫度為25度346m/s
- DisH = distance/10;
- DisL = distance%10;
-
- if((DisH>170)||(DisH<2))//量程170cm,超過量程顯示0;測量距離小?cm,HCSR04最小測算2cm
- {
- Err=1;
-
- }
- else if(DisH>upper)
- {
- gled = 0;
- yled = 1;
- rled = 1;
- beep = 1;
- }
- else if((DisH>=lower)&&(DisH<=upper))
- {
- gled = 1;
- yled = 0;
- rled = 1;
- if(waring == 0)
- {
- beep = 1;
- }
- else
- {
- beep = 0;
- }
- }
- else if(DisH<lower)
- {
-
- gled = 1;
- yled = 1;
- rled = 0;
- beep = 0;
- if(waring == 0)
- {
- LCD_ShowString(2,1,"warning");
- }
- else
- {
- LCD_ShowString(2,1," ");
- }
-
- }
-
-
- }
- if(Err == 1)
- {
- nodis = 1;
- gled = 1;
- yled = 1;
- rled = 1;
- beep = 1;
- }
- }
- void outkey()
- {
- if(set == 0)
- {
- //Delay(8);
- mode++;
- change = 1;
- if(mode>2)
- {
- mode = 0;
- }
- while(set == 0);
- }
- switch(mode)
- {
- case 0://正常讀數模式
- if(change == 1)
- {
- change = 0;
-
- LCD_ShowString(1,1,"distance:");
- LCD_ShowString(1,15,"cm");
- LCD_ShowString(1,13,".");
- LCD_ShowString(2,1," ");
- }
- if(Flag)//每500ms測量一次
- {
- Flag=0;
- Measure();//測量
- if(nodis == 0)
- {
- LCD_ShowNum(1,10,DisH,3);
- LCD_ShowNum(1,14,DisL,1);
- }
- else
- {
- nodis = 0;
- LCD_ShowString(1,10,"-");
- LCD_ShowString(1,11,"-");
- LCD_ShowString(1,12,"-");
- LCD_ShowString(1,14,"-");
- }
- }
- break;
- case 1://改下限
- if(change == 1)
- {
- change = 0;
- LCD_ShowString(2,1,"upper:");
- LCD_ShowNum(2,7,upper,3);
- LCD_ShowString(2,10," ");
- LCD_ShowString(1,1,"lower:");
- LCD_ShowNum(1,7,lower,3);
- LCD_ShowString(1,10," ");
-
- }
- if(up == 0)
- {
- lower++;
- LCD_ShowNum(1,7,lower,3);
- while(up == 0);
- }
- if(down == 0)
- {
- lower--;
- LCD_ShowNum(1,7,lower,3);
- while(down == 0);
- }
- break;
- case 2://改上限
- if(change == 1)
- {
- change = 0;
- LCD_ShowString(2,1,"upper:");
- LCD_ShowNum(2,7,upper,3);
- LCD_ShowString(2,10," ");
- LCD_ShowString(1,1,"lower:");
- LCD_ShowNum(1,7,lower,3);
- LCD_ShowString(1,10," ");
-
- }
- if(up == 0)
- {
- upper++;
- LCD_ShowNum(2,7,upper,3);
- while(up == 0);
- }
- if(down == 0)
- {
- upper--;
- LCD_ShowNum(2,7,upper,3);
- while(down == 0);
- }
- break;
- default:break;
-
- }
- }
- //主函數
- void main()
- {
- LCD_Init();
- Timer0Init(); //該定時器沒有寫TR0.
- Timer1Init();
- LCD_ShowString(1,1,"distance:");
- LCD_ShowString(1,15,"cm");
- LCD_ShowString(1,13,".");
- while(1)
- {
-
- outkey();
-
- }
- }
- /**************************************************
- 定時器1中斷服務
- **************************************************/
- void Time1_Isr() interrupt 3
- {
- static unsigned char value; //定時2ms中斷一次
- TH1 = (65536-2000)/256;
- TL1 = (65536-2000)%256; //2ms
- // smgDis(); //數碼管顯示函數
- value++;
- if(value >= 250)//250次2ms中斷總時間位500ms
- {
- value = 0;
- Flag = 1;
- waring ++;
- }
- if(waring>1)
- {
- waring = 0;
- }
- }
復制代碼
Keil代碼與Proteus仿真下載:
超聲波.7z
(85.15 KB, 下載次數: 88)
2023-6-9 22:21 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|