0 前言
这一节我们来学习DSP的ECAP模块的功能。实验目标:通过超声波测距模块,将采集所测量距离显示在电脑串口助手上。
本节将分为硬件部分、软件部分和实验展示三个方面进行介绍,不清楚的欢迎留言。
1 硬件部分
需要四个硬件如图1所示:超声波模块HC-SR04、DSP28335核心板、烧写器、USB转串口模块。
图1 硬件实物图
超声波模块有四个接口,分别为VCC(+5V)、TRIG(控制端)、ECHO(接收端)和GND,其工作原理如下:
(1)采用IO口输入信号到TRIG接口触发测距,给至少10us的高电平信号;
(2)触发后,模块自动发送8个40kHz的方波,自动检测是否有信号返回;
(3)若有信号返回,ECHO接口将输出一个高电平,其高电平的持续时间就是超声波从发射到返回的时间;
(4)测量距离=(高电平时间*声速)/2,其中声速=340m/s。
为了更清楚的表示超声波工作过程,图2给出了输入输出信号的时序图。
图2 超声波模块工作时序图
因此,在实验过程中,采用DSP的ECAP管脚连接到HC-SR04的ECHO接口,再用一个普通IO口连接到TRIG接口作为触发源管脚即可。其中,具体的硬件连接如图3所示。
图3 硬件接线图
2 软件部分
在软件部分,分为超声波模块功能和串口显示。
首先我们看超声波模块的代码:(注意:查看代码时双击点进去看,否则会内容不全)。
需要注意:
(1)ECAP要设置为单次模式,不能设置连续模式,因为这里超声波模块每触发一次只输出一次回响信号,因此我们只需要捕获信号的上升沿和下降沿即可,即上升沿捕获计数值储存在捕获寄存器CAP1中,而下降沿计数值储存在寄存器CAP2中。否则,所测量的捕获信号将可能储存在CAP3或CAP4中,对后面计算距离造成不便。在这里,我们设置在捕获事件2发生后重新刷新Mod4计数器,具体过程如图4所示。
图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; // 复位控制寄存器2
ECap1Regs.ECCTL2.all = 0x0000; // 复位控制寄存器2
ECap1Regs.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~CAP4
ECap1Regs.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,本实验给15us
GpioDataRegs.GPACLEAR.bit.GPIO0 = 1; // Trig引脚输出低
Distan = cap_val*170/150000; // 计算距离,此处单位为mm
scia_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 protocol
SciaRegs.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_RUN
MemCopy(&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变量窗口可以看到超声波所测量的距离。
图5 实验结果
大家可以参考代码尝试一下, 有疑问的欢迎留言!!
版权声明:本文为CSDN博主「Sk Electronics」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_46556696/article/details/118275250
暂无评论