📄 ultrasound.c
字号:
#include <avr/io.h>
#include <avr/wdt.h>
#include <stdio.h>
#include <avr/delay.h>
#include <avr/signal.h>
#include "MyDef.h"
#include "ds1820.h"
#include "Ultrasound.h"
volatile uint Temp_Reflash_at=0;
float GetUltrasoundSpeed(void)
{
float Temp;
if(!Temp_Reflash_at)
{
Temp=GetTemperature();
Temp_Reflash_at=60000;
if(Temp!=-100) //测温不出错时计算超声波速度
Valuable_Speed=331.4+0.61*Temp;
else
Valuable_Speed=0; //用 0 表示测速出错
}
else
{
Temp_Reflash_at--;
}
#ifdef Debug
// if(Valuable_Speed!=0)
// printf("\nCurrent UltrasoundSpeed: %5.1f m/s",Valuable_Speed);
// else
// printf("\nError Occured!!! Wrong UltrasoundSpeed");
#endif
return Valuable_Speed;
}
uint Calculate_Distant(void) //距离计算函数
{
ulong Distance=0;
ulong Ultrasound_Spread_Time=0; //超声波在空气中传播的时间
uchar Temp;
Ultrasound_Spread_Time = Timer1_Counter_L+Timer1_Counter_H*256;
#ifdef Debug
// printf("\nCurrent Ultrasound_Spread_Time: %ld us",Ultrasound_Spread_Time);
#endif
Distance=GetUltrasoundSpeed(); //获取超声波在空气中的传播速度
if(Distance!=0) //不出错就计算距离
{
Distance = Ultrasound_Spread_Time*(uint)(Distance*10)/10/2; //先将超声波传播速度放大十倍再计算距离
Distance-=36000;
Distance=Distance*24/25; //距离纠正
Distance=Distance/100; //取前四位,即保留至毫米下一位
//四舍五入运算
Temp=(uchar)(Distance%10);
Distance=Distance/10;
if(Temp>4)
Distance++;
}
return (uint)Distance;
}
uint GetImmediateDistance(void)
{
uint CurrentDistant;
Ultrasound_TimeOut_Flag=0;
Ultrasound_Receive_Flag=0;
Start_T1;
Open_Ultrasound; //发射超声波脉冲 100ns
delay_nus(150);
Close_Ultrasound;
delay_nus(150); //防止超声波发射直接传递接收
Start_INT0; //开启超声波接收中断
while(!Ultrasound_TimeOut_Flag&&!Ultrasound_Receive_Flag); //等待接收
if(Ultrasound_TimeOut_Flag) //判断超声波接收是否超时
{
Ultrasound_TimeOut_Flag=0;
#ifdef Debug
//printf("\nError Occured !!! Ultrasound Receive TimeOut");
#endif
delay_nms(300); //每次采样的间隔不能太少 100ms 以上
}
else
{
Ultrasound_Receive_Flag=0;
CurrentDistant = Calculate_Distant(); //超声波正常接收则调用距离计算函数
#ifdef Debug
//printf("\nCurrent Distance: %d mm",CurrentDistant);
#endif
delay_nms(300); //每次采样的间隔不能太少 100ms 以上
return CurrentDistant;
}
return 0;
}
uint GetValuableDistant(void) //若所有抽取的样本均大于或小于上一次记录的值的话,距离才更新,否则保留原值
{
uchar i,Count_Big,Count_Small;
uchar Error=0;
uint Sampling_Distance[Sample]; //样本
Count_Big=0;
Count_Small=0;
for(i=0;i<Sample;i++) //抽样判决
{
Sampling_Distance[i] = GetImmediateDistance();
}
for(i=0;i<Sample;i++)
{
if(Sampling_Distance[i]>Valuable_Distance)
Count_Big++;
if(Sampling_Distance[i]<Valuable_Distance)
Count_Small++;
if(Sampling_Distance[i]<50||Sampling_Distance[i]>650)
Error=1;
}
if(!Error)
{
if(Count_Big==Sample||Count_Small==Sample)
{
Valuable_Distance=0;
for(i=0;i<Sample;i++)
{
Valuable_Distance+=Sampling_Distance[i];
}
Valuable_Distance=Valuable_Distance/Sample;
}
}
#ifdef Debug
if(Error)
printf("\nError Occured!!! Too Far Or Too Close 650mm >= Distance >= 50mm");
else
printf("\nCurrent Valuable Distance: %d mm",Valuable_Distance);
#endif
return Valuable_Distance;
}
SIGNAL(SIG_INTERRUPT0) //超声波接收中断
{
Stop_T1;
Stop_INT0;
Timer1_Counter_L=TCNT1L;
Timer1_Counter_H=TCNT1H;
TCNT1=0;
Ultrasound_Receive_Flag=1;
}
SIGNAL(SIG_OUTPUT_COMPARE1A) //超声波接收超时中断
{
Stop_T1;
TCNT1=0;
Stop_INT0;
Ultrasound_TimeOut_Flag=1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -