keil程序 不懂得可以聯系我 哈哈
超聲波測距仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png (14.85 KB, 下載次數: 149)
下載附件
2019-5-19 02:40 上傳
0.png (4.22 KB, 下載次數: 127)
下載附件
2019-5-19 02:42 上傳
超聲波模塊加載HC-SR04.hex
單片機加載 程序.hex
電路原理圖如下:
0.png (40.68 KB, 下載次數: 129)
下載附件
2019-5-19 02:40 上傳
單片機源程序如下:
- #include <reg52.H>//器件配置文件
- #include <intrins.h>
- //傳感器接口
- sbit RX = P3^2;
- sbit TX = P3^3;
- //按鍵聲明
- sbit S1 = P1^4;
- sbit S2 = P1^5;
- sbit S3 = P1^6;
- //蜂鳴器
- sbit Feng= P2^0;
- sbit W1=P1^0;
- sbit W2=P1^1;
- sbit W3=P1^2;
- sbit W4=P1^3;
- //變量聲明
- unsigned int time=0;
- unsigned int timer=0;
- unsigned char posit=0;
- unsigned long S=0;
- unsigned long BJS=50;//報警距離80CM
- //模式 0正常模式 1調整
- char Mode=0;
- bit flag=0;
- bit flag_KEY=0;
- unsigned char const discode[] ={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0xff/*-*/}; //數碼管顯示碼0123456789-和不顯示
- //unsigned char const positon[4]={0xfd,0xfb,0xf7,0xfe}; //位選
- unsigned char disbuff[4] ={0,0,0,0}; //數組用于存放距離信息
- unsigned char disbuff_BJ[4] ={0,0,0,0};//報警信息
- void Display();
- //延時20ms(不精確)
- void delay(void)
- {
- unsigned char a,b,c;
- for(c=2;c>0;c--)
- for(b=38;b>0;b--)
- for(a=60;a>0;a--);
- }
- //按鍵掃描
- void Key_()
- {
- if(flag_KEY==0)
- {
- if(Mode!=0)
- {
- //+
- if(S1==0)
- {
- delay(); //延時去抖
- if(S1==0)
- {
- BJS++; //報警值加
- flag_KEY=1;
- if(BJS>=151) //最大151
- {
- BJS=0;
- }
- // while(S1==0)
- // Display();
- }
-
- }
- //-
- if(S2==0)
- {
- delay();
- if(S2==0)
- {
- BJS--; //報警值減
- flag_KEY=1;
- if(BJS<=1) //最小1
- {
- BJS=150;
- }
- // while(S2==0)
- // Display();
- }
-
- }
- }
- //功能
- if(S3==0) //設置鍵
- {
- delay();
- if(S3==0)
- {
- Mode++; //模式加
- flag_KEY=1;
- if(Mode>=2) //加到2時清零
- {
- Mode=0;
- }
- // while(S3==0)
- // Display();
- }
- }
- }
- if((P1&0x70)==0x70)
- {
- flag_KEY=0;
- }
- }
- /**********************************************************************************************************/
- //掃描數碼管
- void Display(void)
- {
- //正常顯示
- if(Mode==0)
- {
- P0=0x00; //關閉顯示
- if(posit==1)//數碼管的小數點
- {
- P0=0xff;
- P0=(discode[disbuff[posit]])|0x80;
-
- //按位或,最高位變為1,顯示小數點
- }
- else if(posit==0)
- {
- P0=0xff;
- P0=~discode[11];
- }
- else
- {
- P0=0xff;
- P0=discode[disbuff[posit]];
-
- }
- switch(posit)
- {
- case 0 : W1=0;W2=1;W3=1;W4=1; break;
- case 1 : W1=1;W2=0;W3=1;W4=1; break;
- case 2 : W1=1;W2=1;W3=0;W4=1; break;
- case 3 : W1=1;W2=1;W3=1;W4=0; break;
- }
- posit++;
- if(posit>3) //每進一次顯示函數,變量加1
- posit=0; //加到3時清零
- }
- //報警顯示
- else
- {
- P0=0x00;
- if(posit==1)//數碼管的小數點
- {
- P0=(discode[disbuff_BJ[posit]])|0x80;
- }
- else if(posit==0)
- {
- P0=0x76; //顯示字母
- }
- else
- {
- P0=discode[disbuff_BJ[posit]];
- }
- switch(posit)
- {
- case 0 : W1=0;W2=1;W3=1;W4=1; break;
- case 1 : W1=1;W2=0;W3=1;W4=1; break;
- case 2 : W1=1;W2=1;W3=0;W4=1; break;
- case 3 : W1=1;W2=1;W3=1;W4=0; break;
- }
- posit++;
- if(posit>3)
- posit=0;
- }
- }
- /**********************************************************************************************************/
- //計算
- void Conut(void)
- {
- time=TH0*256+TL0; //讀出T0的計時數值
- TH0=0;
- TL0=0; //清空計時器
- S=(time*1.7)/100; //算出來是CM
- //聲音的速度是340m/s,時間的單位是us,計算到秒需要將時間數據/1000000,
- //長度=速度*時間,340*time/1000000,長度數據單位是m轉換成cm需要乘以100得到340*time/10000,
- //小數點都向左移兩位得到3.4*time/100,因為超聲波是往返了,所以再除以2,得到距離數據(time*1.7)/100
- if(Mode==0) //非設置狀態時
- {
- if((S>=700)||flag==1) //超出測量范圍顯示“-”
- {
- Feng=0; //蜂鳴器報警
- flag=0;
- disbuff[1]=10; //“-”
- disbuff[2]=10; //“-”
- disbuff[3]=10; //“-”
- }
- else
- {
- //距離小于報警距
- if(S<=BJS)
- {
- Feng=0; //報警
- }
- else //大于
- {
- Feng=1; //關閉報警
- }
- disbuff[1]=S%1000/100; //將距離數據拆成單個位賦值
- disbuff[2]=S%1000%100/10;
- disbuff[3]=S%1000%10 %10;
- }
- }
- else
- {
- Feng=1;
- disbuff_BJ[1]=BJS%1000/100;
- disbuff_BJ[2]=BJS%1000%100/10;
- disbuff_BJ[3]=BJS%1000%10 %10;
- }
- }
- /**********************************************************************************************************/
- //定時器0
- void zd0() interrupt 1 //T0中斷用來計數器溢出,超過測距范圍
- {
- flag=1; //中斷溢出標志
- }
- /**********************************************************************************************************/
- //定時器1
- void zd3() interrupt 3 //T1中斷用來掃描數碼管和計800MS啟動模塊
- {
- TH1=0xf8;
- TL1=0x30; //定時2ms
- Key_(); //掃描按鍵
- Display(); //掃描顯示
- timer++; //變量加
- if(timer>=400) //400次就是800ms
- {
- timer=0;
- TX=1; //800MS 啟動一次模塊
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- TX=0;
- }
- }
- /**********************************************************************************************************/
- //主函數
- void main(void)
- {
- TMOD=0x11; //設T0為方式1
- TH0=0;
- TL0=0;
- TH1=0xf8; //2MS定時
- TL1=0x30;
- ET0=1; //允許T0中斷
- ET1=1; //允許T1中斷
- TR1=1; //開啟定時器
- EA=1; //開啟總中斷
- while(1)
- {
- while(!RX); //當上次接收完波后,RX引腳是低電平,取反就是1,此while成立,反復判斷RX狀態。當RX沒有接收到返回波時是高電平,取反就是0,此while不成立,跳出
- TR0=1; //開啟計數
- while(RX); //當RX沒有接收到返回波,此while成立,程序停在這里一直判斷RX狀態。當RX接收到返回波,RX引腳變為低電平,此while不成立,跳出
- TR0=0; //停止計數
- Conut(); //計算
- }
- }
復制代碼
0.png (7.88 KB, 下載次數: 125)
下載附件
2019-5-19 02:41 上傳
所有資料51hei提供下載:
超聲波測距.zip
(11.65 MB, 下載次數: 521)
2019-5-18 16:52 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|