|
這款基于51單片機(jī)的液晶顯示超聲波測(cè)距儀,超聲波模塊使用的是US-100。這個(gè)基本上很常見(jiàn)的:通過(guò)一個(gè)矩形脈沖啟動(dòng)超聲波,通過(guò)echo引腳計(jì)算出高電平的時(shí)間,這個(gè)已經(jīng)有溫度補(bǔ)償!所以計(jì)算出來(lái)的時(shí)間是可以乘340m/s的。蜂鳴器用的是無(wú)源的,用PWM波就可以驅(qū)動(dòng)啦!1k到5k。使用的液晶是1602液晶,以前也用過(guò),實(shí)物圖如下圖所示:具體使用就不多說(shuō)啦!下面是實(shí)物圖及源程序,貼出來(lái)方便大家仿制。
 
第一個(gè)文件:- #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); //顯示和光標(biāo)
- write_com(0x06); //地址指針設(shè)置
- }
- void L1602_char(uchar hang,uchar lie,char sign)//顯示單個(gè)字符
- {
- uchar a;
- if(hang == 1) a = 0x80;
- if(hang == 2) a = 0x80+0x40;
- a = a + lie - 1;
- write_com(a);//寫地址
- write_date(sign); //寫數(shù)據(jù)
- }
- 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);
- }
- }
復(fù)制代碼
第2個(gè)文件:- #include"1602.h"
- #define uchar unsigned char
- #define uint unsigned int
- sbit tring = P1^3; //超聲波控制端
- sbit echo = P3^2; //回波必須接在外部中斷引腳上
- sbit ledwarn = P2^0; //報(bào)警燈,低電平亮
- sbit beep = P2^1; //報(bào)警蜂鳴器
- uint displayCount;//顯示計(jì)數(shù)
- uint time = 0;//時(shí)間
- unsigned long distance ;//距離
- float distancef;//浮點(diǎn)型的數(shù)據(jù)
- uint flagSucceed = 0; //測(cè)量成功標(biāo)志位
- uint flagDisplay = 0; //開(kāi)顯示標(biāo)志位
- 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; //外部引腳為低時(shí)觸發(fā)中斷
- EX0=0; //關(guān)閉外部中斷
- }
- void timer0_Init()
- {
- TMOD = 0x11; //定時(shí)器0和1工作在16位方式
- TH0 = (65535-45872)/256;
- TL0 = (65535-45872)%6;
- TR0 = 1; //啟動(dòng)定時(shí)器
- ET0 = 1; //允許定時(shí)器0中斷
- }
- void timer1_Init()
- {
- TMOD = 0x11; //定時(shí)器0和1工作在16位方式
- TH1 = 0;
- TL1 = 0;
- ET1 = 1; //定時(shí)器1中斷允許
- }
- void wbzd0() interrupt 0//下降沿觸發(fā)
- {
- time =TH1*256+TL1; //取出定時(shí)器的值
- flagSucceed = 1; //置成功測(cè)量的標(biāo)志
- EX0=0; //關(guān)閉外部中斷
- // TR1=0;
- }
- void timer0() interrupt 1 // 定時(shí)器0
- {
- TH0 = (65535-45872)/256;
- TL0 = (65535-45872)%6;
- displayCount ++;
- if (displayCount >= 20) //1秒鐘顯示一次
- {
- flagDisplay = 1; //開(kāi)顯示
- displayCount = 0;
- }
- }
- void start_csb() //啟動(dòng)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;//關(guān)閉總中斷
- start_csb();
- while(echo==0);//變高則進(jìn)入下一步
- flagSucceed = 0;
- TR1=1; //啟動(dòng)定時(shí)器1開(kāi)始計(jì)數(shù)
- EA = 1;
- EX0=1;
- TH1= 0;
- TL1= 0;
- TF1= 0; //定時(shí)器1溢出標(biāo)志位
- while (TH1<90) ; //盲區(qū)
- TR1 = 0; //關(guān)閉定時(shí)器1
- EX0 = 0; //關(guān)閉外部中斷
-
- if(flagSucceed==1) //一次測(cè)試成功,則計(jì)算距離,單位為厘米
- {
- distancef = time * 1.085;//微妙為單位
- distancef /=58;//單位為厘米
- distance = distancef*10+0.5;
- //如果距離小于20cm,則聲光報(bào)警
- if ((flagSucceed == 1) && (distance <= 200))
- {
- ledwarn = 0;
- beep = 0;
- delay1(1);
- beep = 1;
- delay1(1);
- }
- else
- {
- ledwarn = 1;
- beep = 1;
- }
- }
- if (flagDisplay == 1) //1秒顯示時(shí)間到
- {
- if(flagSucceed==0)//沒(méi)有測(cè)試成功
- {
- L1602_string(1,1," can't distance ");
- L1602_string(2,1," ------ ");
- }
- else
- {
- //LCD顯示數(shù)據(jù)
- L1602_string(1,1,"distance result:");
- L1602_string(2,1," cm ");
- L1602_int(2,5,distance);
- }
- flagDisplay = 0;
- }
- }
- }
復(fù)制代碼
|
|