0 前言
这一节我们来学习DSP的ECAP模块的功能。实验目标:通过超声波测距模块,将采集所测量距离显示在电脑串口助手上。
本节将分为硬件部分、软件部分和实验展示三个方面进行介绍,不清楚的欢迎留言。
1 硬件部分
需要四个硬件如图1所示:超声波模块HC-SR04、DSP28335核心板、烧写器、USB转串口模块。
超声波模块有四个接口,分别为VCC(+5V)、TRIG(控制端)、ECHO(接收端)和GND,其工作原理如下:
(1)采用IO口输入信号到TRIG接口触发测距,给至少10us的高电平信号;
(2)触发后,模块自动发送8个40kHz的方波,自动检测是否有信号返回;
(3)若有信号返回,ECHO接口将输出一个高电平,其高电平的持续时间就是超声波从发射到返回的时间;
(4)测量距离=(高电平时间*声速)/2,其中声速=340m/s。
为了更清楚的表示超声波工作过程,图2给出了输入输出信号的时序图。
因此,在实验过程中,采用DSP的ECAP管脚连接到HC-SR04的ECHO接口,再用一个普通IO口连接到TRIG接口作为触发源管脚即可。其中,具体的硬件连接如图3所示。
2 软件部分
在软件部分,分为超声波模块功能和串口显示。
首先我们看超声波模块的代码:(注意:查看代码时双击点进去看,否则会内容不全)。
需要注意:
(1)ECAP要设置为单次模式,不能设置连续模式,因为这里超声波模块每触发一次只输出一次回响信号,因此我们只需要捕获信号的上升沿和下降沿即可,即上升沿捕获计数值储存在捕获寄存器CAP1中,而下降沿计数值储存在寄存器CAP2中。否则,所测量的捕获信号将可能储存在CAP3或CAP4中,对后面计算距离造成不便。在这里,我们设置在捕获事件2发生后重新刷新Mod4计数器,具体过程如图4所示。
(2)测量距离(单位mm)=(高电平时间*声速)/2=(CAP2值-CAP1值)×170/(150×1000)。其中150是代表DSP28335时钟频率为150MHz,1000是米到毫米的单位换算。
bsp_cap.c
/*** ********************************************************************************************* @file bsp_cap.c* @file SK Electronics* @version V1.0* @date 2021-xx-xx* @brief CAP应用函数接口* ******************************************************************************************** @attention* 实验平台:SK-F28335Mini 核心板* CSDN博客:https://blog.csdn.net/weixin_46556696* 淘宝:https://shop409670932.taobao.com*/#include "bsp_cap.h"
#include "bsp_sci.h"
extern Uint32 cap_val,Distan;
extern char Distan_ASCII[2];/*** @brief 初始化ECAP1配置* @parameter 无* @return_value 无*/
void Init_ECap1(void)
{InitECap1Gpio();EALLOW;GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0;//普通IO模式GpioCtrlRegs.GPADIR.bit.GPIO0 = 1;//配置成输出EDIS;ECap1Regs.ECEINT.all = 0x0000; // 关闭所有的CAP中断ECap1Regs.ECCLR.all = 0xFFFF; // 清除所有的CAP中断标志位ECap1Regs.ECCTL1.all = 0x0000; // 复位控制寄存器2ECap1Regs.ECCTL2.all = 0x0000; // 复位控制寄存器2ECap1Regs.TSCTR = 0; // 计数清零ECap1Regs.CTRPHS = 0; // 计数相位寄存器清零ECap1Regs.ECCTL1.bit.CAP2POL = 1;//捕获事件2下降沿触发ECap1Regs.ECCTL1.bit.CTRRST2 = 1;//捕获事件2发生时计数器复位ECap1Regs.ECCTL1.bit.CAP4POL = 1;//捕获事件4下降沿触发ECap1Regs.ECCTL1.bit.CTRRST4 = 1;//捕获事件4发生时计数器复位ECap1Regs.ECCTL1.bit.CAPLDEN = 1;//使能在捕获事件发生时装载CAP1~CAP4ECap1Regs.ECCTL1.bit.FREE_SOFT = 2;//TSCTR不受仿真影响ECap1Regs.ECCTL2.bit.STOP_WRAP = 1;//在捕获事件2发生后停止(单次模式)ECap1Regs.ECCTL2.bit.TSCTRSTOP = 1;//开始计数ECap1Regs.ECCTL2.bit.SYNCO_SEL = 2;//禁止SYNC_OUT输出信号ECap1Regs.ECEINT.bit.CEVT2 = 1; // 使能捕获事件2发生中断
}/*** @brief 计算距离* @parameter 无* @return_value 无*/
void ReadDistance(void)
{GpioDataRegs.GPASET.bit.GPIO0 = 1; //Trig引脚输出高电平DELAY_US(15); //至少10us,本实验给15usGpioDataRegs.GPACLEAR.bit.GPIO0 = 1; // Trig引脚输出低Distan = cap_val*170/150000; // 计算距离,此处单位为mmscia_msg("当前测距:\0");hextoascii(Distan);scia_msg(Distan_ASCII);scia_msg("mm\r\n");
}
bsp_cap.h
/*** ********************************************************************************************* @file bsp_cap.h* @file SK Electronics* @version V1.0* @date 2021-xx-xx* @brief CAP应用函数接口头文件* ******************************************************************************************** @attention* 实验平台:SK-F28335Mini 核心板* CSDN博客:https://blog.csdn.net/weixin_46556696* 淘宝:https://shop409670932.taobao.com*/#include "DSP28x_Project.h"
void Init_ECap1(void);
void ReadDistance(void);
串口模块显示代码:
bsp_sci.c
/*** ********************************************************************************************* @file bsp_sci.c* @file SK Electronics* @version V1.0* @date 2021-xx-xx* @brief 串口通信应用函数接口* ******************************************************************************************** @attention* 实验平台:SK-F28335Mini 核心板* CSDN博客:https://blog.csdn.net/weixin_46556696* 淘宝:https://shop409670932.taobao.com*/
#include "bsp_sci.h"
extern char Distan_ASCII[4];
/*** @brief 初始化SCI串口配置* @parameter 无* @return_value 无*/
void Sci_Init(void)
{//SCI的工作模式和参数需要用户在后面的学习中,深入的了解一个寄存器底层相关的资料了,多看看芯片手册和寄存器的意思。//因为28335的寄存器太多了,所以在以后的学习过程中,就不会对寄存器进行详细的注释了。InitSciaGpio();SciaRegs.SCICCR.all=0x07;// 1 stop bit, No loopback// No parity,8 char bits// async mode, idle-line protocolSciaRegs.SCICTL1.all=0x03;// enable TX, RX, internal SCICLK,#if(CPU_FRQ_150MHZ)SciaRegs.SCIHBAUD=0x0001;// 9600 baud @LSPCLK = 37.5MHz.SciaRegs.SCILBAUD=0x00E7;#endif#if(CPU_FRQ_100MHZ)SciaRegs.SCIHBAUD=0x0001;// 9600 baud @LSPCLK = 20MHz.SciaRegs.SCILBAUD=0x0044;#endif// SciaRegs.SCICTL2.bit.RXBKINTENA=1;// SciaRegs.SCICTL2.bit.TXINTENA=1;//SciaRegs.SCICCR.bit.LOOPBKENA=1;SciaRegs.SCICTL1.bit.SWRESET=1;// PieCtrlRegs.PIECTRL.bit.ENPIE=1;// IER|=M_INT9;// PieCtrlRegs.PIEIER9.bit.INTx1=1;// PieCtrlRegs.PIEIER9.bit.INTx2=1;}void scia_xmit(int a)//发送字节的函数
{while (SciaRegs.SCICTL2.bit.TXRDY == 0) {}SciaRegs.SCITXBUF=a;}void hextoascii(unsigned char num)//十位数字转化为对应ASCII格式
{char one,ten,hundred,thousand=0;one=num/1%10;//取个位ten=num/10%10;//取十位hundred=num/100%10;//取百位thousand=num/1000%10;//取千位Distan_ASCII[0]=thousand+0x30;Distan_ASCII[1]=hundred+0x30;Distan_ASCII[2]=ten+0x30;Distan_ASCII[3]=one+0x30;
}
void scia_msg(char * msg)//发送数组的函数
{int i;i = 0;SciaRegs.SCICTL2.bit.TXINTENA=0;while(msg[i] != '\0'){scia_xmit(msg[i]);i++;}SciaRegs.SCICTL2.bit.TXINTENA=1;
}
bsp_sci.h
/*** ********************************************************************************************* @file bsp_sci.h* @file SK Electronics* @version V1.0* @date 2021-xx-xx* @brief 串口通信函数接口头文件* ******************************************************************************************** @attention* 实验平台:SK-F28335Mini 核心板* CSDN博客:https://blog.csdn.net/weixin_46556696* 淘宝:https://shop409670932.taobao.com*/#ifndef _BSP_SCI_H_
#define _BSP_SCI_H_
#include "DSP28x_Project.h"void Sci_Init(void);
void scia_xmit(int a);//发送字节的函数
void scia_msg(char * msg);//发送数组的函数
void hextoascii(unsigned char num);
#endif /*_BSP_SCI_H_ */
main.c
/*** ********************************************************************************************* @file main.c* @file SK Electronics* @version V1.0* @date 2020-xx-xx* @brief ECAP超声波测距实验* ******************************************************************************************** @attention* 实验平台:SK-F28335Mini 核心板* CSDN博客:https://blog.csdn.net/weixin_46556696* 淘宝:https://shop409670932.taobao.com*/
#include "DSP28x_Project.h"
#include "bsp_cap.h"
#include "bsp_sci.h"
#define FLASH_RUN 1
#define SRAM_RUN 2
#define RUN_TYPE FLASH_RUN
#if RUN_TYPE==FLASH_RUN
extern Uint16 RamfuncsLoadStart;
extern Uint16 RamfuncsLoadEnd;
extern Uint16 RamfuncsRunStart;
#endif
/**************************************变量定义************************************************/
Uint32 cap_val=0,Distan=0;
char Distan_ASCII[4]={0,0,0,0};//存放测量距离的ASCII转换结果/**************************************声明区**************************************************/
__interrupt void Ecap1_isr(void); // Ecap1_isr()函数声明
interrupt void scia_Tx_isr(void);
interrupt void scia_Rx_isr(void);
void delay_1ms(Uint16 t);
/*** @brief 主函数* @parameter 无* @return_value 无*/
void main(void)
{
/*第一步:初始化系统控制:*/InitSysCtrl();/*第二步:初始化GPIO口*/InitGpio();/* 第三步:清除所有中断 和初始化 PIE 向量表:*/DINT;// 关闭全局中断InitPieCtrl();// 初始化 PIE 控制寄存器到默认状态,默认状态是全部 PIE 中断被禁用和标志位被清除IER = 0x0000;// 禁用 CPU 中断和清除所有 CPU 中断标志位:IFR = 0x0000;InitPieVectTable();// 初始化 PIE 中断向量表// 中断重映射,注册中断程序入口(用户按需求添加)EALLOW;PieVectTable. ECAP1_INT = &Ecap1_isr; // ECAP1_INT的中断映射EDIS;///*程序烧录入28335(可选的)*/
#if RUN_TYPE==FLASH_RUNMemCopy(&RamfuncsLoadStart,&RamfuncsLoadEnd,&RamfuncsRunStart);InitFlash();
#endif
/* 第四步: 初始化片上外设*/// InitPeripherals(); //初始化所有外设(本例程不需要)Sci_Init();//初始化和配置SCIA串口通信Init_ECap1(); // ECap1模块初始化IER |= M_INT4; //使能第一组中断PieCtrlRegs.PIEIER4.bit.INTx1 = 1; //使能第四组中断里的第一个中断--CAP1中断/* 第五步:添加用户功能具体代码*/EINT;ERTM;scia_msg("Hello SK Electronics!\r\n\0");scia_msg("更详细的DSP基础教程,请关注支持本人博客哈!\r\n\0");scia_msg("CSDN博客:https://blog.csdn.net/weixin_46556696\r\n\0");scia_msg("淘宝店铺:https://shop409670932.taobao.com\r\n\0");for(;;){ReadDistance(); // 计算距离delay_1ms(500); // 延时500ms}
}void delay_1ms(Uint16 t)
{while(t--){DELAY_US(1000);}
}/*** @brief ECAP1中断服务函数* @parameter 无* @return_value 无*/
__interrupt void Ecap1_isr(void)
{PieCtrlRegs.PIEACK.all = PIEACK_GROUP4; // 清除CAP1的PIE中断标志ECap1Regs.ECCLR.bit.INT = 1; // 清除ECap1中断标志位ECap1Regs.ECCLR.bit.CEVT2 = 1; // 清除事件2标志位cap_val=(int32)ECap1Regs.CAP2 - (int32)ECap1Regs.CAP1; // 计算脉冲
}
3 实验展示
程序烧录进去后,图5所示在串口助手和在CCS变量窗口可以看到超声波所测量的距离。
大家可以参考代码尝试一下, 有疑问的欢迎留言!!