|
这款基于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;
- }
- }
- }
复制代码
|
|