這個是我設計做的51單片機實現超聲波雙路測距。(附帶詳細電路圖)
本程序可以實現雙路超聲波測距,并且顯示在12864上,并且實現了短距離報警功能。
電路原理圖如下:
0.png (84.65 KB, 下載次數: 27)
下載附件
2019-10-7 23:20 上傳
單片機代碼如下: - #include <reg52.h>
- #include <intrins.h>
- #define uint unsigned int
- #define uchar unsigned char
- //引腳定義
- sbit Trig1 = P2^4; //
- sbit Ecno1 = P2^5; //
- sbit Trig2 = P3^2; //
- sbit Ecno2 = P3^3; //
- sbit SPK=P2^3;
- sbit LED1=P1^0;
- sbit LED2=P1^1;
- #define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
- #define LCD_data P1^0 //數據口
- sbit LCD_RS = P3^5; //寄存器選擇輸入
- sbit LCD_RW = P3^6; //液晶讀/寫控制
- sbit LCD_EN = P3^4; //液晶使能控制
- sbit LCD_PSB = P3^7; //串/并方式控制
- sbit wela = P2^7;
- sbit dula = P2^6;
- // 函數聲明
- void Write_char(uchar dat);
- bit lcd_busy();
- void Lcd_init(void);
- void LCD_Write_string(uchar *str);
- void LCD_set_xy( unsigned char x, unsigned char y );
- void StartModule() ;
- void Clr_Scr();
- unsigned char code num[]={"0123456789 :."};
- unsigned char code table1[]={"前方距離:"};
- unsigned char code table2[] ={"后方距離:"};
- unsigned char code M[] = {"CM"};
- unsigned int time1=0;
- unsigned int time2=0;
- long S1=0;
- long S2=0;
- bit flag =0;
-
- unsigned char disbuff[4]={ 0,0,0,0,};
- /******************************************************************************/
- /*******************************************************************/
- /* */
- /* 延時函數 */
- /* */
- /*******************************************************************/
- void delay(uint x)
- {
- uint i,j;
- for(i= x;i>0;i--)
- for(j=110;j>0;j--);
- }
- void lcd_wcmd(uchar cmd)
- {
- while(lcd_busy());
- LCD_RS = 0;
- LCD_RW = 0;
- LCD_EN = 0;
- _nop_();
- _nop_();
- P0 = cmd;
- delayNOP();
- LCD_EN = 1;
- delayNOP();
- LCD_EN = 0;
- }
- void Lcd_init(void) //初始化LCD
- {
- LCD_PSB = 1; //并口方式
-
- lcd_wcmd(0x34); //擴充指令操作
- delay(5);
- lcd_wcmd(0x30); //基本指令操作
- delay(5);
- lcd_wcmd(0x0C); //顯示開,關光標
- delay(5);
- lcd_wcmd(0x01); //清除LCD的顯示內容
- delay(5);
- }
- bit lcd_busy()
- {
- bit result;
- LCD_RS = 0;
- LCD_RW = 1;
- LCD_EN = 1;
- delayNOP();
- result = (bit)(P0&0x80);
- LCD_EN = 0;
- return(result);
- }
- /******************************************************************************/
- /*void Write_char(uchar dat) //寫指令或數據
- {
- while(lcd_busy());
- LCD_RS = 1;
- LCD_RW = 0;
- LCD_EN = 0;
- P0 = dat;
- delayNOP();
- LCD_EN = 1;
- delayNOP();
- LCD_EN = 0;
- }
- */
-
- /******************************************************************************/
- void Delaynms(unsigned int di) //延時
- {
- unsigned int da,db;
- for(da=0;da<di;da++)
- for(db=0;db<10;db++);
- }
- /******************************************************************************/
- void Clr_Scr(void)//清屏函數
- {
- lcd_wcmd(0x01);
- }
- /******************************************************************************/
- void LCD_set_xy( unsigned char X, unsigned char Y )//設置LCD顯示的起始位置,X為行,Y為列
- {
-
- uchar pos;
- if (X==0)
- {X=0x80;}
- else if (X==1)
- {X=0x90;}
- else if (X==2)
- {X=0x88;}
- else if (X==3)
- {X=0x98;}
- pos = X+Y ;
- lcd_wcmd(pos); //顯示地址
- }
- void lcd_wdat(uchar dat)
- {
- while(lcd_busy());
- LCD_RS = 1;
- LCD_RW = 0;
- LCD_EN = 0;
- P0 = dat;
- delayNOP();
- LCD_EN = 1;
- delayNOP();
- LCD_EN = 0;
- }
- /******************************************************************************/
-
- void LCD_Write_string(uchar *str)//
- {
-
-
- for(;*str!='\0';str++)
- {
- lcd_wdat(*str);
- delay(2);
- }
-
- }
- /******************************************************************************/
- void LCD_Write_number(unsigned char s)// 數字顯示函數
- {
-
- lcd_wdat(num[s]);
- Delaynms(1);
- }
- /******************************************************************************/
- void Lcd_Mark2(void)
- {
- Clr_Scr();//清屏
- LCD_set_xy(0,0);
- LCD_Write_string("前方");//
- LCD_set_xy(0,7);
- LCD_Write_string("CM");
- LCD_set_xy(1,0);
- LCD_Write_string("后方");//
- LCD_set_xy(1,7);
- LCD_Write_string("CM");
- }
- /********************************************************/
- /********************************************************/
- void Conut1(void)
- {
- time1=TH0*256+TL0;
- TH0=0x00;
- TL0=0x00;
- S1=time1*1.87/100; // 11.0592M晶振
-
- if(flag==1) //超出測量
- {
- flag=0;
- LCD_set_xy( 0, 5 );
- LCD_Write_string("超");
-
- }
- else
- {
- disbuff[1]=S1%1000/100;
- disbuff[2]=S1%1000%100/10;
- disbuff[3]=S1%1000%100%10;
- LCD_set_xy( 0, 5 );
- LCD_Write_number(disbuff[1]);
- LCD_Write_number(disbuff[2]);
- LCD_set_xy( 0, 6 );
- LCD_Write_number(disbuff[3]);
- if(S1<70&&S1>=50)
- {
- SPK= 1;
- delay(1000);
- SPK= 0;
- delay(10);
-
- }
- if(S1<50&&S1>=30)
- {
- SPK= 1;
- delay(500);
- SPK= 0;
- delay(10);
-
- }
- if(S1<30&&S1>=10)
- {
- SPK= 1;
- delay(200);
- SPK= 0;
- delay(10);
-
- }
- if(S1<10)
- {
- SPK= 0;
-
- }
- else
- {
- SPK=1;
- }
- if(S1<70&&S1>=50)
- {
- LED1= 1;
- delay(1000);
- LED1= 0;
- delay(10);
-
- }
- if(S1<50&&S1>=30)
- {
- LED1= 1;
- delay(500);
- LED1= 0;
- delay(10);
-
- }
- if(S1<30&&S1>=10)
- {
- LED1= 1;
- delay(200);
- LED1= 0;
- delay(10);
-
- }
- if(S1<10)
- {
- LED1= 0;
-
- }
- else
- {
- LED1=1;
- }
- }
- }
-
- /****************************************************/
- void Conut2(void)
- {
- time2=TH0*256+TL0;
- TH0=0x00;
- TL0=0x00;
- S2=time2*1.87/100; // 11.0592M晶振
- if(flag==1) //超出測量
- {
- flag=0;
- LCD_set_xy( 1, 5 );
- LCD_Write_string("超");
-
- }
- else
- {
- disbuff[1]=S2%1000/100;
- disbuff[2]=S2%1000%100/10;
- disbuff[3]=S2%1000%100%10;
- LCD_set_xy( 1, 5 );
- LCD_Write_number(disbuff[1]);
- LCD_Write_number(disbuff[2]);
- LCD_set_xy( 1, 6 );
- LCD_Write_number(disbuff[3]);
- }
- }
- /****************************************************/
- void changkuan()
- {
- }
- /********************************************************/
- void delay20us(void) //誤差 -0.016637731481us
- {
- unsigned char a,b;
- for(b=1;b>0;b--)
- for(a=52;a>0;a--);
- //if Keil,require use intrins.h
- }
- void Delay5ms() //@11.0592MHz
- {
- unsigned char i, j;
- i = 54;
- j = 199;
- do
- {
- while (--j);
- } while (--i);
- }
- void Delay50ms() //@11.0592MHz
- {
- unsigned char i, j, k;
- i = 3;
- j = 26;
- k = 223;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
-
-
-
- void Delay300ms() //@11.0592MHz
- {
- unsigned char i, j, k;
- i = 13;
- j = 156;
- k = 83;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
- /********************************************************/
- void zd0() interrupt 1 //T0中斷用來計數器溢出,超過測距范圍
- {
- flag=1; //中斷溢出標志
- }
- /********************************************************/
- void StartModule1() //超聲波觸發函數
- { Trig1=0;
- delay20us();
- Trig1=1;
- delay20us(); //發射一個大于10us的脈沖,觸發超聲波發射
- Trig1=0;
- }
- /******************************************************/
- void StartModule2() //超聲波觸發函數
- { Trig2=0;
- delay20us();
- Trig2=1;
- delay20us(); //發射一個大于10us的脈沖,觸發超聲波發射
- Trig2=0;
- }
- /******************************************************/
- /********************************************************/
- void main(void)
- {
- TMOD=0x01; //設T0為方式1
- TH0=0x00;
- TL0=0x00;
- TR0=1;
- ET0=1; //允許T0中斷
- EA=1; //開啟總中斷
- Lcd_init(); //設置液晶顯示器
- Clr_Scr(); //清屏
- Delaynms(1000);
- Lcd_init(); //
- Lcd_Mark2();
- Delaynms(1000);
- while(1)
- {
- StartModule1(); //發出信號
- Ecno1 =1; //把Ecno腳置高后等待高電平回波信號
- while(!Ecno1); //當Ecno為零時等待
- TR0=1; //開啟計數
- while(Ecno1); //當RX為1計數并等待
- TR0=0; //關閉計數
- Conut1();
- delay(200);
-
- StartModule2(); //發出信號
- Ecno2 =1; //把Ecno腳置高后等待高電平回波信號
- while(!Ecno2); //當Ecno為零時等待
- TR0=1; //開啟計數
- while(Ecno2); //當RX為1計數并等待
- TR0=0; //關閉計數
- Conut2();
- delay(250);
-
- }
- }
復制代碼
全部資料51hei下載地址:
雙路超聲波測距 12864顯示.zip
(106.25 KB, 下載次數: 44)
2019-10-7 17:07 上傳
點擊文件名下載附件
雙路超聲波測距 下載積分: 黑幣 -5
|