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

📄 userfunction.c

📁 超声波倒车雷达的设计程序 利用SPCE061A单片机实现超声波倒车雷达的测量计算方法。程序中采用软件校正
💻 C
字号:
//========================================================
//	文件名称:	UserFunction.c
//	功能描述:	超声波测距功能子程序程序
//  日期:       2006-4-13  
//========================================================
//========================================================
#include "SPCE061A.h"

#define M_TIMERA_EN       0x0001						//使能TimerA的配置,计数频率为96KHz
#define M_TIMERA_STOP	  0x0006						//停止TimerA的配置,计数器停止工作

unsigned int  M_TIMER_DELAY=95;						//为防止余波干扰而定义的延时
unsigned int  M_LOW_DISTEN=7;
unsigned int  M_TIMER_OFFSET=20;
unsigned int  M_TIMER_SEND=14;
unsigned int  M_MUT_DATA=32800;

unsigned int uiIOB_20Hz_flag;							//IOB01口(即20Hz方波输出口)的状态标识
unsigned int uiEXT_EN_flag;								//外部中断使能标识位

unsigned int uiMeasure_Index;							//当前测量的次数
unsigned int uiResult[4];								//保存测四次测量结果的缓存区

unsigned int ResultOS(void);
void ErrorOS(void);
void InitMeasureData(void);

unsigned int uiError_Counter;							//出错累加器
//============================================================= 
// 函数名称:    InitMeasure()
// 功能描述:	系统IO口、中断等进行初始化
// 语法格式:    void InitMeasure(void)
// 入口参数:    无
// 出口参数:    无
// 注意事项:    用户可参考设置进行必要修改,以适应不同情况
//=============================================================
void InitMeasure(void)
{
	//设置IOB口   IOB04口为20Hz(也许用16Hz)的输出,以控制模组发射40KHz方波   
	//IOB2 口为外部中断的输入,设置为带上拉的输入口。
	*P_SystemClock = 0x000b;
	
	*P_IOB_Dir = 0x0008;
	*P_IOB_Attrib = 0x0008;
	*P_IOB_Data = 0x0004;
	//开时间基准中断,TMB1  16Hz
	*P_TimeBase_Setup=0x0001;
	//设置TimerB   选使其处于停止工作状态
	*P_TimerB_Data = 0x0000;
	*P_TimerB_Ctrl = M_TIMERA_STOP;

	__asm("FIQ OFF");
	__asm("IRQ ON");
	
	InitMeasureData();
}
//============================================================= 
// 函数名称:    InitMeasureData()
// 功能描述:	部分全局数据的初始化
// 语法格式:    void InitMeasureData(void)
// 入口参数:    无
// 出口参数:    无
// 注意事项:    仅为用户模型
//=============================================================
unsigned int uiLCD_EN_flag;
void InitMeasureData(void)
{
	uiIOB_20Hz_flag = 0;								//初始化为零
	uiEXT_EN_flag = 0;
	uiMeasure_Index = 0;
	uiLCD_EN_flag=0;
}

