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

📄 007.cpp

📁 本系统利用凌阳SPCE061A单片机原理
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//=======================================================================================
//  工程名称:	ultrasonic_long.spj
//  功能描述:   超声波双向测距 
//  涉及的库:	CMacro1016.lib  SACMV26e.lib
//  组成文件:	main.c  ultrasonic_App.c  Speech.c  IRQ.c
//				key_scan.c  hardware.asm  isr.asm   Resource.asm
//	硬件连接:  IOA0~7连接数码管输入a~h,IOB4~7连接数码管片选输入
//				IOB3---------温度传感器的DQ数据端口引脚
//				IOB11---------外部电路CD4052模拟开关选通输出
//				IOB10---------单片机CD4052的低位选择 A 引脚
//				IOB9----------发送模块电路的出口
//				IOB2----------接收模块电路的入口
//				IOA8~15连接COL1~8,ROW接高电平
//=========================================================================================
//========================================================================
//	文件名称:	main.c
//	功能描述:	
//	创建日期:	2008-05-16   V5.0	15:50
//========================================================================
#include "SPCE061A.h"
#include "ultrasonic_App.h"
//========================================================================
//	语法格式:	int main(void)
//	实现功能:	主程序
//	参数:		无
//	返回值:	int 无意义
//========================================================================
unsigned int S_Address[13]={0x003f,0x0006,0x005b,0x004f,0x0066,0x006d,0x007d,0x0007,0x007f,0x006f,0x0039,0x0077,0x0071};
//译码表0,1,2,3,4,5,6,7,8,9,C,A,F
unsigned int D_Dig[4]={0x0810,0x0820,0x0840,0x0880};//位选信号
extern float Temper;

int main(void)
{
	void Init_IOAB(void);
	void display_Before(unsigned int data);
	void display_After(unsigned int data);
	void display_Temper(unsigned int data);
	void display_total(unsigned int data);
	unsigned int uiKey,flag=0;
	unsigned int result[3];
	unsigned int uiTemp;
	Init_IOAB();
	Initial_ult();	
	while(1)
	{	
		
		switch(flag)
		{
			case 0:break;
			case 1:display_total(result[0]);break;
			case 2:display_Before(result[1]);break;
			case 3:display_After(result[2]);break;
			case 4:display_Temper(Temper*10);break;
		}
		if((*P_IOA_Data&0xff00)!=0)
		{
			Init_IOAB();
			uiKey = Get_key();
			switch(uiKey)
			{
			case 0: break;
			case 256: 
				flag = 1;
				uiTemp = *P_IOB_Buffer;
				*P_IOB_Data = uiTemp&0xf7ff;			//接通外部电路供电开关	
				     
				measure_Times(result);
				
				uiTemp = *P_IOB_Buffer;
				*P_IOB_Data = uiTemp|0x0800;			//关闭外部电路供电开关
				
				Speech_Resource(14);					//"	测量结果为"		
				if(result[0]==0)
					Speech_Resource(15);				//结果为0时表示测量出错,播放"出错了"
				else
					Speech_Total(result[0]);
				break;
			case 512: 
				flag = 2;
				if(result[1]==0)
					Speech_Resource(15);		//结果为0时表示测量出错,播放"出错了"
				else
					Speech_Result(result[1]);
				break;
			case 1024: 	
				flag = 3;
				if(result[2]==0)
					Speech_Resource(15);		//结果为0时表示测量出错,播放"出错了"
				else
					Speech_Result(result[2]);
				break;
			case 2048:	
				flag = 4;
				if(Temper==0)
					Speech_Resource(15);		//结果为0时表示测量出错,播放"出错了"
				else							
					Speech_Temper(Temper*10);
				break;
			default: flag = 0;break;
			}
			uiKey = 0;
		}
		*P_Watchdog_Clear = 0x0001;
		
	}    
}

