📄 007.cpp
字号:
//=======================================================================================
// 工程名称: 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 + -