之前使用stm32的大概原理是:

 输入引脚输入一个脉冲,捕获1开始极性捕获,捕获的是从启动捕获功能开始计数,捕获的是当前的计数值;

例如一个脉冲,捕获1捕获上升沿,捕获2捕获下降沿;而两个捕获计数值的差就是高电平的计数值;

计数值,又涉及到时钟,分频等;一个捕获时钟*计数值等于电平时间;

如下是预分频结构图/预定标

这个预定标是什么东西,2分频就是两个极性化成一个极性。第一个极性有效;4分频也是如此

DSP捕获输入简单笔记-LMLPHP

捕获大概框图

GPIO复用,ECAP模块,PIE组中断

DSP捕获输入简单笔记-LMLPHP

可以选择是捕获或者APWM模式

现在是CAP模式

DSP捕获输入简单笔记-LMLPHP

详细的捕获框图

cap引脚进来后,是 分频/预定标,极性选择,捕获计数器和相位寄存器控制(而且有时钟同步),捕获单次/连续控制,PIE组中断;

DSP捕获输入简单笔记-LMLPHP

连续/单次控制

捕获事件的时候,受到单次/连续事件 停止值控制;

这个中的计数器,是可以选择连续用捕获1到4的捕获,4次捕获。并且可以设置是否重置计数值;

DSP捕获输入简单笔记-LMLPHP

中断

ECFLG 标记         (后面是这个图没有的) 和PIE中断标记 和   ECAp一个通用的中断INT 只要有事件这个中断标记必有,在寄存器说明有;

所以中断里面需要清除三个标志;

本次是使用单次模式下的 连续1234捕获。在第四次捕获完成之后,进入中断;

DSP捕获输入简单笔记-LMLPHP

程序

/*
 * 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;
       }


    }

}
12-18 08:20