//IOA0~7,IOB4~7低电平输出,IOB11--CD4051B模拟开关选通输出
void Init_IOAB(void)
{
	unsigned uitemp;
	*P_IOA_Dir = 0x00ff;
	*P_IOA_Attrib = 0x00ff;
	*P_IOA_Data = 0x0000;
	
	uitemp = *P_IOB_Dir;
	uitemp = uitemp|0x08f0;
	*P_IOB_Dir = uitemp;
	uitemp = uitemp|0x08f0;
	*P_IOB_Attrib = uitemp;
	uitemp = *P_IOB_Buffer;
	uitemp = uitemp|0x0000;
	*P_IOB_Data = uitemp;
}
void display_Before(unsigned int data)
{
	unsigned int uiTemp;
	*P_IOB_Data = D_Dig[3];				//显示前距标志位"F"
	*P_IOA_Data = S_Address[12];
	Delay_ok(1,100);					//调用延时程序,延时约1ms
	uiTemp = data/100;
	*P_IOB_Data = D_Dig[2];
	*P_IOA_Data =S_Address[uiTemp]|0x0080;//或上小数点
	Delay_ok(1,100);					//调用延时程序,延时约1ms
	uiTemp = (data/10)%10;
	*P_IOB_Data = D_Dig[1];
	*P_IOA_Data = S_Address[uiTemp];
	Delay_ok(1,100);					//调用延时程序,延时约1ms
	uiTemp = data%10;		
	*P_IOB_Data = D_Dig[0];
	*P_IOA_Data = S_Address[uiTemp];
	Delay_ok(1,100);					//调用延时程序,延时约1ms
}
void display_After(unsigned int data)
{
	unsigned int uiTemp;
	*P_IOB_Data = D_Dig[3];				//显示后距标志位"A"
	*P_IOA_Data = S_Address[11];
	Delay_ok(1,100);					//调用延时程序,延时约1ms
	uiTemp = data/100;
	*P_IOB_Data = D_Dig[2];
	*P_IOA_Data =S_Address[uiTemp]|0x0080;//或上小数点
	Delay_ok(1,100);					//调用延时程序,延时约1ms
	uiTemp = (data/10)%10;
	*P_IOB_Data = D_Dig[1];
	*P_IOA_Data = S_Address[uiTemp];
	Delay_ok(1,100);					//调用延时程序,延时约1ms
	uiTemp = data%10;		
	*P_IOB_Data = D_Dig[0];
	*P_IOA_Data = S_Address[uiTemp];
	Delay_ok(1,100);					//调用延时程序,延时约1ms
}

void display_Temper(unsigned int data)
{
	unsigned int uiTemp;
	uiTemp = data/100;
	*P_IOB_Data = D_Dig[3];
	*P_IOA_Data =S_Address[uiTemp];
	Delay_ok(1,100);					//调用延时程序,延时约1ms
	uiTemp = (data/10)%10;
	*P_IOB_Data = D_Dig[2];
	*P_IOA_Data = S_Address[uiTemp]|0x0080; //或上小数点
	Delay_ok(1,100);					//调用延时程序,延时约1ms
	uiTemp = data%10;
	*P_IOB_Data = D_Dig[1];
	*P_IOA_Data = S_Address[uiTemp];
	Delay_ok(1,100);					//调用延时程序,延时约1ms
	*P_IOB_Data = D_Dig[0];				//显示温度标志"C"
	*P_IOA_Data = S_Address[10];
	Delay_ok(1,100);					//调用延时程序,延时约1ms
}

void display_total(unsigned int data)
{
	unsigned int uitemp;
	uitemp = data/1000;
	if(uitemp!=0)
	{
		*P_IOB_Data = D_Dig[3];
		*P_IOA_Data =S_Address[uitemp];
		Delay_ok(1,100);					//调用延时程序,延时约1ms
	}
	uitemp = (data/100)%10;
	*P_IOB_Data = D_Dig[2];           
	*P_IOA_Data = S_Address[uitemp]|0x0080;//或上小数点;
	Delay_ok(1,100);					//调用延时程序,延时约1ms
	uitemp = (data%100)/10;
	*P_IOB_Data = D_Dig[1];
	*P_IOA_Data = S_Address[uitemp];
	Delay_ok(1,100);					//调用延时程序,延时约1ms
	uitemp = data%10;
	*P_IOB_Data = D_Dig[0];
	*P_IOA_Data = S_Address[uitemp];
	Delay_ok(1,100);					//调用延时程序,延时约1ms
}

