注意:在捕获方波时,方波电压范围要在0~3.3V,电压高于3.3V会烧坏芯片,低于0V会捕获不到。
捕获原理:通过设置eCAP模块的寄存器,对引脚电平进行监测,分别记录下方波上升沿,下降沿的时间,在进行计算,得出所捕获的频率、占空比。
连续/单次模式:2位Mod4计数器对相应的边沿捕获事件递增计数(CEVT1~4);Mod4计数器循环计数(0→1→2→3→0),直至停止工作。
在单次模式下,eCAP模块等待N(1~4)个捕获事件的发生,N值为停止寄存器的值。达到N值后,Mod4计数器和CAP寄存器的值将被冻结。如果向CAP控制寄存器ECCTL2中的单次加载REARM位写1后,Mod4计数器恢复作用,同时如果将ECCTL1中CAPLDEN置1,那么CAP1~4会再次加载新值。
在连续模式下,Mod4计数器持续工作(0→1→2→3→0),捕获值在一个环形缓冲里按顺序不断写入有CAP1~4。
CAP寄存器配置程序:
void InitECapture()
{
ECap1Regs.ECEINT.all = 0x0000; // Disable all capture interrupts
ECap1Regs.ECCLR.all = 0xFFFF; // Clear all CAP interrupt flags
ECap1Regs.ECCTL1.bit.CAPLDEN = 0; // Disable CAP1-CAP4 register loads
ECap1Regs.ECCTL2.bit.TSCTRSTOP = 0; // Make sure the counter is stopped
// Configure peripheral registers
ECap1Regs.ECCTL2.bit.CONT_ONESHT = 0; // 0:One-shot mode 1:Continuous mode
ECap1Regs.ECCTL2.bit.STOP_WRAP = 3; // Stop at 4 events
ECap1Regs.ECCTL1.bit.CAP1POL = 1; // Falling edge
ECap1Regs.ECCTL1.bit.CAP2POL = 0; // Rising edge
ECap1Regs.ECCTL1.bit.CAP3POL = 1; // Falling edge
ECap1Regs.ECCTL1.bit.CAP4POL = 0; // Rising edge
ECap1Regs.ECCTL1.bit.CTRRST1 = 0; // Difference operation
ECap1Regs.ECCTL1.bit.CTRRST2 = 0; // Difference operation
ECap1Regs.ECCTL1.bit.CTRRST3 = 0; // Difference operation
ECap1Regs.ECCTL1.bit.CTRRST4 = 0; // Difference operation
ECap1Regs.ECCTL2.bit.SYNCI_EN = 1; // Enable sync in
ECap1Regs.ECCTL2.bit.SYNCO_SEL = 0; // Pass through
ECap1Regs.ECCTL1.bit.CAPLDEN = 1; // Enable capture units
ECap1Regs.ECCTL2.bit.TSCTRSTOP = 1; // Start Counter
ECap1Regs.ECCTL2.bit.REARM = 1; // arm one-shot
ECap1Regs.ECCTL1.bit.CAPLDEN = 1; // Enable CAP1-CAP4 register loads
ECap1Regs.ECEINT.bit.CEVT4 = 1; // 4 events = interrupt
}
配置各个寄存器含义:
ECCTL1 | |
CAPLDEN | 在捕获事件中使能CAP1~4寄存器的加载; 0:禁止加载;1:使能加载 |
CAPxPOL | 捕捉沿选择 0:上升沿捕捉;1:下降沿捕捉 |
CTRRSTx | CAPx事件中重置计数器 0:不重置;1:重置 |
CEVTx | 1:在第x个捕捉事件中产生中断 |
ECCTL2 | |
TSCTRSTOP | 计数器停止位控制; 0:停止;1:计数 |
CON_ONESHT | 模式选择; 0:连续模式;1:单次模式 |
STOP_WRAP | 单次/连续模式下的停止值,CAP1-0/CAP2-1/CAP3-2/CAP4-3 单次模式下:在CAPx的捕捉事件发生后产生停止信号 连续模式下:在CAPx的捕捉事件发生后计数器正常运行 |
当程序运行四个事件后发生中断,在中断中计算捕获的频率、占空比,程序如下:
__interrupt void ecap1_isr(void)
{
// Cap input is syc'ed to SYSCLKOUT so there may be
// a +/- 1 cycle variation
t1 = ECap1Regs.CAP1;
t2 = ECap1Regs.CAP2;
t3 = ECap1Regs.CAP3;
t4 = ECap1Regs.CAP4;
T1 = t4 - t2; // period time
T2 = t3 - t2; // duty time
Frequency = (90000000 / T1); //frequency
Duty = 100 * T2/T1; // duty
ECap1Regs.ECCLR.bit.CEVT4 = 1;
ECap1Regs.ECCLR.bit.INT = 1;
ECap1Regs.ECCTL2.bit.REARM = 1;
// Acknowledge this interrupt to receive more interrupts from group 4
PieCtrlRegs.PIEACK.all = PIEACK_GROUP4;
}
主程序如下:
#include "DSP28x_Project.h" // Device Headerfile and Examples Include File
// Prototype statements for functions found within this file.
__interrupt void ecap1_isr(void);
void InitECapture(void);
// Global variables used in this example
Uint32 t1, t2, t3, t4;
float32 T1, T2;
float32 Frequency, Duty;
void main(void)
{
// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the F2806x_SysCtrl.c file.
InitSysCtrl();
// Step 2. Initalize GPIO:
// This example function is found in the F2806x_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
// InitGpio(); // Skipped for this example
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 F2806x_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 F2806x_DefaultIsr.c.
// This function is found in F2806x_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 F2806x_InitPeripherals.c
// InitPeripherals(); // Not required for this example
InitECapture();
// Step 5. User specific code, enable interrupts:
T1 = 0;
T2 = 0;
t1 = 0;
t2 = 0;
t3 = 0;
t4 = 0;
Frequency = 0;
Duty = 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");
}
}
捕获到频率产生误差,可在中断程序计算中进行修正。