我的项目是通过超声波模块来检测水位高低,超声波模块选的是CH-SR04,这个模块的检测范围是2~450cm,可以检测到水位在4.5米范围内的变化情况。
超声波模块的使用方法是先将Trig引脚拉高40毫秒,然后拉低,发出检测信号,然后等待Echo引脚输出高电平,高电平的持续时间与检测到的距离成正比,为每毫秒170毫米。我用定时器1配置周期为1毫秒,然后在定时器中断内对Echo高电平计数,最后得到检测距离,下面是定时器中断的代码:
void mTimer1Interrupt( void ) interrupt INT_NO_TMR1 using 2 //timer1中断服务程序,使用寄存器组2
{
//方式2时,Timer1自动重装
static UINT16 tmr1 = 0;
tmr1++;
if(tmr1 == 2000) //100us*2000 = 200ms
{
tmr1 = 0;
SCK = ~SCK;
LED0 = ~LED0;
}
if(SR04_Echo==1) //收到返回信息
count++;
}
#endif
然后在主循环内定时调用超声波检测函数:
LED_Control(2,1);
level_handler(); //检测水位
LED_Control(2,0);
下面是检测及显示处理函数:
void level_handler(void) //检测水位
{
UINT16 levs;
UINT8 c,d,i,l,m,n;
/* 超声波测距 */
levs = 0;
for(i=0;i<5;i++){
SR04_Trig = 1;
mDelaymS(1);
count = 0;
SR04_Trig = 0;
mDelaymS(100);
levs = levs +count;
}
levs = levs * 17 / 50; //计算检测距离(仪器到水面)200/80/5
if(levs > 500)
LCD_write_ASCII(43,3," ERROR");
else
LCD_write_value(45,3,5,2,0,levs);
levs = height - levs; //计算水位高度(安装高度-检测距离)
if(levs<=500){
if(level>levs){
if((level-levs)>devia) //水位变化超过范围,更新数据
level = levs;
}
else{
if((levs-level)>devia) //水位变化超过范围,更新数据
level = levs;
}
}
LCD_write_value(51,2,4,1,0,level/10);
//动态显示当前水位
LCD_write_ASCII(6,1," ");
LCD_write_ASCII(6,2," ");
LCD_write_ASCII(6,3," ");
LCD_write_ASCII(6,4," ");
l = 4 - (level / (height / 4));
LCD_write_value(6,l,3,1,0,level/10);
d = level *48 / height; //计算需要显示模拟高度的点
m = d / 8; //取模
n = d % 8; //取余
for (i=0; i<6; i++)
{
for (c=1; c<3; c++)
{
if (i < m)
{
LCD_set_XY(c,5-i);
LCD_write_byte(0xFF,1); //显示全部点
}
else if (i == m)
{
LCD_set_XY(c,5-i);
LCD_write_byte(map[n],1);//显示部分点
}
else
{
LCD_set_XY(c,5-i);
LCD_write_byte(0x00,1); //不显示点
}
}
}
}
这是检测结果显示,左边的水位模拟图会根据检测到的水位高低动态变化:
下图是测试的过程:
这是检测结果显示,左边的水位模拟图会根据检测到的水位高低动态变化:
此内容由EEWORLD论坛网友hujj原创,如需转载或用于商业用途需征得作者同意并注明出处