⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ultrasound.c

📁 基于AVR的超声波测距程序
💻 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 + -