TI DSP 28335 eCAP 测量脉冲占空比


前言

随开发板带的教程并没有给出eCAP的解释和例程。
通过TI给出的源码结合调试开发板,正式看懂eCAP。
特此记录,加深印象~


本文用eCAP1捕获ePWM3生成50%占空比的脉冲,并验证该脉冲的周期占空比

1 eCAP简介

eCAP即增强型捕获模块
捕获模块能够捕获外部输入引脚的逻辑状态(电平的高或低、电平翻转时的上升沿或下降沿),并利用内部定时器对外部事件或者引脚状态的变化进行处理。

典型应用有:
- 电机测速
- 测量脉冲电平事件
- 测量脉冲信号周期和占空比
- 电压/电流传感器的PWM编码信号的解码

2 eCAP模块结构原理图

在这里插入图片描述
CAP模式下,捕获信号经过分频和极性选择后进行识别,对应时刻TSCTR的值存入CAP1-4,用于计算脉冲周期和占空比。

3 ePWM3配置步骤:InitEPwmTimer()

上一篇博客TI DSP 28335 ePWM实现单路带死区PWM仔细介绍过ePWM配置。
此处不再注释。

ePWM3频率TBCLK75MHzSYSCLKOUT/2),占空比50%(即占(PWM3_TIMER_MAX +1)/TBCLK),周期T2*(PWM3_TIMER_MAX +1)/TBCLK

#define PWM3_TIMER_MAX     8000
void InitEPwmTimer()
{
   EALLOW;
   SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
   EDIS;

   EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up
   EPwm3Regs.TBPRD = PWM3_TIMER_MAX;
   EPwm3Regs.TBPHS.all = 0x00000000;
   EPwm3Regs.AQCTLA.bit.PRD = AQ_TOGGLE;      // Toggle on PRD

   // TBCLK = SYSCLKOUT/2
   EPwm3Regs.TBCTL.bit.HSPCLKDIV = 1;
   EPwm3Regs.TBCTL.bit.CLKDIV = 0;
   
   EALLOW;
   SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
   EDIS;
}

4 eCAP1配置步骤:InitECapture()

对eCAP1的配置步骤进行了详细的注释。

void InitECapture()
{
   // 失能eCAP1所有中断
   ECap1Regs.ECEINT.all = 0x0000;             // Disable all capture interrupts
   // 清除eCAP1所有中断标志位
   ECap1Regs.ECCLR.all = 0xFFFF;              // Clear all CAP interrupt flags
   // 禁止在捕获事件发生时装载CAP1-CAP4
   ECap1Regs.ECCTL1.bit.CAPLDEN = 0;          // Disable CAP1-CAP4 register loads
   // TSCTR停止计数
   ECap1Regs.ECCTL2.bit.TSCTRSTOP = 0;        // Make sure the counter is stopped
  
   // 配置外设寄存器
   
   // 运行于单次模式
   ECap1Regs.ECCTL2.bit.CONT_ONESHT = 1;      // One-shot
   // 单次模式下捕获事件4之后停止
   ECap1Regs.ECCTL2.bit.STOP_WRAP = 3;        // Stop at 4 events

   // 上升沿触发捕获事件1
   ECap1Regs.ECCTL1.bit.CAP1POL = 0;          // Rising edge
   // 下降沿触发捕获事件2
   ECap1Regs.ECCTL1.bit.CAP2POL = 1;          // Falling edge
   // 上升沿触发捕获事件3
   ECap1Regs.ECCTL1.bit.CAP3POL = 0;          // Rising edge
   // 下降沿触发捕获事件4
   ECap1Regs.ECCTL1.bit.CAP4POL = 1;          // Falling edge
	
   // 差分模式
   // 在捕获事件1发生时复位计数器
   ECap1Regs.ECCTL1.bit.CTRRST1 = 1;          // Difference operation
   // 在捕获事件2发生时复位计数器
   ECap1Regs.ECCTL1.bit.CTRRST2 = 1;          // Difference operation
   // 在捕获事件3发生时复位计数器
   ECap1Regs.ECCTL1.bit.CTRRST3 = 1;          // Difference operation
   // 在捕获事件4发生时复位计数器
   ECap1Regs.ECCTL1.bit.CTRRST4 = 1;          // Difference operation

   // 使能计时器同步
   ECap1Regs.ECCTL2.bit.SYNCI_EN = 1;         // Enable sync in
   // 同步输入SYNC_IN将作为同步输出SYNC_OUT
   ECap1Regs.ECCTL2.bit.SYNCO_SEL = 0;        // Pass through  					  
											  
   // 使能在捕获事件发生时装载CAP1-CAP4
   ECap1Regs.ECCTL1.bit.CAPLDEN = 1;          // Enable capture units
   // TSCTR开始计数
   ECap1Regs.ECCTL2.bit.TSCTRSTOP = 1;        // Start Counter
   // Mod4重新装载
   ECap1Regs.ECCTL2.bit.REARM = 1;            // arm one-shot
   // 使能捕获事件4中断
   ECap1Regs.ECEINT.bit.CEVT4 = 1;            // 4 events = interrupt
}

5 ISR:周期及占空比计算

修改TI源码的ISR。
为方便观察实验结果,在InitECapture()中配置为差分模式。
该ISR能得到脉冲的周期、占空比以及进入CAP中断的次数。

