UltrasonicSensor.c
/*-----------------------------------------------------------------
模块名称: 超声波
型 号:HC-SR04
模块功能: 返回探测距离
完成日期:2014-01-18
接 线:
4个接线端
VCC----------->+5V
TRIG---------->P3^3;
ECHO---------->P3^2;
GND----------->GND
备 注:
CPU:STC89C52RC
晶振:11.0592MHZ
每个定时器中断探测的距离:
DISTANCE=170*(12/11.0592)*(255-TL1) mm
即DISTANCE=0.1844*(255-TL1)毫米
-----------------------------------------------------------------*/
#include <AT89X52.H>
#include <intrins.h>
#include "UltrasonicSensor.h"
/*-----------------------------------------------------------------
函数名称:void UltrasonicSensorInit(void)
函数功能:初始化定时器0
参 数:无
返 回 值:无
备 注:
使用资源:INT0、定时器0
-----------------------------------------------------------------*/
unsigned int tmp;
void UltrasonicSensorInit(void)
{
定时器0初始化
TMOD |= 0x02; //定时器0自动重载8位定时器/计数器
//TMOD |= 0x08; //GATE=1外部INT0(p32)高电平触发
TR0 = 1; //INT0(P32)外部中断管脚高电平时启动定时器0
//P3 &= 0XD;/ INT0 = 0;
TH0 = 256-5;//设定初始值,0.922mm
TL0 = 256-5; //设定初始值
ET0 = 1; //定时器0中断允许
外部中断INT0初始化
IT0=1; //下降沿触发INT0
EA = 1; //打开全局中断
EX0 = 1; //打开外部中断0
num = 0;
ECHO=0;
}
/*-----------------------------------------------------------------
函数名称: void DelayMs(unsigned int i)
函数功能: 端口初始化
参 数:
返 回 值: 无
延时程序计算方法
计数个数j = 延时时间/6*晶振频率 - 1
-----------------------------------------------------------------*/
void delayms(unsigned int xms)
{
unsigned int i,j;
for(i=xms;i>0;i--)
for(j=110;j>0;j--);
}
/*-----------------------------------------------------------------
函数名称:unsigned int UltSensorTrig (void)
函数功能:触发超声波模块,并接受数据,返回数据
参 数:无
返 回 值:未标定的接受值
备 注:
-----------------------------------------------------------------*/
unsigned int UltSensorTrig (void)
{
unsigned char i;
num=0;
打开中断
EA=1;//全局中断允许
EX0=1;//INT0中断允许
ET0=1; //定时器0溢出中断允许
触发
TRIG=0;
TRIG=1;
for(i=20;i>0;i--);
TRIG=0;
接受
while(!ECHO); //等待电平拉高
TR0=1; //拉高电平后,定时器0使能,开始计时
while(ECHO); //等待电平拉低
TR0=0;//接受完成后,定时器0禁止,停止计时
转换完成
//关闭中断
EA=0;//全局中断禁止
EX0=0;//INT0中断禁止
ET0=0;//拉低后,反馈完成,定时器0溢出中断禁止
数据返回
return tmp;
}
/*-----------------------------------------------------------------
函数名称:unsigned int DataFlter(unsigned int *data,unsigned char num)
函数功能:中值滤波
参 数:data:原始数据地址 num:数据个数
返 回 值:无
备 注:
-----------------------------------------------------------------*/
unsigned int DataFilter(unsigned int* data_tmp,unsigned char num)
{
unsigned char i,j;
unsigned int result,tmp;
//中值滤波,舍去最小与最大,求中间3个数字的平均值
for(i=0;i<num-1;i++)//冒泡法排序
for(j=0;j<num-i;j++)
{
if(data_tmp[j]>data_tmp[j+1])
{
tmp=data_tmp[j];
data_tmp[j]=data_tmp[j+1];
data_tmp[j+1]=tmp;
}
}
result=(data_tmp[9]+data_tmp[10]+data_tmp[11])/3; //取中间3数字平均值
return result;
}
/*-----------------------------------------------------------------
函数名称:unsigned int GetData(unsigned int delayms)
函数功能:选择delayms获取数据,先中值滤波,后返回终值
参 数:无
返 回 值:16位uint
备 注:
-----------------------------------------------------------------*/
unsigned int GetData(unsigned int delaynum)
{
static unsigned char i;
static unsigned int result_tmp;
static unsigned int data_tmp[20];
for(i=0;i<20;i++)//取20组数据
{
data_tmp[i]= UltSensorTrig();
delayms(delaynum/20);//延时触发
}
result_tmp=DataFilter(data_tmp,20);//将20数据滤波得到终值
return result_tmp;
}
//产生一次中断时间为 0.27ms
void T0_timer() interrupt 1
{
num++;
}
//INT0中断,下降沿触发,说明转换完成,则清零计数器,计算距离
void INT0_ser() interrupt 0
{
TR0=0;//禁止定时器0
tmp=num; //单位为mm
num=0;//清零数据
ECHO=0;
}
UltrasonicSensor.h
#ifndef __UltrasonicSensor_H_
#define __UltrasonicSensor_H_
//#include <......h> 包含led.c中需要用到的外部函数所在头文件
sbit TRIG=P3^3;
sbit ECHO=P3^2;
static unsigned int num,tmp;
extern unsigned int GetData(unsigned int delayms);//获取数据,返回最终滤波后的数据
extern void delayms(unsigned int xms);
extern void T0_timer(void);//终端服务程序
extern void INT0_ser(void);//终端服务程序
extern void UltrasonicSensorInit(void);
static unsigned int DataFilter(unsigned int* data_tmp,unsigned char num);//中值滤波
static unsigned int UltSensorTrig (void); //发送超声波触发信号
#endif
main.c
#include <AT89X52.H>
#include <intrins.h>
#include "SerialPort.h"
#include "Timer.h"
#include "UltrasonicSensor.h"
//水位
#define HIGH 50
#define LOW 240
unsigned char STATUS;//状态 0:正常 1:水位过高 2:水位过低
unsigned char FLAG;//超声波回传完成标志
/*接线:VCC GND TRIG接P33 ECHO接P32*/
/*-----------------------------------------------------------------
函数名称: main()
函数功能: 每隔1000ms检测一次距离,并将距离通过串口发送
参 数: 无
返 回 值: 无
延时程序计算方法
计数个数j = 延时时间/6*晶振频率 - 1
-----------------------------------------------------------------*/
main()
{
unsigned int result;
SerialPortInit();//串口初始化,串口:定时器1
UltrasonicSensorInit();//超声波传感器及使用资源初始化;使用资源:
send_hex(0x01);
while(1)
{
result=GetData(1000);//1000ms检测一次
send_hex2uint(result);
send_hex('\r');
send_hex('\n');
if(result<HIGH)//水位越高,距离越近,数值越小
STATUS=1;
if(result>LOW)//水位越低,距离越远,数值越大
STATUS=2;
if(result<LOW&&result>HIGH)
STATUS=0;
/* switch (STATUS)
{
case 0: //
send_hex('0');
break;
case 1:
send_hex('1');
break;
case 2:
send_hex('2');
break;
default:
send_hex('3');
} */
}
}