可以设定超声波测距的报警范围,显示超声波距离
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include <REGX52.H>
- #include "LCD1602.h" //LCD1602头文件
- #include "Delay.h" //延时
- #include "Timer0.h" //定时0头文件
- #include "Timer1.h" //定时1头文件
- //定义各种参数
- unsigned short Distance;
- unsigned char i;
- unsigned long DisH,DisL;
- unsigned int T0Count;
- unsigned char Time;
- unsigned int a,b;
- sbit Trig = P3^6; //定义两个超声波管脚
- sbit Echo = P3^7;
- sbit set = P3^0; //切换模式
- sbit up = P3^1; //加
- sbit down = P3^2; //减
- sbit yled = P2^1;
- sbit gled = P2^2;
- sbit rled = P2^3;
- sbit beep = P3^5;
- unsigned char Flag;//测量标志位0.5秒触发一次
- unsigned char nodis;//超出量程
- unsigned int mode;
- unsigned int change;
- unsigned int waring;
- unsigned int upper = 120;//上限
- unsigned int lower = 50;//下限
- //超声波初始化
- void Super_Wave_Init()
- {
- Trig = 0;
- Echo = 0;
- }
- //
- /**************************************************
- 距离测量
- **************************************************/
- void Measure(void)
- {
- unsigned char Err; //错误标记
- unsigned long distance,pTime;//距离,时间变量
- Err=0;
- Trig=1; //TR保持10us高电平触发模块测距
- Delay10Us();
- Trig=0;
- TH0=0;
- TL0=0;
- while(Echo==0);//等待ECHO变为高
- TR0=1; //启动定时器,外部高电平触发
- while(Echo==1)//等待超声波回应获超时
- {
- pTime=TH0*256+TL0;
- if(pTime>40000)//时间超时
- {
- Err=1;
- break;
- }
- }
- TR0=0;//关闭定时器
- pTime=TH0*256+TL0; //获取时间
-
- if(Err==0)
- {
-
- distance=(pTime*173)/1000;//;pTime*346/1000000/2=pTime*0.0173 仿真的环境温度为25度346m/s
- DisH = distance/10;
- DisL = distance%10;
-
- if((DisH>170)||(DisH<2))//量程170cm,超过量程显示0;测量距离小?cm,HCSR04最小测算2cm
- {
- Err=1;
-
- }
- else if(DisH>upper)
- {
- gled = 0;
- yled = 1;
- rled = 1;
- beep = 1;
- }
- else if((DisH>=lower)&&(DisH<=upper))
- {
- gled = 1;
- yled = 0;
- rled = 1;
- if(waring == 0)
- {
- beep = 1;
- }
- else
- {
- beep = 0;
- }
- }
- else if(DisH<lower)
- {
-
- gled = 1;
- yled = 1;
- rled = 0;
- beep = 0;
- if(waring == 0)
- {
- LCD_ShowString(2,1,"warning");
- }
- else
- {
- LCD_ShowString(2,1," ");
- }
-
- }
-
-
- }
- if(Err == 1)
- {
- nodis = 1;
- gled = 1;
- yled = 1;
- rled = 1;
- beep = 1;
- }
- }
- void outkey()
- {
- if(set == 0)
- {
- //Delay(8);
- mode++;
- change = 1;
- if(mode>2)
- {
- mode = 0;
- }
- while(set == 0);
- }
- switch(mode)
- {
- case 0://正常读数模式
- if(change == 1)
- {
- change = 0;
-
- LCD_ShowString(1,1,"distance:");
- LCD_ShowString(1,15,"cm");
- LCD_ShowString(1,13,".");
- LCD_ShowString(2,1," ");
- }
- if(Flag)//每500ms测量一次
- {
- Flag=0;
- Measure();//测量
- if(nodis == 0)
- {
- LCD_ShowNum(1,10,DisH,3);
- LCD_ShowNum(1,14,DisL,1);
- }
- else
- {
- nodis = 0;
- LCD_ShowString(1,10,"-");
- LCD_ShowString(1,11,"-");
- LCD_ShowString(1,12,"-");
- LCD_ShowString(1,14,"-");
- }
- }
- break;
- case 1://改下限
- if(change == 1)
- {
- change = 0;
- LCD_ShowString(2,1,"upper:");
- LCD_ShowNum(2,7,upper,3);
- LCD_ShowString(2,10," ");
- LCD_ShowString(1,1,"lower:");
- LCD_ShowNum(1,7,lower,3);
- LCD_ShowString(1,10," ");
-
- }
- if(up == 0)
- {
- lower++;
- LCD_ShowNum(1,7,lower,3);
- while(up == 0);
- }
- if(down == 0)
- {
- lower--;
- LCD_ShowNum(1,7,lower,3);
- while(down == 0);
- }
- break;
- case 2://改上限
- if(change == 1)
- {
- change = 0;
- LCD_ShowString(2,1,"upper:");
- LCD_ShowNum(2,7,upper,3);
- LCD_ShowString(2,10," ");
- LCD_ShowString(1,1,"lower:");
- LCD_ShowNum(1,7,lower,3);
- LCD_ShowString(1,10," ");
-
- }
- if(up == 0)
- {
- upper++;
- LCD_ShowNum(2,7,upper,3);
- while(up == 0);
- }
- if(down == 0)
- {
- upper--;
- LCD_ShowNum(2,7,upper,3);
- while(down == 0);
- }
- break;
- default:break;
-
- }
- }
- //主函数
- void main()
- {
- LCD_Init();
- Timer0Init(); //该定时器没有写TR0.
- Timer1Init();
- LCD_ShowString(1,1,"distance:");
- LCD_ShowString(1,15,"cm");
- LCD_ShowString(1,13,".");
- while(1)
- {
-
- outkey();
-
- }
- }
- /**************************************************
- 定时器1中断服务
- **************************************************/
- void Time1_Isr() interrupt 3
- {
- static unsigned char value; //定时2ms中断一次
- TH1 = (65536-2000)/256;
- TL1 = (65536-2000)%256; //2ms
- // smgDis(); //数码管显示函数
- value++;
- if(value >= 250)//250次2ms中断总时间位500ms
- {
- value = 0;
- Flag = 1;
- waring ++;
- }
- if(waring>1)
- {
- waring = 0;
- }
- }
复制代码
Keil代码与Proteus仿真下载:
超声波.7z
(85.15 KB, 下载次数: 88)
|