interrupt void ecap1_isr(void)
{
   // 提取CAP1-CAP4的值
   TSt1 = ECap1Regs.CAP1;
   TSt2 = ECap1Regs.CAP2;
   TSt3 = ECap1Regs.CAP3;
   TSt4 = ECap1Regs.CAP4;
   // 计算周期
   Period1 = TSt1 + TSt2;
   Period2 = TSt3 + TSt4;
   // 计算占空比
   Duty1 = TSt1 / Period1;
   Duty2 = TSt3 / Period2;

   // 中断次数
   ECap1IntCount++;

   // 清除捕获事件4中断标志位
   ECap1Regs.ECCLR.bit.CEVT4 = 1;
   // 清除全局中断标志位
   ECap1Regs.ECCLR.bit.INT = 1;
   // Mod4重新装载
   ECap1Regs.ECCTL2.bit.REARM = 1;

   // 允许响应同组中断
   PieCtrlRegs.PIEACK.all = PIEACK_GROUP4;
}

6 主函数

这部分并没有修改TI的源码,只是增加了周期、占空比变量的声明

#include "DSP28x_Project.h"     // Device Headerfile and Examples Include File


// Configure the start/end period for the timer
#define PWM3_TIMER_MIN     10                    
#define PWM3_TIMER_MAX     8000

// Prototype statements for functions found within this file.
interrupt void ecap1_isr(void);
void InitECapture(void);
void InitEPwmTimer(void);

// Global variables used in this example
Uint32  ECap1IntCount;

// 周期、占空比声明
Uint32  TSt1 = 0;
Uint32  TSt2 = 0;
Uint32  TSt3 = 0;
Uint32  TSt4 = 0;
float32 Period1 = 0;
float32 Period2 = 0;
float32 Duty1 = 0;
float32 Duty2 = 0;

void main(void)
{

// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the DSP2833x_SysCtrl.c file.
   InitSysCtrl();

// Step 2. Initalize GPIO: 
// This example function is found in the DSP2833x_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
// InitGpio();  // Skipped for this example  
   
   InitEPwm3Gpio();
   InitECap1Gpio();

// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts 
   DINT;

// Initialize the PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.  
// This function is found in the DSP2833x_PieCtrl.c file.
   InitPieCtrl();
   
// Disable CPU interrupts and clear all CPU interrupt flags:
   IER = 0x0000;
   IFR = 0x0000;

// Initialize the PIE vector table with pointers to the shell Interrupt 
// Service Routines (ISR).  
// This will populate the entire table, even if the interrupt
// is not used in this example.  This is useful for debug purposes.
// The shell ISR routines are found in DSP2833x_DefaultIsr.c.
// This function is found in DSP2833x_PieVect.c.
   InitPieVectTable();

// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.  
   EALLOW;  // This is needed to write to EALLOW protected registers
   PieVectTable.ECAP1_INT = &ecap1_isr;
   EDIS;    // This is needed to disable write to EALLOW protected registers

// Step 4. Initialize all the Device Peripherals:
// This function is found in DSP2833x_InitPeripherals.c
// InitPeripherals();  // Not required for this example
   InitEPwmTimer();    // For this example, only initialize the ePWM Timers
   InitECapture();


// Step 5. User specific code, enable interrupts:

// Initalize counters:   
   ECap1IntCount = 0;
   // ECap1PassCount = 0;
   
// Enable CPU INT4 which is connected to ECAP1-4 INT:
   IER |= M_INT4;

// Enable eCAP INTn in the PIE: Group 3 interrupt 1-6
   PieCtrlRegs.PIEIER4.bit.INTx1 = 1;

// Enable global Interrupts and higher priority real-time debug events:
   EINT;   // Enable Global interrupt INTM
   ERTM;   // Enable Global realtime interrupt DBGM

// Step 6. IDLE loop. Just sit and loop forever (optional):
   for(;;)
   {
       asm("          NOP");
   }

} 

6 实验分析

ePWM3输出的引脚EPWM3A(即GPIO4)接到eCAP1的捕获引脚ECAP1(即GPIO24)。

ePWM3频率TBCLK75MHzSYSCLKOUT/2),高、低电平各占50%,即占(PWM3_TIMER_MAX +1)/TBCLK,在该例为

	Ton=Toff=(PWM3_TIMER_MAX +1)/TBCLK=(8000+1)/75

eCAP并未分频,其计数器频率为为150MHzSYSCLKOUT),对ePWM3生成的高、低电平进行捕获,TCR应为

	TCRcap=Ton*SYSCLKOUT=(8000+1)/75*150=16002

实际仿真为16001,见下图。
误差为

	Terror=1*SYSCLKOUT=1/150MHz=6.67ns

个人认为这完全在可接受范围内。

占空比仿真结果同理论结果,均为50%

在这里插入图片描述

总结

第39篇

由于手头没有对应的编码器等试验器材,增强型正交编码脉冲eQEP这一章节就不进行学习了。日后如有接触再进行对应学习。
学习到这,已经能看到DSP的特点:

除了强大高效的算力,更特别适合于运动控制

愿今日之所自学,他日能助我一臂之力。

个人水平有限,有问题欢迎各位大神批评指正!

  • 12
    点赞
  • 92
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值