#include <mega16.h>
#include<delay.h>
#define uchar unsigned char
#define uint unsigned int
#define Open_Ultrasound() DDRD |=( 1<<7 ) //开启超声波发射
#define Close_Ultrasound() DDRD &= ~( 1<<7 ) //关闭超声波发射
#define Start_T1() TCNT1=0;SFIOR |=1;TCCR1B |= (1<<1);TIFR |= ((1<<4)|(1<<5));TIMSK |= (1<<5); //清零定时器 复位预分频器 开启计数器 允许输入捕获中断 8M 晶振下 8分频 获得 1us 时基
#define Stop_T1() TCCR1B &= ~(1<<1);TIMSK &= ~(1<<5); //关闭T1 关闭输入捕获中断
volatile unsigned char Flag_TimeoUt; //超声波接收超时
volatile unsigned char Flag_RecevOk; //超声波接受正常
sfrw ICR1=0x26;
void Ultrasound_Init(void)
{
TCCR1B =0x08; //设置T1工作模式 为比较匹配
OCR1A =4000; //设置为 65ms 超时 最大测量距离约为10M 一般不会超过这个
TIMSK = (1<<4); //溢出(超时) 中断
TCCR2=((1<<4)|(1<<3)|1);
//T2 使用 CTC模式 不预分频
OCR2=99; //PWM 输出 40000Hz
//OCR2=104; //PWM 输出 38000Hz
}
unsigned char GetDistant(void) //距离计算函数
{
unsigned int Speed,Distance;
Distance=0;
Speed=331;
//启动超声波发射
Open_Ultrasound() ;
delay_us(250); //放出约10个周期的超声波 周期 t = 1/40000 ~ 25us 所以在250us这个时间内 超声波约走了 d = 346.5*250/10000(25 摄氏度) = 8.7cm 的路程
//关闭超声波发射
Close_Ultrasound();
delay_us(400);
//还要继续延时约 走路程为两个超声波头间距离的时间 我设计的电路板 连个超声波头间距为4cm 那么最好延时 115us 以上
//总体上 超声波盲区 (测量出错区) 约为 (250 + 150)/10000*346.5 cm = 13.25cm(大概减少发送超声波的周期数可以缩短盲区 不过这样会减少测量的最大距离 这里只是我个人的实验结果,如有错误,请指正)
//开启定时器
Start_T1();
//等待超声波返回 或者 超时
while(!(Flag_TimeoUt)&&!(Flag_RecevOk));
if(Flag_TimeoUt)
{ Flag_TimeoUt = 0;
return 0;
}
else
{
//计算距离
Distance = (ICR1 +650+ 2)/2*Speed; //ICR1 + 前面延时的时间 + 指令执行的时间
Flag_RecevOk = 0;
TCNT1=0;
return (Distance);
}
}
interrupt [TIM1_COMPA] void timer1_compa_isr(void) //超声波接收超时中断
{
Stop_T1(); //关闭计数器
Flag_TimeoUt = 1;
}
interrupt [TIM1_CAPT] void tim1capt(void) //超声波接收中断
{
Stop_T1(); //关闭计数器
Flag_RecevOk = 1;
}
void display_tem()
{ unsigned int wen;
unsigned char n,v;
wen=get18b20data();
wen=wen%10000;
wen=wen%1000;
n=wen/10;
v=wen%10;
DisplayOneChar(2,0,n+0x30);
DisplayOneChar(3,0,v+0x30);
}
void main()
{
unsigned int distance;
unsigned char th,tm,tl,tmin;
DDRA=0xff;
//PORTA|=0X00;
DDRC=0XFF;
LCM_Init();
#asm("sei");
Ultrasound_Init();
while(1)
{
distance=GetDistant();
th=distance/1000;
tm=distance%1000/100;
tl=distance/100;
tmin=distance%10;
DisplayOneChar(2,0,th+0x30);
DisplayOneChar(3,0,tm+0x30);
DisplayOneChar(4,0,tl+0x30);
DisplayOneChar(5,0,tmin+0x30);
delay_ms(1000);
}
}