|
這款基于51單片機的液晶顯示超聲波測距儀,超聲波模塊使用的是US-100。這個基本上很常見的:通過一個矩形脈沖啟動超聲波,通過echo引腳計算出高電平的時間,這個已經有溫度補償!所以計算出來的時間是可以乘340m/s的。蜂鳴器用的是無源的,用PWM波就可以驅動啦!1k到5k。使用的液晶是1602液晶,以前也用過,實物圖如下圖所示:具體使用就不多說啦!下面是實物圖及源程序,貼出來方便大家仿制。
 
第一個文件:- #ifndef _1602_H_
- #define _1602_H_
- #include "reg52.h"
- sbit RS=P1^0;
- sbit RW=P1^1;
- sbit EN=P1^2;
- void delay();
- void delay1(int z);
- void write_com(unsigned char com);
- void write_date(unsigned char date);
- void L1602_init();
- void L1602_char(unsigned char hang,unsigned char lie,char sign);
- void L1602_string(unsigned char hang,unsigned char lie,unsigned char *p);
- void L1602_int(unsigned char hang, unsigned char lie, int num);
- #endif
- #include "1602.H"
- #include "reg52.h"
- #define uint unsigned int
- #define uchar unsigned char
- void delay()
- {
- int i,j;
- for(i=1;i>0;i--)
- for(j=15;j>0;j--);
- }
- void delay1(int z)
- {
- int i,j;
- for(i=z;i>0;i--)
- for(j=110;j>0;j--);
- }
- void write_com(uchar com)
- {
- P0 = com;
- RS = 0;
- RW = 0;//寫
- EN = 0;
- delay();
- EN = 1;
- delay();
- }
- void write_date(uchar date)
- {
- P0 = date;
- RS = 1;
- RW = 0;
- EN = 0;
- delay();
- EN = 1;
- delay();
- }
- void L1602_init()
- {
- write_com(0x01); //清屏
- write_com(0x38); //顯示模式
- write_com(0x0c); //顯示和光標
- write_com(0x06); //地址指針設置
- }
- void L1602_char(uchar hang,uchar lie,char sign)//顯示單個字符
- {
- uchar a;
- if(hang == 1) a = 0x80;
- if(hang == 2) a = 0x80+0x40;
- a = a + lie - 1;
- write_com(a);//寫地址
- write_date(sign); //寫數據
- }
- void L1602_string(uchar hang,uchar lie,uchar *p) //顯示字符串
- {
- uchar a;
- if(hang == 1) a = 0x80;
- if(hang == 2) a = 0x80+0x40;
- a = a + lie - 1;
- write_com(a);
- while(1)
- {
- if(*p == '\0') break;
- write_date(*p);
- p++;
- }
- }
- void L1602_int(uchar hang, uchar lie, int num)
- {
- uint temp;
- uint gewei,shiwei,baiwei,xiaoshu;
-
- temp = num;
- baiwei = temp / 1000;
- shiwei = temp % 1000 / 100;
- gewei = temp % 100 / 10;
- xiaoshu = temp % 10;
- if (num>=1000)
- {
- L1602_char(hang, lie+1, baiwei+48);
- L1602_char(hang, lie+2, shiwei+48);
- L1602_char(hang, lie+3, gewei+48);
- L1602_char(hang, lie+4, '.');
- L1602_char(hang, lie+5, xiaoshu+48);
- }
- else if (num>=100)
- {
-
- L1602_char(hang, lie+1, ' ');
- L1602_char(hang, lie+2, shiwei+48);
- L1602_char(hang, lie+3, gewei+48);
- L1602_char(hang, lie+4, '.');
- L1602_char(hang, lie+5, xiaoshu+48);
- }
- else
- {
- L1602_char(hang, lie+1, ' ');
- L1602_char(hang, lie+2, ' ');
- L1602_char(hang, lie+3, gewei+48);
- L1602_char(hang, lie+4, '.');
- L1602_char(hang, lie+5, xiaoshu+48);
- }
- }
復制代碼
第2個文件:- #include"1602.h"
- #define uchar unsigned char
- #define uint unsigned int
- sbit tring = P1^3; //超聲波控制端
- sbit echo = P3^2; //回波必須接在外部中斷引腳上
- sbit ledwarn = P2^0; //報警燈,低電平亮
- sbit beep = P2^1; //報警蜂鳴器
- uint displayCount;//顯示計數
- uint time = 0;//時間
- unsigned long distance ;//距離
- float distancef;//浮點型的數據
- uint flagSucceed = 0; //測量成功標志位
- uint flagDisplay = 0; //開顯示標志位
- void delay_20us()
- {
- uchar i ;
- for(i=0;i<140;i++);
- }
- void init_shuju()
- {
- tring = 0;
- distance = 0;
- displayCount = 0;
- }
- void init_waibu0()
- {
- IT0 = 0; //外部引腳為低時觸發中斷
- EX0=0; //關閉外部中斷
- }
- void timer0_Init()
- {
- TMOD = 0x11; //定時器0和1工作在16位方式
- TH0 = (65535-45872)/256;
- TL0 = (65535-45872)%6;
- TR0 = 1; //啟動定時器
- ET0 = 1; //允許定時器0中斷
- }
- void timer1_Init()
- {
- TMOD = 0x11; //定時器0和1工作在16位方式
- TH1 = 0;
- TL1 = 0;
- ET1 = 1; //定時器1中斷允許
- }
- void wbzd0() interrupt 0//下降沿觸發
- {
- time =TH1*256+TL1; //取出定時器的值
- flagSucceed = 1; //置成功測量的標志
- EX0=0; //關閉外部中斷
- // TR1=0;
- }
- void timer0() interrupt 1 // 定時器0
- {
- TH0 = (65535-45872)/256;
- TL0 = (65535-45872)%6;
- displayCount ++;
- if (displayCount >= 20) //1秒鐘顯示一次
- {
- flagDisplay = 1; //開顯示
- displayCount = 0;
- }
- }
- void start_csb() //啟動csb模塊
- {
- tring = 1;
- delay_20us();
- tring = 0;
- }
- void main()
- {
- EA=0;
- init_shuju();
- init_waibu0();
- timer0_Init();
- timer1_Init();
- L1602_init();
- L1602_string(1,1,"welcome my ");
- L1602_string(2,1,"test distance ");
- delay1(1);
- while(1)
- {
- EA=0;//關閉總中斷
- start_csb();
- while(echo==0);//變高則進入下一步
- flagSucceed = 0;
- TR1=1; //啟動定時器1開始計數
- EA = 1;
- EX0=1;
- TH1= 0;
- TL1= 0;
- TF1= 0; //定時器1溢出標志位
- while (TH1<90) ; //盲區
- TR1 = 0; //關閉定時器1
- EX0 = 0; //關閉外部中斷
-
- if(flagSucceed==1) //一次測試成功,則計算距離,單位為厘米
- {
- distancef = time * 1.085;//微妙為單位
- distancef /=58;//單位為厘米
- distance = distancef*10+0.5;
- //如果距離小于20cm,則聲光報警
- if ((flagSucceed == 1) && (distance <= 200))
- {
- ledwarn = 0;
- beep = 0;
- delay1(1);
- beep = 1;
- delay1(1);
- }
- else
- {
- ledwarn = 1;
- beep = 1;
- }
- }
- if (flagDisplay == 1) //1秒顯示時間到
- {
- if(flagSucceed==0)//沒有測試成功
- {
- L1602_string(1,1," can't distance ");
- L1602_string(2,1," ------ ");
- }
- else
- {
- //LCD顯示數據
- L1602_string(1,1,"distance result:");
- L1602_string(2,1," cm ");
- L1602_int(2,5,distance);
- }
- flagDisplay = 0;
- }
- }
- }
復制代碼
|
|