//========================================================================
//	文件名称:	ultrasonic_App.c
//	功能描述:	超声波测距模组的功能接口函数

//  修改时间:  2008-05-01
//  硬件连接方案:IOB10---------CD4052的低位选择 A 引脚
//				  IOB9----------发送模块电路的出口
//				  IOB2----------接收模块电路的入口
//	修改内容: measure_Times()		修改为:具有前后通道选择的测量控制主程序
//				Test_Temper()	修改为:将测量时的声速经行温度补偿
	
//========================================================================
#include "SPCE061A.h"
#include "ultrasonic_App.h"
#define SEND_TIMER			1000			//测距时的40KHz信号发射时长
#define SEND_TIMER2			3000		//测距的补充测距时的40KHz信号发射时长
#define WAIT_DELAY			600			//测距的防余波干扰延时时长
#define WAIT_DELAY2			1500			//测距的补充测距时的防余波干扰延时时长
#define FRONT_RES_ADD		0x0000		//测前距的结果补偿值
#define BEHIND_RES_ADD		0x0000		//测后距的补充测距时的结果补偿值
#define TOTAL_RES_ADD		0x0010		//测后距的补充测距时的结果补偿值

unsigned int Counter_buf;				//超声波测距当中,用于保存TimerB计数的变量,相当于时长
float Temper;							//外部温度值变量
unsigned int EXT1_IRQ_flag=0;			//外部中断标志变量,用于EXT1的IRQ中断程序和测距程序同步
//======================== ================================================
//	语法格式:	void Initial_ult(void)
//	实现功能:	超声波测距模组的初始化子程序
//	参数:		无
//	返回值:	无
//========================================================================
void Initial_ult(void)			//初始化端口主要是IOB8和IOB9,IOB2和IOB10
{	
	unsigned int uiTemp;
	uiTemp = *P_IOB_Dir;
	uiTemp = uiTemp|0x0600;
	uiTemp = uiTemp&0xfefb;
	*P_IOB_Dir = uiTemp;
	uiTemp = *P_IOB_Attrib;
	uiTemp = uiTemp|0x0604;
	uiTemp = uiTemp&0xfeff;
	*P_IOB_Attrib = uiTemp;
	uiTemp = *P_IOB_Buffer;
	uiTemp = uiTemp|0x0304;
	*P_IOB_Data = uiTemp;
}
//========================================================================
//	语法格式:	void Delay_ult(unsigned int timers)
//	实现功能:	超声波测距模组的延时子程序
//	参数:		unsigned int timers    延时的时长(仅是一个相对量)
//	返回值:	无
//========================================================================
void Delay_ult(unsigned int timers)
{
	unsigned int i;
	for(i=0;i<timers;i++)
	{
		asm("nop");
	}
}
//========================================================================
//	语法格式:	unsigned int Resoult_ult(unsigned int Counter)
//	实现功能:	超声波测距模组的测距数据处理程序,将TimerB的计数值换算为距离
//	参数:		Counter	需要换算的计数值
//	返回值:	计算后的距离,厘米为单位
//========================================================================
unsigned int Resoult_ult(unsigned int Counter)
{
	float temp;
	unsigned int vocity;
	unsigned long uiTemp;
	temp = 0.607*Temper;
	vocity = 33145+(unsigned int)temp;
	uiTemp = (unsigned long)Counter*vocity;
	uiTemp = uiTemp/196608;
	uiTemp = uiTemp>>1;
	return uiTemp;
}
//========================================================================
//	语法格式:	unsigned int measure_ult(void)
//	实现功能:	超声波测距模组的测距程序,完成一次测距
//	返回值:	所测得的距离,以厘米为单位
//========================================================================
unsigned int measure2_ult(void);
unsigned int measure_ult(void)
{
	unsigned int Exit_flag = 1;
	unsigned int uiResoult;
	unsigned int uiSystem_Clock;
	uiSystem_Clock = *P_SystemClock;	//将当前的系统时钟设置暂时保存起来
	*P_SystemClock = 0x0088;			//将系统时钟设置为49MHz,分频比为1,强振模式

	*P_TimerB_Ctrl = 0x03c0;			//enable 40KHz out
	*P_TimerB_Data = 0xfece;	
	Delay_ult(SEND_TIMER);			//delay for send the signal
	*P_TimerB_Ctrl = 0x0006;			//stop 40KHz out
	
	*P_TimerA_Ctrl = 0x0031;			//TimerA work as a counter at 192KHz
	*P_TimerA_Data = 0x0000;
	
	while(*P_TimerA_Data<WAIT_DELAY)	//等待一定时间,以避开余波的干扰
	{								
		*P_Watchdog_Clear = 0x0001;
	}
	*P_INT_Clear = 0x0100;					//开中断前先清中断
	*P_INT_Ctrl = *P_INT_Ctrl_New|0x0100;
	*P_INT_Clear = 0xffff;				//清除中断发生标志
	__asm("IRQ ON");					//打开总中断使能
	EXT1_IRQ_flag = 0;					//TimerA的溢出中断的标志变量置0
	while(Exit_flag)
	{
		if(EXT1_IRQ_flag==1)			//当该变量在timerA的FIQ中断中被置1时表示接收到了回波
		{
			Exit_flag = 0;				//exit
			Counter_buf = Counter_buf;  
			uiResoult = Resoult_ult(Counter_buf);//对计数值进行处理,得出距离值
		}
		if(*P_TimerA_Data>10000)		//如计数值大于10000,表示超时
		{
			Exit_flag = 0;				//exit
			uiResoult = measure2_ult();//再进行一次补充的测距,将会加长40KHz信号发射的量
//			*P_TimerA_Ctrl = 0x0006;	//stop timerA
		}
		*P_Watchdog_Clear = 0x0001;
	}
	*P_INT_Ctrl = *P_INT_Ctrl_New&(~0x0100);	//关掉外部中断
	__asm("IRQ OFF");					//关掉总中断
	
	*P_SystemClock = uiSystem_Clock;	//恢复系统时钟的设置
	return uiResoult;
}
//========================================================================
//	语法格式:	void EXT1_IRQ_ult(void)
//	实现功能:	超声波测距模组的测距程序的EXT1中断服务程序,在EXT1的IRQ中断
//				中调用
//	参数:		无
//	返回值:	无
//========================================================================
void EXT1_IRQ_ult(void)
{
	Counter_buf = *P_TimerA_Data;		//save the timerA counter
	*P_TimerA_Ctrl = 0x0006;			//stop timerA
	*P_INT_Ctrl = *P_INT_Ctrl_New&(~0x0100);	//关掉外部中断
	*P_INT_Clear = 0xffff;				//清除中断发生标志
	EXT1_IRQ_flag = 1;					//通知测距程序,外部中断已发生
}
//========================================================================
//	语法格式:	unsigned int measure2_ult(void)
//	实现功能:	补充进行一次远距的测量,以保证能够获取测量结果

//	返回值:	所测得的距离,以厘米为单位
//========================================================================
unsigned int measure2_ult(void)
{
	unsigned int Exit_flag = 1;
	unsigned int uiResoult;
	*P_TimerA_Ctrl = 0x0006;			//stop TimerA

	*P_INT_Ctrl = *P_INT_Ctrl_New&(~0x0100);	//关掉外部中断
	__asm("IRQ OFF");					//关掉总中断
	*P_INT_Clear = 0xffff;				//清除掉中断发生标志
	
	*P_TimerB_Ctrl = 0x03c0;			//enable 40KHz out
	*P_TimerB_Data = 0xfece;	
	Delay_ult(SEND_TIMER2);			//delay for send the signal
	*P_TimerB_Ctrl = 0x0006;			//stop 40KHz out
	
	*P_TimerA_Ctrl = 0x0031;			//TimerA work as a counter at 192KHz

⌨️ 快捷键说明

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