//============================================================= 
// 函数名称:    BeginMeasure()
// 功能描述:	进行一次测距  包括数据处理
//              每次测距都要进行四次测量,而且都是通过后台
//				的16Hz中断启动这四次测量
// 语法格式:    unsigend int BeginMeasure(void)
// 入口参数:    无
// 出口参数:    无
// 注意事项:    仅为用户模型
//=============================================================
//延时程序
//
void User_Delay(unsigned int iTimers)
{
	unsigned int i;
	for(i=0;i<iTimers;i++)
	{
		__asm("nop");
		*P_Watchdog_Clear = 0x0001;
	}
}
void US_Send200us(void)
{
	*P_TimerB_Data = 0x0000;							//TimerA计数器清零
	*P_IOB_Data=*P_IOB_Buffer|0x0008;
	*P_TimerB_Ctrl = M_TIMERA_EN;						//使能TimerA
	User_Delay(M_TIMER_SEND);							//延时,发送完十一个以上的完整的40KHz方波脉冲
	*P_IOB_Data=*P_IOB_Buffer&0xfff7;					//停止发送
	uiIOB_20Hz_flag = 1;								//置位标识位
}
unsigned int BeginMeasure(void)
{
	unsigned int uiExit_RQ;								//退出循环标识
	unsigned int uiMeasure_Result;						//测量结果
	unsigned int Temp = 0, Temp2 = 0;
	int i = 0, j = 0;
	
	*P_SystemClock = 0x000b;							//设置SystemCkock,以保证软件延时的准确
	uiExit_RQ = 1;
	
	uiMeasure_Index = 0;								//开始测量
	*P_INT_Ctrl = *P_INT_Ctrl_New|0x0002;				//打开16Hz中断,在中断里面启动测量
	while(uiExit_RQ)
	{
		if(uiIOB_20Hz_flag)								//当该标识位非零时才进行下面的判断
		{
			if(*P_TimerB_Data>=M_TIMER_DELAY)			//计数器中数值表明已经过了余波干扰延时
			{											//可以打开外部中断,检测回波信号
				*P_INT_Clear = 0x0100;					//开中断前先清中断
				*P_INT_Ctrl = *P_INT_Ctrl_New|0x0100;
				uiEXT_EN_flag = 1;
				uiIOB_20Hz_flag = 0;					//清该标志位,由16Hz中断启动下一次测量
			}
		}
		if(*P_TimerB_Data>900)							//TimerB当中的Data超过900时,表示超过了1.5m							
		{//如果测量的距离超过限定的1.5m ,则结束一次检测,固定置距离值为1.5m
			*P_INT_Ctrl = *P_INT_Ctrl_New&(~0x0100);	//关掉外部中断
			uiEXT_EN_flag = 0;
			*P_TimerB_Ctrl = M_TIMERA_STOP;				//同时计数器停止工作
			//对测得的时间差进行初步处理.......
			i = uiMeasure_Index;
			j = 0;
			Temp = 900;
			while(i)
			{
				Temp2 = uiResult[j];
				uiResult[j] = Temp;
				Temp = Temp2;
				j++;
				i--;
			}//end.......
		}
		//一次测距结束(即完成四次测量),进入结果处理
		if(uiMeasure_Index>4)							
		{
			uiMeasure_Index=0;
			uiMeasure_Result = ResultOS();				//处理测距结果
			if(uiMeasure_Result<=M_LOW_DISTEN)
			{//测量时出错,进入错误管理
				uiMeasure_Result = 0;					//出错时,结果为0
			}
			uiExit_RQ=0;
			break;
		}
		*P_Watchdog_Clear = 0x0001;
	}
	return uiMeasure_Result;							//返回数据,返回0时代表测量出错。
}

//============================================================= 
// 函数名称:    ResultOS()
// 功能描述:	对结果进行软件处理  包括结果解算、软件补偿等。 
// 语法格式:    unsigned int ResultOS(void)
// 入口参数:    无
// 出口参数:    十进制的距离,以cm为单位
// 注意事项:    仅为用户模型
//=============================================================
unsigned int ResultOS(void)
{
	unsigned long int uliResult2;	
	unsigned int uiResult1;
	unsigned int i;
	if(uiResult[0]<=(M_TIMER_DELAY+M_TIMER_OFFSET))
	{//测回数据当中,如果最大数小于规定的域值,此时的数据是错的
		return 0;
	}
	uiResult1 = (uiResult[1]+uiResult[2])/2-3;			//取平均值
	uliResult2 = (unsigned long int)uiResult1*M_MUT_DATA;//数据处理
	uliResult2 = uliResult2/96;
	uliResult2 = uliResult2/2;
	//用户可在止加入适当的软件补偿,以期得到更准确的距离值
//	uliResult2 = uliResult2-3050;
	uliResult2 = uliResult2/1000;
	
	//..end
	uiResult1 = (unsigned int)uliResult2;
	for(i=0;i<4;i++)
	{
		uiResult[i]=0;
	}
	return uiResult1;
}

//============================================================= 
// 函数名称:    void ErrorOS(void)
// 功能描述:	测量出错管理(处理)
// 语法格式:    void ErrorOS(void)
// 入口参数:    无
// 出口参数:    无
// 注意事项:    仅为用户模型
//=============================================================
void ErrorOS(void)
{
	unsigned int i;
	i=0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -