之前使用stm32的大概原理是:
输入引脚输入一个脉冲,捕获1开始极性捕获,捕获的是从启动捕获功能开始计数,捕获的是当前的计数值;
例如一个脉冲,捕获1捕获上升沿,捕获2捕获下降沿;而两个捕获计数值的差就是高电平的计数值;
计数值,又涉及到时钟,分频等;一个捕获时钟*计数值等于电平时间;
如下是预分频结构图/预定标
这个预定标是什么东西,2分频就是两个极性化成一个极性。第一个极性有效;4分频也是如此
捕获大概框图
GPIO复用,ECAP模块,PIE组中断
可以选择是捕获或者APWM模式
现在是CAP模式
详细的捕获框图
cap引脚进来后,是 分频/预定标,极性选择,捕获计数器和相位寄存器控制(而且有时钟同步),捕获单次/连续控制,PIE组中断;
连续/单次控制
捕获事件的时候,受到单次/连续事件 停止值控制;
这个中的计数器,是可以选择连续用捕获1到4的捕获,4次捕获。并且可以设置是否重置计数值;
中断
ECFLG 标记 (后面是这个图没有的) 和PIE中断标记 和 ECAp一个通用的中断INT 只要有事件这个中断标记必有,在寄存器说明有;
所以中断里面需要清除三个标志;
本次是使用单次模式下的 连续1234捕获。在第四次捕获完成之后,进入中断;
程序
/*
* cap.c
*
* Created on: 2023年12月16日
* Author: My PC
*/
#include"cap.h"
void cap_init()
{
EALLOW;
SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1;//gpio时钟
SysCtrlRegs.PCLKCR1.bit.ECAP5ENCLK = 1;//cap5时钟
EDIS;
EALLOW;
GpioCtrlRegs.GPBMUX2.bit.GPIO48 = 1;//复用1
GpioCtrlRegs.GPBDIR.bit.GPIO48 = 0;//输入
GpioCtrlRegs.GPBPUD.bit.GPIO48 = 0;//下拉
GpioCtrlRegs.GPBQSEL2.bit.GPIO48 = 0;//与系统时钟同步
EDIS;
EALLOW;
ECap5Regs.ECEINT.all = 0;//禁止全部中断
ECap5Regs.ECCLR.all = 0xffff;//清除所有中断标记
ECap5Regs.ECCTL1.bit.CAPLDEN = 0;//禁止向cap捕获装载值
ECap5Regs.ECCTL2.bit.TSCTRSTOP = 0;//禁止计数
ECap5Regs.ECCTL1.bit.CAP1POL = 1;//下降沿触发
ECap5Regs.ECCTL1.bit.CAP2POL = 0;//上升边沿触发
ECap5Regs.ECCTL1.bit.CAP3POL = 1;
ECap5Regs.ECCTL1.bit.CAP4POL = 0;
ECap5Regs.ECCTL1.bit.CTRRST1 = 0;//捕获1后,计数值不复位,首次启动的时候,避免捕获1过大,选择此次复位,赋值为1合适点,反正第一次捕获值没什么意义;
ECap5Regs.ECCTL1.bit.CTRRST2 = 0;
ECap5Regs.ECCTL1.bit.CTRRST3 = 0;
ECap5Regs.ECCTL1.bit.CTRRST4 = 1;//捕获4后,计数值复位
ECap5Regs.ECCTL2.bit.CAP_APWM = 0;//运行再cap模式下
ECap5Regs.ECCTL2.bit.CONT_ONESHT = 1;//捕获处于单次模式
ECap5Regs.ECCTL2.bit.STOP_WRAP = 3;//单次模式下。捕获4完成之后停止
ECap5Regs.ECCTL2.bit.SYNCI_EN = 1;//使能内部同步 使得相位装载到计数器
ECap5Regs.ECCTL2.bit.SYNCO_SEL = 0;// 选择内部同步信号为外部同步信号
ECap5Regs.ECCTL2.bit.REARM = 1;//单次序列强制 mod计数器复位为0 计数器使能 使能捕获寄存器
EDIS;
EALLOW;
ECap5Regs.ECCTL2.bit.TSCTRSTOP = 1;//计数
ECap5Regs.ECCTL1.bit.CAPLDEN = 1;//使能向cap捕获装载值
ECap5Regs.ECEINT.bit.CEVT4 = 1;//使能捕获4中断
EDIS;
EALLOW;
PieCtrlRegs.PIEIER4.bit.INTx5 = 1;//PIE4的第5个中断使能;
PieVectTable.ECAP5_INT = &ECAP5_INT_REQ;//中断的函数 存中断函数地址的地址
EDIS;
IER |= M_INT4;//CAP5中断在 PIE的第四组
EINT;
ERTM;
}
Uint32 CAP_num_1=0, CAP_num_2=0, CAP_num_3=0, CAP_num_4=0;
interrupt void ECAP5_INT_REQ()
{
CAP_num_1 = ECap5Regs.CAP1;
CAP_num_2 = ECap5Regs.CAP2;
CAP_num_3 = ECap5Regs.CAP3;
CAP_num_4 = ECap5Regs.CAP4;
ECap5Regs.ECCLR.bit.CEVT4 = 1;
ECap5Regs.ECCLR.bit.INT = 1;//因为每个中断,这个INT标记都会设置1.所以要同时清除
ECap5Regs.ECCTL2.bit.REARM = 1;//下一次还是强制为单次序列
PieCtrlRegs.PIEACK.bit.ACK4=1;//PIE组4 的应答清除
}
48脚接一个PWM,可以仿真看到4个捕获值
主程序
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File
#include "led1.h"
#include "key.h"
#include "epwm.h"
#include "exti.h"
#include "time0.h"
#include "adc.h"
#include "cap.h"
int main()
{
float temp = 0;
Uint16 adc_num,i=0;
InitSysCtrl();
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
led_init();
time0_init(2000);
epwm_init(1000);
EPWM6_set_compara(1000, 500);//150M,不分频的PWM
cap_init();
while (1)
{
DELAY_US(200000);
EPWM6_set_compara(1000, i+=100);
if(i>1000)
{
i=0;
}
}
}