1 eCAP 介绍
- 1脉冲捕获的基本原理
捕获单元模块(eCAP)能够捕获外部输入引脚的逻辑状态(电平的高或者低、 低电平翻转时的上升沿或下降沿),并利用内部定时器对外部事件或者引脚状态 变化进行处理。典型应用如下:
--电机测速。
--测量脉冲电平宽度。
--测量一系列脉冲占空比和周期。
--电流/电压传感器的 PWM 编码信号的解码。
捕获单元示意图如下:
控制器给每个捕获单元模块都分配了一个捕获引脚,在捕获引脚上输入待测 脉冲波形,捕获模块会捕获到指定捕获的逻辑状态,如上图中的下降沿,捕获单 元记录下定时器的时间,两个下降沿之间的时间差值就是脉冲周期即脉冲频率。 同理也可以捕获脉冲的上升沿,计算上升沿与下降沿之间的时间差值即可或得占 空比,因此捕获单元可以用来测量脉冲周期以及脉冲的宽度(占空比)。在一些 数字脉冲测速场合,如点击的常用测速方法之一,在电机某个固定位置通过光电 传感器发出一个脉冲,每周一个脉冲,两个脉冲之间的时间,就是电机的转速。 在一些精确控制场合中,一周当然不止发出一个脉冲,这取决与传感器(光电编 码器)的选型和性能。
- 2F28335 eCAP 介绍
F28335 内含有 6 组 eCAP 模块,每个 eCAP 除了具有输入捕获功能,还可通过 相关配置用作 PWM 输出功能。F28335 捕获模块的主要特征如下:
--150MHz 系统时钟的情况下,32 位的时基的时间分辨率为 6.67ns。
--4 组 32 位的时间标志寄存器。
--4 级捕获事件序列,可以灵活配置捕获事件边沿极性。
--4 级触发事件均可以产生中断。
--软件配置一次捕获可以最多得到 4 个捕获时间。
--可连续循环 4 级捕获。
--绝对时间捕获。
--不同模式的时间捕获。
--所有捕获都发生在一个输入引脚上。
--如果 eCAP 模块不作捕获使用,可以配置成一个单通道输出的 PWM 模式。 eCAP 模块中一个捕获通道完成一次捕获任务,需要以下关键资源:
--专用捕获输入引脚。
--32 位时基(计数器)。
--4*32 位时间标签捕获寄存器。
--4 级序列器,与外部 eCAP 引脚的上升/下降沿同步。
--4 个事件可独立配置边沿极性。
--输入捕获信号预定标(2~62)。
--一个 2 位的比较寄存器,一次触发后可以捕获 4 个时间标签事件。
--采用 4 级深度的循环缓冲器以进行连续捕获。
--4 个捕获事件中任意一个都可以产生中断。
1.3 F28335 捕获单元与 APWM 操作模式
(1)APWM 操作模式
如果 eCAP 模块不用作输入捕获,可以将它用来产生一个单通道的 PWM。计数 器工作在计数增模式,可以提供时基能产生不同占空比的 PWM。CAP1 与 CAP2 寄 存器作为主要的周期和比较寄存器,CAP3 与 CAP4 寄存器作为周期和比较寄存器 的影子寄存器,其原理框图如下:
(2)F28335 捕获操作模式
F28335 DSP 中 eCAP 的原理框图如下:
1.4 CAP 相关寄存器
CAP 所有寄存器及地址信息如下所示:
2 eCAP 配置步骤
前面介绍了非常多的理论知识,对于初学者来说可能有点懵,没关系,我们
可以先从软件层面来学习,先学会如何使用,再深入学习理论。接下来我们就来
学习如何配置 F28355 的 eCAP1,至于其他 eCAP 配置方法一样,只需修改数字即 可。具体步骤如下:
(1)使能 eCAP 外设时钟
要使用 eCAP 外设则需开启相应时钟,开启 eCAP 外设时钟代码如下:
EALLOW;
SysCtrlRegs.PCLKCR1.bit.ECAP1ENCLK = 1; // eCAP1
EDIS;
(2)初始化 GPIO 为 eCAP1 功能,即选择 GPIO 复用功能
eCAP1 的 GPIO 初始化函数如下:
void InitECap1Gpio(void);
本章实验例程内使用的 eCAP1 对应的是 GPIO24 脚
(3)eCAP 外设相关参数设置,包括捕捉模式、捕获边沿信号、捕获后计数
器是否清零、捕获中断等。
要想使用 eCAP 捕获输入信号,除了使能 eCAP 时钟和配置 GPIO 外,还需要
对其进行寄存器相关参数的设置。比如捕捉模式、捕获边沿信号、捕获后计数器
是否清零、捕获中断等。下面我们就以本章 eCAP 和初始化配置为例进行介绍,
我们开发板上使用的是 eCAP1。代码如下:
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 counteris stopped
// Configure peripheral registers
ECap1Regs.ECCTL2.bit.CONT_ONESHT = 1;// One-shot
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 = 1;// Difference operation
ECap1Regs.ECCTL1.bit.CTRRST2 = 1;// Difference operation
ECap1Regs.ECCTL1.bit.CTRRST3 = 1;// Difference operation
ECap1Regs.ECCTL1.bit.CTRRST4 = 1;// 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
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
// 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
上述代码是 eCAP1 的设置,如果你使用的是其他 eCAP,那么只需要修改数字
即可。本章例程开启了 eCAP1 的中断功能,而 eCAP1 它连接在 INT4.1,所以需要对它进行使能以及中断向量表的指定,这个在前面中断章节介绍过。
(4)编写中断函数。
通过前面的配置已使能了 eCAP1 的中断,当 eCAP1 连续捕获到 4 次边沿信号
时即进入中断,因此需要编写一个中断服务函数,函数名要与前面指定的中断向
量名一致,中断函数执行完后需要清除相关中断标志。
3 硬件设计
本实验使用到硬件资源如下:
(1)D1 指示灯
(2)ePWM5A
(3)eCAP1
4 软件设计
(1)eCAP_Capture_pwm
// Configure the start/end period for the timer
#define PWM3_TIMER_MIN 10
#define PWM3_TIMER_MAX 8000
// To keep track of which way the timer value is moving
#define EPWM_TIMER_UP 1
#define EPWM_TIMER_DOWN 0
void EPWM3_Init(Uint16 tbprd);
// Configure the start/end period for the timer
#define PWM5_TIMER_MIN 10
#define PWM5_TIMER_MAX 8000
// TBCTL (Time-Base Control)
//==========================
// CTRMODE bits
#define TB_COUNT_UP 0x0
#define TB_COUNT_DOWN 0x1
#define TB_COUNT_UPDOWN 0x2
#define TB_FREEZE 0x3
// PHSEN bit
#define TB_DISABLE 0x0
#define TB_ENABLE 0x1
// PRDLD bit
#define TB_SHADOW 0x0
#define TB_IMMEDIATE 0x1
// SYNCOSEL bits
#define TB_SYNC_IN 0x0
#define TB_CTR_ZERO 0x1
#define TB_CTR_CMPB 0x2
#define TB_SYNC_DISABLE 0x3
// HSPCLKDIV and CLKDIV bits
#define TB_DIV1 0x0
#define TB_DIV2 0x1
#define TB_DIV4 0x2
// PHSDIR bit
#define TB_DOWN 0x0
#define TB_UP 0x1
// CMPCTL (Compare Control)
//==========================
// LOADAMODE and LOADBMODE bits
#define CC_CTR_ZERO 0x0
#define CC_CTR_PRD 0x1
#define CC_CTR_ZERO_PRD 0x2
#define CC_LD_DISABLE 0x3
// SHDWAMODE and SHDWBMODE bits
#define CC_SHADOW 0x0
#define CC_IMMEDIATE 0x1
// AQCTLA and AQCTLB (Action Qualifier Control)
//=============================================
// ZRO, PRD, CAU, CAD, CBU, CBD bits
#define AQ_NO_ACTION 0x0
#define AQ_CLEAR 0x1
#define AQ_SET 0x2
#define AQ_TOGGLE 0x3
// DBCTL (Dead-Band Control)
//==========================
// OUT MODE bits
#define DB_DISABLE 0x0
#define DBA_ENABLE 0x1
#define DBB_ENABLE 0x2
#define DB_FULL_ENABLE 0x3
// POLSEL bits
#define DB_ACTV_HI 0x0
#define DB_ACTV_LOC 0x1
#define DB_ACTV_HIC 0x2
#define DB_ACTV_LO 0x3
// IN MODE
#define DBA_ALL 0x0
#define DBB_RED_DBA_FED 0x1
#define DBA_RED_DBB_FED 0x2
#define DBB_ALL 0x3
// CHPCTL (chopper control)
//==========================
// CHPEN bit
#define CHP_DISABLE 0x0
#define CHP_ENABLE 0x1
// CHPFREQ bits
#define CHP_DIV1 0x0
#define CHP_DIV2 0x1
#define CHP_DIV3 0x2
#define CHP_DIV4 0x3
#define CHP_DIV5 0x4
#define CHP_DIV6 0x5
#define CHP_DIV7 0x6
#define CHP_DIV8 0x7
// CHPDUTY bits
#define CHP1_8TH 0x0
#define CHP2_8TH 0x1
#define CHP3_8TH 0x2
#define CHP4_8TH 0x3
#define CHP5_8TH 0x4
#define CHP6_8TH 0x5
#define CHP7_8TH 0x6
// TZSEL (Trip Zone Select)
//==========================
// CBCn and OSHTn bits
#define TZ_DISABLE 0x0
#define TZ_ENABLE 0x1
// TZCTL (Trip Zone Control)
//==========================
// TZA and TZB bits
#define TZ_HIZ 0x0
#define TZ_FORCE_HI 0x1
#define TZ_FORCE_LO 0x2
#define TZ_NO_CHANGE 0x3
// ETSEL (Event Trigger Select)
//=============================
#define ET_CTR_ZERO 0x1
#define ET_CTR_PRD 0x2
#define ET_CTRU_CMPA 0x4
#define ET_CTRD_CMPA 0x5
#define ET_CTRU_CMPB 0x6
#define ET_CTRD_CMPB 0x7
// ETPS (Event Trigger Pre-scale)
//===============================
// INTPRD, SOCAPRD, SOCBPRD bits
#define ET_DISABLE 0x0
#define ET_1ST 0x1
#define ET_2ND 0x2
#define ET_3RD 0x3
//--------------------------------
// HRPWM (High Resolution PWM)
//================================
// HRCNFG
#define HR_Disable 0x0
#define HR_REP 0x1
#define HR_FEP 0x2
#define HR_BEP 0x3
#define HR_CMP 0x0
#define HR_PHS 0x1
#define HR_CTR_ZERO 0x0
#define HR_CTR_PRD 0x1
void InitECap1Gpio(void)
{
EALLOW;
/* Enable internal pull-up for the selected pins */
// Pull-ups can be enabled or disabled by the user.
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.
// GpioCtrlRegs.GPAPUD.bit.GPIO5 = 0; // Enable pull-up on GPIO5 (CAP1)
GpioCtrlRegs.GPAPUD.bit.GPIO24 = 0; // Enable pull-up on GPIO24 (CAP1)
// GpioCtrlRegs.GPBPUD.bit.GPIO34 = 0; // Enable pull-up on GPIO34 (CAP1)
// Inputs are synchronized to SYSCLKOUT by default.
// Comment out other unwanted lines.
// GpioCtrlRegs.GPAQSEL1.bit.GPIO5 = 0; // Synch to SYSCLKOUT GPIO5 (CAP1)
GpioCtrlRegs.GPAQSEL2.bit.GPIO24 = 0; // Synch to SYSCLKOUT GPIO24 (CAP1)
// GpioCtrlRegs.GPBQSEL1.bit.GPIO34 = 0; // Synch to SYSCLKOUT GPIO34 (CAP1)
/* Configure eCAP-1 pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be eCAP1 functional pins.
// Comment out other unwanted lines.
// GpioCtrlRegs.GPAMUX1.bit.GPIO5 = 3; // Configure GPIO5 as CAP1
GpioCtrlRegs.GPAMUX2.bit.GPIO24 = 1; // Configure GPIO24 as CAP1
// GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 1; // Configure GPIO24 as CAP1
EDIS;
}
void eCAP1_Init(void)
{
EALLOW;
SysCtrlRegs.PCLKCR1.bit.ECAP1ENCLK = 1; // eCAP1
EDIS;
InitECap1Gpio();
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 = 1; // One-shot
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 = 1; // Difference operation
ECap1Regs.ECCTL1.bit.CTRRST2 = 1; // Difference operation
ECap1Regs.ECCTL1.bit.CTRRST3 = 1; // Difference operation
ECap1Regs.ECCTL1.bit.CTRRST4 = 1; // 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
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
// 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
}
__interrupt void ecap1_isr(void)
{
// Cap input is syc'ed to SYSCLKOUT so there may be
// a +/- 1 cycle variation
if(ECap1Regs.CAP2 > EPwm5Regs.TBPRD*2+1 || ECap1Regs.CAP2 < EPwm5Regs.TBPRD*2-1)
{
Fail();
}
if(ECap1Regs.CAP3 > EPwm5Regs.TBPRD*2+1 || ECap1Regs.CAP3 < EPwm5Regs.TBPRD*2-1)
{
Fail();
}
if(ECap1Regs.CAP4 > EPwm5Regs.TBPRD*2+1 || ECap1Regs.CAP4 < EPwm5Regs.TBPRD*2-1)
{
Fail();
}
ECap1IntCount++;
if(EPwm5TimerDirection == EPWM_TIMER_UP)
{
if(EPwm5Regs.TBPRD < PWM5_TIMER_MAX)
{
EPwm5Regs.TBPRD++;
}
else
{
EPwm5TimerDirection = EPWM_TIMER_DOWN;
EPwm5Regs.TBPRD--;
}
}
else
{
if(EPwm5Regs.TBPRD > PWM5_TIMER_MIN)
{
EPwm5Regs.TBPRD--;
}
else
{
EPwm5TimerDirection = EPWM_TIMER_UP;
EPwm5Regs.TBPRD++;
}
}
ECap1PassCount++;
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;
}
void Fail()
{
__asm(" ESTOP0");
}
void main()
{
Uint16 i=0;
InitSysCtrl();
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
LED_Init();
TIM0_Init(150,200000);//200ms
UARTa_Init(4800);
EPWM5_Init(PWM5_TIMER_MIN);
eCAP1_Init();
while(1)
{
}
}
(2)eCAP_apwm
void InitECap1Gpio(void)
{
EALLOW;
/* Enable internal pull-up for the selected pins */
// Pull-ups can be enabled or disabled by the user.
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.
// GpioCtrlRegs.GPAPUD.bit.GPIO5 = 0; // Enable pull-up on GPIO5 (CAP1)
GpioCtrlRegs.GPAPUD.bit.GPIO24 = 0; // Enable pull-up on GPIO24 (CAP1)
// GpioCtrlRegs.GPBPUD.bit.GPIO34 = 0; // Enable pull-up on GPIO34 (CAP1)
// Inputs are synchronized to SYSCLKOUT by default.
// Comment out other unwanted lines.
// GpioCtrlRegs.GPAQSEL1.bit.GPIO5 = 0; // Synch to SYSCLKOUT GPIO5 (CAP1)
GpioCtrlRegs.GPAQSEL2.bit.GPIO24 = 0; // Synch to SYSCLKOUT GPIO24 (CAP1)
// GpioCtrlRegs.GPBQSEL1.bit.GPIO34 = 0; // Synch to SYSCLKOUT GPIO34 (CAP1)
/* Configure eCAP-1 pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be eCAP1 functional pins.
// Comment out other unwanted lines.
// GpioCtrlRegs.GPAMUX1.bit.GPIO5 = 3; // Configure GPIO5 as CAP1
GpioCtrlRegs.GPAMUX2.bit.GPIO24 = 1; // Configure GPIO24 as CAP1
// GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 1; // Configure GPIO24 as CAP1
EDIS;
}
void eCAP1_APWM_Init(void)
{
EALLOW;
SysCtrlRegs.PCLKCR1.bit.ECAP1ENCLK = 1; // eCAP1
EDIS;
InitECap1Gpio();
// Setup APWM mode on CAP1, set period and compare registers
ECap1Regs.ECCTL2.bit.CAP_APWM = 1; // Enable APWM mode
ECap1Regs.CAP1 = 0x01312D00; // Set Period value
ECap1Regs.CAP2 = 0x00989680; // Set Compare value
ECap1Regs.ECCLR.all = 0x0FF; // Clear pending interrupts
ECap1Regs.ECEINT.bit.CTR_EQ_CMP = 1; // enable Compare Equal Int
// Start counters
ECap1Regs.ECCTL2.bit.TSCTRSTOP = 1;
}
// Global variables
Uint16 direction = 0;
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
Uint16 i=0;
InitSysCtrl();
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
LED_Init();
TIM0_Init(150,200000);//200ms
UARTa_Init(4800);
eCAP1_APWM_Init();
while(1)
{
// set next duty cycle to 50%
ECap1Regs.CAP4 = ECap1Regs.CAP1 >> 1;
// vary freq between 7.5 Hz and 15 Hz (for 150MHz SYSCLKOUT) 5 Hz and 10 Hz (for 100 MHz SYSCLKOUT)
if(ECap1Regs.CAP1 >= 0x01312D00)
{
direction = 0;
}
else if (ECap1Regs.CAP1 <= 0x00989680)
{
direction = 1;
}
if(direction == 0)
{
ECap1Regs.CAP3 = ECap1Regs.CAP1 - 500000;
}
else
{
ECap1Regs.CAP3 = ECap1Regs.CAP1 + 500000;
}
}
}
(3)eQEP_freqcal
FREQCAL freq=FREQCAL_DEFAULTS;
interrupt void prdTick(void);
#if (CPU_FRQ_150MHZ)
#define CPU_CLK 150e6
#endif
#if (CPU_FRQ_100MHZ)
#define CPU_CLK 100e6
#endif
#define PWM_CLK 5e3 // If diff freq. desired, change freq here.
#define SP CPU_CLK/(2*PWM_CLK)
#define TBCTLVAL 0x200E // Up-down cnt, timebase = SYSCLKOUT
void EPwm1Setup(void)
{
InitEPwm1Gpio();
EPwm1Regs.TBSTS.all=0;
EPwm1Regs.TBPHS.half.TBPHS=0;
EPwm1Regs.TBCTR=0;
EPwm1Regs.CMPCTL.all=0x50; // Immediate mode for CMPA and CMPB
EPwm1Regs.CMPA.half.CMPA =SP/2;
EPwm1Regs.CMPB=0;
EPwm1Regs.AQCTLA.all=0x60; // EPWMxA = 1 when CTR=CMPA and counter inc
// EPWMxA = 0 when CTR=CMPA and counter dec
EPwm1Regs.AQCTLB.all=0;
EPwm1Regs.AQSFRC.all=0;
EPwm1Regs.AQCSFRC.all=0;
EPwm1Regs.DBCTL.all=0xb; // EPWMxB is inverted
EPwm1Regs.DBRED=0;
EPwm1Regs.DBFED=0;
EPwm1Regs.TZSEL.all=0;
EPwm1Regs.TZCTL.all=0;
EPwm1Regs.TZEINT.all=0;
EPwm1Regs.TZFLG.all=0;
EPwm1Regs.TZCLR.all=0;
EPwm1Regs.TZFRC.all=0;
EPwm1Regs.ETSEL.all=9; // Interrupt when TBCTR = 0x0000
EPwm1Regs.ETPS.all=1; // Interrupt on first event
EPwm1Regs.ETFLG.all=0;
EPwm1Regs.ETCLR.all=0;
EPwm1Regs.ETFRC.all=0;
EPwm1Regs.PCCTL.all=0;
EPwm1Regs.TBCTL.all=0x0010+TBCTLVAL; // Enable Timer
EPwm1Regs.TBPRD=SP;
EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.EPWM1_INT= &prdTick;
EDIS;
IER |= M_INT3;
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
}
void EQEP1_Init(void)
{
EALLOW; // This is needed to write to EALLOW protected registers
SysCtrlRegs.PCLKCR1.bit.EQEP1ENCLK = 1; // eQEP1
EDIS;
InitEQep1Gpio();
EPwm1Setup();
freq.init(); // Initializes eQEP for frequency calculation in
// FREQCAL_Init(void)function in Example_EPwmSetup.c
}
interrupt void prdTick(void) // Interrupts once per ePWM period
{
freq.calc(&freq); // Checks for event and calculates frequency in FREQCAL_Calc(FREQCAL *p)
// function in Example_EPwmSetup.c
// Acknowledge this interrupt to receive more interrupts from group 1
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
EPwm1Regs.ETCLR.bit.INT=1;
}
void main()
{
Uint16 i=0;
InitSysCtrl();
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
LED_Init();
TIM0_Init(150,200000);//200ms
UARTa_Init(4800);
EQEP1_Init();
while(1)
{
}
}
(4)eQEP_pos_speed
/*-----------------------------------------------------------------------------
Define the structure of the POSSPEED Object
-----------------------------------------------------------------------------*/
typedef struct {int theta_elec; // Output: Motor Electrical angle (Q15)
int theta_mech; // Output: Motor Mechanical Angle (Q15)
int DirectionQep; // Output: Motor rotation direction (Q0)
int QEP_cnt_idx; // Variable: Encoder counter index (Q0)
int theta_raw; // Variable: Raw angle from Timer 2 (Q0)
int mech_scaler; // Parameter: 0.9999/total count, total count = 4000 (Q26)
int pole_pairs; // Parameter: Number of pole pairs (Q0)
int cal_angle; // Parameter: Raw angular offset between encoder and phase a (Q0)
int index_sync_flag; // Output: Index sync status (Q0)
Uint32 SpeedScaler; // Parameter : Scaler converting 1/N cycles to a GLOBAL_Q speed (Q0) - independently with global Q
_iq Speed_pr; // Output : speed in per-unit
Uint32 BaseRpm; // Parameter : Scaler converting GLOBAL_Q speed to rpm (Q0) speed - independently with global Q
int32 SpeedRpm_pr; // Output : speed in r.p.m. (Q0) - independently with global Q
_iq oldpos; // Input: Electrical angle (pu)
_iq Speed_fr; // Output : speed in per-unit
int32 SpeedRpm_fr; // Output : Speed in rpm (Q0) - independently with global Q
void (*init)(); // Pointer to the init funcion
void (*calc)(); // Pointer to the calc funtion
} POSSPEED;
POSSPEED qep_posspeed=POSSPEED_DEFAULTS;
Uint16 Interrupt_Count = 0;
interrupt void prdTick(void);
#if (CPU_FRQ_150MHZ)
#define CPU_CLK 150e6
#endif
#if (CPU_FRQ_100MHZ)
#define CPU_CLK 100e6
#endif
#define PWM_CLK 5e3 // 5kHz (300rpm) EPWM1 frequency. Freq. can be changed here
#define SP CPU_CLK/(2*PWM_CLK)
#define TBCTLVAL 0x200E // up-down count, timebase=SYSCLKOUT
void EPwm1Setup(void)
{
InitEPwm1Gpio();
EALLOW;
GpioCtrlRegs.GPADIR.bit.GPIO4 = 1; // GPIO4 as output simulates Index signal
GpioDataRegs.GPACLEAR.bit.GPIO4 = 1; // Normally low
EDIS;
EPwm1Regs.TBSTS.all=0;
EPwm1Regs.TBPHS.half.TBPHS =0;
EPwm1Regs.TBCTR=0;
EPwm1Regs.CMPCTL.all=0x50; // immediate mode for CMPA and CMPB
EPwm1Regs.CMPA.half.CMPA=SP/2;
EPwm1Regs.CMPB=0;
EPwm1Regs.AQCTLA.all=0x60; // CTR=CMPA when inc->EPWM1A=1, when dec->EPWM1A=0
EPwm1Regs.AQCTLB.all=0x09; // CTR=PRD ->EPWM1B=1, CTR=0 ->EPWM1B=0
EPwm1Regs.AQSFRC.all=0;
EPwm1Regs.AQCSFRC.all=0;
EPwm1Regs.TZSEL.all=0;
EPwm1Regs.TZCTL.all=0;
EPwm1Regs.TZEINT.all=0;
EPwm1Regs.TZFLG.all=0;
EPwm1Regs.TZCLR.all=0;
EPwm1Regs.TZFRC.all=0;
EPwm1Regs.ETSEL.all=0x0A; // Interrupt on PRD
EPwm1Regs.ETPS.all=1;
EPwm1Regs.ETFLG.all=0;
EPwm1Regs.ETCLR.all=0;
EPwm1Regs.ETFRC.all=0;
EPwm1Regs.PCCTL.all=0;
EPwm1Regs.TBCTL.all=0x0010+TBCTLVAL; // Enable Timer
EPwm1Regs.TBPRD=SP;
EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.EPWM1_INT= &prdTick;
EDIS;
IER |= M_INT3;
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
}
void InitEQep1Gpio(void)
{
EALLOW;
/* Enable internal pull-up for the selected pins */
// Pull-ups can be enabled or disabled by the user.
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.
// GpioCtrlRegs.GPAPUD.bit.GPIO20 = 0; // Enable pull-up on GPIO20 (EQEP1A)
// GpioCtrlRegs.GPAPUD.bit.GPIO21 = 0; // Enable pull-up on GPIO21 (EQEP1B)
// GpioCtrlRegs.GPAPUD.bit.GPIO22 = 0; // Enable pull-up on GPIO22 (EQEP1S)
// GpioCtrlRegs.GPAPUD.bit.GPIO23 = 0; // Enable pull-up on GPIO23 (EQEP1I)
GpioCtrlRegs.GPBPUD.bit.GPIO50 = 0; // Enable pull-up on GPIO50 (EQEP1A)
GpioCtrlRegs.GPBPUD.bit.GPIO51 = 0; // Enable pull-up on GPIO51 (EQEP1B)
GpioCtrlRegs.GPBPUD.bit.GPIO52 = 0; // Enable pull-up on GPIO52 (EQEP1S)
GpioCtrlRegs.GPBPUD.bit.GPIO53 = 0; // Enable pull-up on GPIO53 (EQEP1I)
// Inputs are synchronized to SYSCLKOUT by default.
// Comment out other unwanted lines.
// GpioCtrlRegs.GPAQSEL2.bit.GPIO20 = 0; // Sync to SYSCLKOUT GPIO20 (EQEP1A)
// GpioCtrlRegs.GPAQSEL2.bit.GPIO21 = 0; // Sync to SYSCLKOUT GPIO21 (EQEP1B)
// GpioCtrlRegs.GPAQSEL2.bit.GPIO22 = 0; // Sync to SYSCLKOUT GPIO22 (EQEP1S)
// GpioCtrlRegs.GPAQSEL2.bit.GPIO23 = 0; // Sync to SYSCLKOUT GPIO23 (EQEP1I)
GpioCtrlRegs.GPBQSEL2.bit.GPIO50 = 0; // Sync to SYSCLKOUT GPIO50 (EQEP1A)
GpioCtrlRegs.GPBQSEL2.bit.GPIO51 = 0; // Sync to SYSCLKOUT GPIO51 (EQEP1B)
GpioCtrlRegs.GPBQSEL2.bit.GPIO52 = 0; // Sync to SYSCLKOUT GPIO52 (EQEP1S)
GpioCtrlRegs.GPBQSEL2.bit.GPIO53 = 0; // Sync to SYSCLKOUT GPIO53 (EQEP1I)
/* Configure eQEP-1 pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be eQEP1 functional pins.
// Comment out other unwanted lines.
// GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 1; // Configure GPIO20 as EQEP1A
// GpioCtrlRegs.GPAMUX2.bit.GPIO21 = 1; // Configure GPIO21 as EQEP1B
// GpioCtrlRegs.GPAMUX2.bit.GPIO22 = 1; // Configure GPIO22 as EQEP1S
// GpioCtrlRegs.GPAMUX2.bit.GPIO23 = 1; // Configure GPIO23 as EQEP1I
GpioCtrlRegs.GPBMUX2.bit.GPIO50 = 1; // Configure GPIO50 as EQEP1A
GpioCtrlRegs.GPBMUX2.bit.GPIO51 = 1; // Configure GPIO51 as EQEP1B
GpioCtrlRegs.GPBMUX2.bit.GPIO52 = 1; // Configure GPIO52 as EQEP1S
GpioCtrlRegs.GPBMUX2.bit.GPIO53 = 1; // Configure GPIO53 as EQEP1I
EDIS;
}
void InitEPwm1Gpio(void)
{
EALLOW;
/* Enable internal pull-up for the selected pins */
// Pull-ups can be enabled or disabled by the user.
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.
GpioCtrlRegs.GPAPUD.bit.GPIO0 = 0; // Enable pull-up on GPIO0 (EPWM1A)
GpioCtrlRegs.GPAPUD.bit.GPIO1 = 0; // Enable pull-up on GPIO1 (EPWM1B)
/* Configure ePWM-1 pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be ePWM1 functional pins.
// Comment out other unwanted lines.
GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; // Configure GPIO0 as EPWM1A
GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1; // Configure GPIO1 as EPWM1B
EDIS;
}
void EPwm1Setup(void)
{
InitEPwm1Gpio();
EALLOW;
GpioCtrlRegs.GPADIR.bit.GPIO4 = 1; // GPIO4 as output simulates Index signal
GpioDataRegs.GPACLEAR.bit.GPIO4 = 1; // Normally low
EDIS;
EPwm1Regs.TBSTS.all=0;
EPwm1Regs.TBPHS.half.TBPHS =0;
EPwm1Regs.TBCTR=0;
EPwm1Regs.CMPCTL.all=0x50; // immediate mode for CMPA and CMPB
EPwm1Regs.CMPA.half.CMPA=SP/2;
EPwm1Regs.CMPB=0;
EPwm1Regs.AQCTLA.all=0x60; // CTR=CMPA when inc->EPWM1A=1, when dec->EPWM1A=0
EPwm1Regs.AQCTLB.all=0x09; // CTR=PRD ->EPWM1B=1, CTR=0 ->EPWM1B=0
EPwm1Regs.AQSFRC.all=0;
EPwm1Regs.AQCSFRC.all=0;
EPwm1Regs.TZSEL.all=0;
EPwm1Regs.TZCTL.all=0;
EPwm1Regs.TZEINT.all=0;
EPwm1Regs.TZFLG.all=0;
EPwm1Regs.TZCLR.all=0;
EPwm1Regs.TZFRC.all=0;
EPwm1Regs.ETSEL.all=0x0A; // Interrupt on PRD
EPwm1Regs.ETPS.all=1;
EPwm1Regs.ETFLG.all=0;
EPwm1Regs.ETCLR.all=0;
EPwm1Regs.ETFRC.all=0;
EPwm1Regs.PCCTL.all=0;
EPwm1Regs.TBCTL.all=0x0010+TBCTLVAL; // Enable Timer
EPwm1Regs.TBPRD=SP;
EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.EPWM1_INT= &prdTick;
EDIS;
IER |= M_INT3;
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
}
void EQEP1_Init(void)
{
EALLOW; // This is needed to write to EALLOW protected registers
SysCtrlRegs.PCLKCR1.bit.EQEP1ENCLK = 1; // eQEP1
EDIS;
InitEQep1Gpio();
EPwm1Setup();
qep_posspeed.init(&qep_posspeed);
}
interrupt void prdTick(void) // EPWM1 Interrupts once every 4 QCLK counts (one period)
{
Uint16 i;
// Position and Speed measurement
qep_posspeed.calc(&qep_posspeed);
// Control loop code for position control & Speed contol
Interrupt_Count++;
if (Interrupt_Count==1000) // Every 1000 interrupts(4000 QCLK counts or 1 rev.)
{
EALLOW;
GpioDataRegs.GPASET.bit.GPIO4 = 1; // Pulse Index signal (1 pulse/rev.)
for (i=0; i<700; i++){
}
GpioDataRegs.GPACLEAR.bit.GPIO4 = 1;
Interrupt_Count = 0; // Reset count
EDIS;
}
// Acknowledge this interrupt to receive more interrupts from group 1
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
EPwm1Regs.ETCLR.bit.INT=1;
}
void main()
{
Uint16 i=0;
InitSysCtrl();
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
LED_Init();
TIM0_Init(150,200000);//200ms
UARTa_Init(4800);
EQEP1_Init();
while(1)
{
}
}
版权声明:本文为CSDN博主「时光话」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u012616827/article/details/122182224
1 eCAP 介绍
- 1脉冲捕获的基本原理
捕获单元模块(eCAP)能够捕获外部输入引脚的逻辑状态(电平的高或者低、 低电平翻转时的上升沿或下降沿),并利用内部定时器对外部事件或者引脚状态 变化进行处理。典型应用如下:
--电机测速。
--测量脉冲电平宽度。
--测量一系列脉冲占空比和周期。
--电流/电压传感器的 PWM 编码信号的解码。
捕获单元示意图如下:
控制器给每个捕获单元模块都分配了一个捕获引脚,在捕获引脚上输入待测 脉冲波形,捕获模块会捕获到指定捕获的逻辑状态,如上图中的下降沿,捕获单 元记录下定时器的时间,两个下降沿之间的时间差值就是脉冲周期即脉冲频率。 同理也可以捕获脉冲的上升沿,计算上升沿与下降沿之间的时间差值即可或得占 空比,因此捕获单元可以用来测量脉冲周期以及脉冲的宽度(占空比)。在一些 数字脉冲测速场合,如点击的常用测速方法之一,在电机某个固定位置通过光电 传感器发出一个脉冲,每周一个脉冲,两个脉冲之间的时间,就是电机的转速。 在一些精确控制场合中,一周当然不止发出一个脉冲,这取决与传感器(光电编 码器)的选型和性能。
- 2F28335 eCAP 介绍
F28335 内含有 6 组 eCAP 模块,每个 eCAP 除了具有输入捕获功能,还可通过 相关配置用作 PWM 输出功能。F28335 捕获模块的主要特征如下:
--150MHz 系统时钟的情况下,32 位的时基的时间分辨率为 6.67ns。
--4 组 32 位的时间标志寄存器。
--4 级捕获事件序列,可以灵活配置捕获事件边沿极性。
--4 级触发事件均可以产生中断。
--软件配置一次捕获可以最多得到 4 个捕获时间。
--可连续循环 4 级捕获。
--绝对时间捕获。
--不同模式的时间捕获。
--所有捕获都发生在一个输入引脚上。
--如果 eCAP 模块不作捕获使用,可以配置成一个单通道输出的 PWM 模式。 eCAP 模块中一个捕获通道完成一次捕获任务,需要以下关键资源:
--专用捕获输入引脚。
--32 位时基(计数器)。
--4*32 位时间标签捕获寄存器。
--4 级序列器,与外部 eCAP 引脚的上升/下降沿同步。
--4 个事件可独立配置边沿极性。
--输入捕获信号预定标(2~62)。
--一个 2 位的比较寄存器,一次触发后可以捕获 4 个时间标签事件。
--采用 4 级深度的循环缓冲器以进行连续捕获。
--4 个捕获事件中任意一个都可以产生中断。
1.3 F28335 捕获单元与 APWM 操作模式
(1)APWM 操作模式
如果 eCAP 模块不用作输入捕获,可以将它用来产生一个单通道的 PWM。计数 器工作在计数增模式,可以提供时基能产生不同占空比的 PWM。CAP1 与 CAP2 寄 存器作为主要的周期和比较寄存器,CAP3 与 CAP4 寄存器作为周期和比较寄存器 的影子寄存器,其原理框图如下:
(2)F28335 捕获操作模式
F28335 DSP 中 eCAP 的原理框图如下:
1.4 CAP 相关寄存器
CAP 所有寄存器及地址信息如下所示:
2 eCAP 配置步骤
前面介绍了非常多的理论知识,对于初学者来说可能有点懵,没关系,我们
可以先从软件层面来学习,先学会如何使用,再深入学习理论。接下来我们就来
学习如何配置 F28355 的 eCAP1,至于其他 eCAP 配置方法一样,只需修改数字即 可。具体步骤如下:
(1)使能 eCAP 外设时钟
要使用 eCAP 外设则需开启相应时钟,开启 eCAP 外设时钟代码如下:
EALLOW;
SysCtrlRegs.PCLKCR1.bit.ECAP1ENCLK = 1; // eCAP1
EDIS;
(2)初始化 GPIO 为 eCAP1 功能,即选择 GPIO 复用功能
eCAP1 的 GPIO 初始化函数如下:
void InitECap1Gpio(void);
本章实验例程内使用的 eCAP1 对应的是 GPIO24 脚
(3)eCAP 外设相关参数设置,包括捕捉模式、捕获边沿信号、捕获后计数
器是否清零、捕获中断等。
要想使用 eCAP 捕获输入信号,除了使能 eCAP 时钟和配置 GPIO 外,还需要
对其进行寄存器相关参数的设置。比如捕捉模式、捕获边沿信号、捕获后计数器
是否清零、捕获中断等。下面我们就以本章 eCAP 和初始化配置为例进行介绍,
我们开发板上使用的是 eCAP1。代码如下:
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 counteris stopped
// Configure peripheral registers
ECap1Regs.ECCTL2.bit.CONT_ONESHT = 1;// One-shot
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 = 1;// Difference operation
ECap1Regs.ECCTL1.bit.CTRRST2 = 1;// Difference operation
ECap1Regs.ECCTL1.bit.CTRRST3 = 1;// Difference operation
ECap1Regs.ECCTL1.bit.CTRRST4 = 1;// 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
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
// 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
上述代码是 eCAP1 的设置,如果你使用的是其他 eCAP,那么只需要修改数字
即可。本章例程开启了 eCAP1 的中断功能,而 eCAP1 它连接在 INT4.1,所以需要对它进行使能以及中断向量表的指定,这个在前面中断章节介绍过。
(4)编写中断函数。
通过前面的配置已使能了 eCAP1 的中断,当 eCAP1 连续捕获到 4 次边沿信号
时即进入中断,因此需要编写一个中断服务函数,函数名要与前面指定的中断向
量名一致,中断函数执行完后需要清除相关中断标志。
3 硬件设计
本实验使用到硬件资源如下:
(1)D1 指示灯
(2)ePWM5A
(3)eCAP1
4 软件设计
(1)eCAP_Capture_pwm
// Configure the start/end period for the timer
#define PWM3_TIMER_MIN 10
#define PWM3_TIMER_MAX 8000
// To keep track of which way the timer value is moving
#define EPWM_TIMER_UP 1
#define EPWM_TIMER_DOWN 0
void EPWM3_Init(Uint16 tbprd);
// Configure the start/end period for the timer
#define PWM5_TIMER_MIN 10
#define PWM5_TIMER_MAX 8000
// TBCTL (Time-Base Control)
//==========================
// CTRMODE bits
#define TB_COUNT_UP 0x0
#define TB_COUNT_DOWN 0x1
#define TB_COUNT_UPDOWN 0x2
#define TB_FREEZE 0x3
// PHSEN bit
#define TB_DISABLE 0x0
#define TB_ENABLE 0x1
// PRDLD bit
#define TB_SHADOW 0x0
#define TB_IMMEDIATE 0x1
// SYNCOSEL bits
#define TB_SYNC_IN 0x0
#define TB_CTR_ZERO 0x1
#define TB_CTR_CMPB 0x2
#define TB_SYNC_DISABLE 0x3
// HSPCLKDIV and CLKDIV bits
#define TB_DIV1 0x0
#define TB_DIV2 0x1
#define TB_DIV4 0x2
// PHSDIR bit
#define TB_DOWN 0x0
#define TB_UP 0x1
// CMPCTL (Compare Control)
//==========================
// LOADAMODE and LOADBMODE bits
#define CC_CTR_ZERO 0x0
#define CC_CTR_PRD 0x1
#define CC_CTR_ZERO_PRD 0x2
#define CC_LD_DISABLE 0x3
// SHDWAMODE and SHDWBMODE bits
#define CC_SHADOW 0x0
#define CC_IMMEDIATE 0x1
// AQCTLA and AQCTLB (Action Qualifier Control)
//=============================================
// ZRO, PRD, CAU, CAD, CBU, CBD bits
#define AQ_NO_ACTION 0x0
#define AQ_CLEAR 0x1
#define AQ_SET 0x2
#define AQ_TOGGLE 0x3
// DBCTL (Dead-Band Control)
//==========================
// OUT MODE bits
#define DB_DISABLE 0x0
#define DBA_ENABLE 0x1
#define DBB_ENABLE 0x2
#define DB_FULL_ENABLE 0x3
// POLSEL bits
#define DB_ACTV_HI 0x0
#define DB_ACTV_LOC 0x1
#define DB_ACTV_HIC 0x2
#define DB_ACTV_LO 0x3
// IN MODE
#define DBA_ALL 0x0
#define DBB_RED_DBA_FED 0x1
#define DBA_RED_DBB_FED 0x2
#define DBB_ALL 0x3
// CHPCTL (chopper control)
//==========================
// CHPEN bit
#define CHP_DISABLE 0x0
#define CHP_ENABLE 0x1
// CHPFREQ bits
#define CHP_DIV1 0x0
#define CHP_DIV2 0x1
#define CHP_DIV3 0x2
#define CHP_DIV4 0x3
#define CHP_DIV5 0x4
#define CHP_DIV6 0x5
#define CHP_DIV7 0x6
#define CHP_DIV8 0x7
// CHPDUTY bits
#define CHP1_8TH 0x0
#define CHP2_8TH 0x1
#define CHP3_8TH 0x2
#define CHP4_8TH 0x3
#define CHP5_8TH 0x4
#define CHP6_8TH 0x5
#define CHP7_8TH 0x6
// TZSEL (Trip Zone Select)
//==========================
// CBCn and OSHTn bits
#define TZ_DISABLE 0x0
#define TZ_ENABLE 0x1
// TZCTL (Trip Zone Control)
//==========================
// TZA and TZB bits
#define TZ_HIZ 0x0
#define TZ_FORCE_HI 0x1
#define TZ_FORCE_LO 0x2
#define TZ_NO_CHANGE 0x3
// ETSEL (Event Trigger Select)
//=============================
#define ET_CTR_ZERO 0x1
#define ET_CTR_PRD 0x2
#define ET_CTRU_CMPA 0x4
#define ET_CTRD_CMPA 0x5
#define ET_CTRU_CMPB 0x6
#define ET_CTRD_CMPB 0x7
// ETPS (Event Trigger Pre-scale)
//===============================
// INTPRD, SOCAPRD, SOCBPRD bits
#define ET_DISABLE 0x0
#define ET_1ST 0x1
#define ET_2ND 0x2
#define ET_3RD 0x3
//--------------------------------
// HRPWM (High Resolution PWM)
//================================
// HRCNFG
#define HR_Disable 0x0
#define HR_REP 0x1
#define HR_FEP 0x2
#define HR_BEP 0x3
#define HR_CMP 0x0
#define HR_PHS 0x1
#define HR_CTR_ZERO 0x0
#define HR_CTR_PRD 0x1
void InitECap1Gpio(void)
{
EALLOW;
/* Enable internal pull-up for the selected pins */
// Pull-ups can be enabled or disabled by the user.
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.
// GpioCtrlRegs.GPAPUD.bit.GPIO5 = 0; // Enable pull-up on GPIO5 (CAP1)
GpioCtrlRegs.GPAPUD.bit.GPIO24 = 0; // Enable pull-up on GPIO24 (CAP1)
// GpioCtrlRegs.GPBPUD.bit.GPIO34 = 0; // Enable pull-up on GPIO34 (CAP1)
// Inputs are synchronized to SYSCLKOUT by default.
// Comment out other unwanted lines.
// GpioCtrlRegs.GPAQSEL1.bit.GPIO5 = 0; // Synch to SYSCLKOUT GPIO5 (CAP1)
GpioCtrlRegs.GPAQSEL2.bit.GPIO24 = 0; // Synch to SYSCLKOUT GPIO24 (CAP1)
// GpioCtrlRegs.GPBQSEL1.bit.GPIO34 = 0; // Synch to SYSCLKOUT GPIO34 (CAP1)
/* Configure eCAP-1 pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be eCAP1 functional pins.
// Comment out other unwanted lines.
// GpioCtrlRegs.GPAMUX1.bit.GPIO5 = 3; // Configure GPIO5 as CAP1
GpioCtrlRegs.GPAMUX2.bit.GPIO24 = 1; // Configure GPIO24 as CAP1
// GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 1; // Configure GPIO24 as CAP1
EDIS;
}
void eCAP1_Init(void)
{
EALLOW;
SysCtrlRegs.PCLKCR1.bit.ECAP1ENCLK = 1; // eCAP1
EDIS;
InitECap1Gpio();
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 = 1; // One-shot
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 = 1; // Difference operation
ECap1Regs.ECCTL1.bit.CTRRST2 = 1; // Difference operation
ECap1Regs.ECCTL1.bit.CTRRST3 = 1; // Difference operation
ECap1Regs.ECCTL1.bit.CTRRST4 = 1; // 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
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
// 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
}
__interrupt void ecap1_isr(void)
{
// Cap input is syc'ed to SYSCLKOUT so there may be
// a +/- 1 cycle variation
if(ECap1Regs.CAP2 > EPwm5Regs.TBPRD*2+1 || ECap1Regs.CAP2 < EPwm5Regs.TBPRD*2-1)
{
Fail();
}
if(ECap1Regs.CAP3 > EPwm5Regs.TBPRD*2+1 || ECap1Regs.CAP3 < EPwm5Regs.TBPRD*2-1)
{
Fail();
}
if(ECap1Regs.CAP4 > EPwm5Regs.TBPRD*2+1 || ECap1Regs.CAP4 < EPwm5Regs.TBPRD*2-1)
{
Fail();
}
ECap1IntCount++;
if(EPwm5TimerDirection == EPWM_TIMER_UP)
{
if(EPwm5Regs.TBPRD < PWM5_TIMER_MAX)
{
EPwm5Regs.TBPRD++;
}
else
{
EPwm5TimerDirection = EPWM_TIMER_DOWN;
EPwm5Regs.TBPRD--;
}
}
else
{
if(EPwm5Regs.TBPRD > PWM5_TIMER_MIN)
{
EPwm5Regs.TBPRD--;
}
else
{
EPwm5TimerDirection = EPWM_TIMER_UP;
EPwm5Regs.TBPRD++;
}
}
ECap1PassCount++;
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;
}
void Fail()
{
__asm(" ESTOP0");
}
void main()
{
Uint16 i=0;
InitSysCtrl();
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
LED_Init();
TIM0_Init(150,200000);//200ms
UARTa_Init(4800);
EPWM5_Init(PWM5_TIMER_MIN);
eCAP1_Init();
while(1)
{
}
}
(2)eCAP_apwm
void InitECap1Gpio(void)
{
EALLOW;
/* Enable internal pull-up for the selected pins */
// Pull-ups can be enabled or disabled by the user.
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.
// GpioCtrlRegs.GPAPUD.bit.GPIO5 = 0; // Enable pull-up on GPIO5 (CAP1)
GpioCtrlRegs.GPAPUD.bit.GPIO24 = 0; // Enable pull-up on GPIO24 (CAP1)
// GpioCtrlRegs.GPBPUD.bit.GPIO34 = 0; // Enable pull-up on GPIO34 (CAP1)
// Inputs are synchronized to SYSCLKOUT by default.
// Comment out other unwanted lines.
// GpioCtrlRegs.GPAQSEL1.bit.GPIO5 = 0; // Synch to SYSCLKOUT GPIO5 (CAP1)
GpioCtrlRegs.GPAQSEL2.bit.GPIO24 = 0; // Synch to SYSCLKOUT GPIO24 (CAP1)
// GpioCtrlRegs.GPBQSEL1.bit.GPIO34 = 0; // Synch to SYSCLKOUT GPIO34 (CAP1)
/* Configure eCAP-1 pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be eCAP1 functional pins.
// Comment out other unwanted lines.
// GpioCtrlRegs.GPAMUX1.bit.GPIO5 = 3; // Configure GPIO5 as CAP1
GpioCtrlRegs.GPAMUX2.bit.GPIO24 = 1; // Configure GPIO24 as CAP1
// GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 1; // Configure GPIO24 as CAP1
EDIS;
}
void eCAP1_APWM_Init(void)
{
EALLOW;
SysCtrlRegs.PCLKCR1.bit.ECAP1ENCLK = 1; // eCAP1
EDIS;
InitECap1Gpio();
// Setup APWM mode on CAP1, set period and compare registers
ECap1Regs.ECCTL2.bit.CAP_APWM = 1; // Enable APWM mode
ECap1Regs.CAP1 = 0x01312D00; // Set Period value
ECap1Regs.CAP2 = 0x00989680; // Set Compare value
ECap1Regs.ECCLR.all = 0x0FF; // Clear pending interrupts
ECap1Regs.ECEINT.bit.CTR_EQ_CMP = 1; // enable Compare Equal Int
// Start counters
ECap1Regs.ECCTL2.bit.TSCTRSTOP = 1;
}
// Global variables
Uint16 direction = 0;
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
Uint16 i=0;
InitSysCtrl();
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
LED_Init();
TIM0_Init(150,200000);//200ms
UARTa_Init(4800);
eCAP1_APWM_Init();
while(1)
{
// set next duty cycle to 50%
ECap1Regs.CAP4 = ECap1Regs.CAP1 >> 1;
// vary freq between 7.5 Hz and 15 Hz (for 150MHz SYSCLKOUT) 5 Hz and 10 Hz (for 100 MHz SYSCLKOUT)
if(ECap1Regs.CAP1 >= 0x01312D00)
{
direction = 0;
}
else if (ECap1Regs.CAP1 <= 0x00989680)
{
direction = 1;
}
if(direction == 0)
{
ECap1Regs.CAP3 = ECap1Regs.CAP1 - 500000;
}
else
{
ECap1Regs.CAP3 = ECap1Regs.CAP1 + 500000;
}
}
}
(3)eQEP_freqcal
FREQCAL freq=FREQCAL_DEFAULTS;
interrupt void prdTick(void);
#if (CPU_FRQ_150MHZ)
#define CPU_CLK 150e6
#endif
#if (CPU_FRQ_100MHZ)
#define CPU_CLK 100e6
#endif
#define PWM_CLK 5e3 // If diff freq. desired, change freq here.
#define SP CPU_CLK/(2*PWM_CLK)
#define TBCTLVAL 0x200E // Up-down cnt, timebase = SYSCLKOUT
void EPwm1Setup(void)
{
InitEPwm1Gpio();
EPwm1Regs.TBSTS.all=0;
EPwm1Regs.TBPHS.half.TBPHS=0;
EPwm1Regs.TBCTR=0;
EPwm1Regs.CMPCTL.all=0x50; // Immediate mode for CMPA and CMPB
EPwm1Regs.CMPA.half.CMPA =SP/2;
EPwm1Regs.CMPB=0;
EPwm1Regs.AQCTLA.all=0x60; // EPWMxA = 1 when CTR=CMPA and counter inc
// EPWMxA = 0 when CTR=CMPA and counter dec
EPwm1Regs.AQCTLB.all=0;
EPwm1Regs.AQSFRC.all=0;
EPwm1Regs.AQCSFRC.all=0;
EPwm1Regs.DBCTL.all=0xb; // EPWMxB is inverted
EPwm1Regs.DBRED=0;
EPwm1Regs.DBFED=0;
EPwm1Regs.TZSEL.all=0;
EPwm1Regs.TZCTL.all=0;
EPwm1Regs.TZEINT.all=0;
EPwm1Regs.TZFLG.all=0;
EPwm1Regs.TZCLR.all=0;
EPwm1Regs.TZFRC.all=0;
EPwm1Regs.ETSEL.all=9; // Interrupt when TBCTR = 0x0000
EPwm1Regs.ETPS.all=1; // Interrupt on first event
EPwm1Regs.ETFLG.all=0;
EPwm1Regs.ETCLR.all=0;
EPwm1Regs.ETFRC.all=0;
EPwm1Regs.PCCTL.all=0;
EPwm1Regs.TBCTL.all=0x0010+TBCTLVAL; // Enable Timer
EPwm1Regs.TBPRD=SP;
EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.EPWM1_INT= &prdTick;
EDIS;
IER |= M_INT3;
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
}
void EQEP1_Init(void)
{
EALLOW; // This is needed to write to EALLOW protected registers
SysCtrlRegs.PCLKCR1.bit.EQEP1ENCLK = 1; // eQEP1
EDIS;
InitEQep1Gpio();
EPwm1Setup();
freq.init(); // Initializes eQEP for frequency calculation in
// FREQCAL_Init(void)function in Example_EPwmSetup.c
}
interrupt void prdTick(void) // Interrupts once per ePWM period
{
freq.calc(&freq); // Checks for event and calculates frequency in FREQCAL_Calc(FREQCAL *p)
// function in Example_EPwmSetup.c
// Acknowledge this interrupt to receive more interrupts from group 1
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
EPwm1Regs.ETCLR.bit.INT=1;
}
void main()
{
Uint16 i=0;
InitSysCtrl();
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
LED_Init();
TIM0_Init(150,200000);//200ms
UARTa_Init(4800);
EQEP1_Init();
while(1)
{
}
}
(4)eQEP_pos_speed
/*-----------------------------------------------------------------------------
Define the structure of the POSSPEED Object
-----------------------------------------------------------------------------*/
typedef struct {int theta_elec; // Output: Motor Electrical angle (Q15)
int theta_mech; // Output: Motor Mechanical Angle (Q15)
int DirectionQep; // Output: Motor rotation direction (Q0)
int QEP_cnt_idx; // Variable: Encoder counter index (Q0)
int theta_raw; // Variable: Raw angle from Timer 2 (Q0)
int mech_scaler; // Parameter: 0.9999/total count, total count = 4000 (Q26)
int pole_pairs; // Parameter: Number of pole pairs (Q0)
int cal_angle; // Parameter: Raw angular offset between encoder and phase a (Q0)
int index_sync_flag; // Output: Index sync status (Q0)
Uint32 SpeedScaler; // Parameter : Scaler converting 1/N cycles to a GLOBAL_Q speed (Q0) - independently with global Q
_iq Speed_pr; // Output : speed in per-unit
Uint32 BaseRpm; // Parameter : Scaler converting GLOBAL_Q speed to rpm (Q0) speed - independently with global Q
int32 SpeedRpm_pr; // Output : speed in r.p.m. (Q0) - independently with global Q
_iq oldpos; // Input: Electrical angle (pu)
_iq Speed_fr; // Output : speed in per-unit
int32 SpeedRpm_fr; // Output : Speed in rpm (Q0) - independently with global Q
void (*init)(); // Pointer to the init funcion
void (*calc)(); // Pointer to the calc funtion
} POSSPEED;
POSSPEED qep_posspeed=POSSPEED_DEFAULTS;
Uint16 Interrupt_Count = 0;
interrupt void prdTick(void);
#if (CPU_FRQ_150MHZ)
#define CPU_CLK 150e6
#endif
#if (CPU_FRQ_100MHZ)
#define CPU_CLK 100e6
#endif
#define PWM_CLK 5e3 // 5kHz (300rpm) EPWM1 frequency. Freq. can be changed here
#define SP CPU_CLK/(2*PWM_CLK)
#define TBCTLVAL 0x200E // up-down count, timebase=SYSCLKOUT
void EPwm1Setup(void)
{
InitEPwm1Gpio();
EALLOW;
GpioCtrlRegs.GPADIR.bit.GPIO4 = 1; // GPIO4 as output simulates Index signal
GpioDataRegs.GPACLEAR.bit.GPIO4 = 1; // Normally low
EDIS;
EPwm1Regs.TBSTS.all=0;
EPwm1Regs.TBPHS.half.TBPHS =0;
EPwm1Regs.TBCTR=0;
EPwm1Regs.CMPCTL.all=0x50; // immediate mode for CMPA and CMPB
EPwm1Regs.CMPA.half.CMPA=SP/2;
EPwm1Regs.CMPB=0;
EPwm1Regs.AQCTLA.all=0x60; // CTR=CMPA when inc->EPWM1A=1, when dec->EPWM1A=0
EPwm1Regs.AQCTLB.all=0x09; // CTR=PRD ->EPWM1B=1, CTR=0 ->EPWM1B=0
EPwm1Regs.AQSFRC.all=0;
EPwm1Regs.AQCSFRC.all=0;
EPwm1Regs.TZSEL.all=0;
EPwm1Regs.TZCTL.all=0;
EPwm1Regs.TZEINT.all=0;
EPwm1Regs.TZFLG.all=0;
EPwm1Regs.TZCLR.all=0;
EPwm1Regs.TZFRC.all=0;
EPwm1Regs.ETSEL.all=0x0A; // Interrupt on PRD
EPwm1Regs.ETPS.all=1;
EPwm1Regs.ETFLG.all=0;
EPwm1Regs.ETCLR.all=0;
EPwm1Regs.ETFRC.all=0;
EPwm1Regs.PCCTL.all=0;
EPwm1Regs.TBCTL.all=0x0010+TBCTLVAL; // Enable Timer
EPwm1Regs.TBPRD=SP;
EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.EPWM1_INT= &prdTick;
EDIS;
IER |= M_INT3;
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
}
void InitEQep1Gpio(void)
{
EALLOW;
/* Enable internal pull-up for the selected pins */
// Pull-ups can be enabled or disabled by the user.
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.
// GpioCtrlRegs.GPAPUD.bit.GPIO20 = 0; // Enable pull-up on GPIO20 (EQEP1A)
// GpioCtrlRegs.GPAPUD.bit.GPIO21 = 0; // Enable pull-up on GPIO21 (EQEP1B)
// GpioCtrlRegs.GPAPUD.bit.GPIO22 = 0; // Enable pull-up on GPIO22 (EQEP1S)
// GpioCtrlRegs.GPAPUD.bit.GPIO23 = 0; // Enable pull-up on GPIO23 (EQEP1I)
GpioCtrlRegs.GPBPUD.bit.GPIO50 = 0; // Enable pull-up on GPIO50 (EQEP1A)
GpioCtrlRegs.GPBPUD.bit.GPIO51 = 0; // Enable pull-up on GPIO51 (EQEP1B)
GpioCtrlRegs.GPBPUD.bit.GPIO52 = 0; // Enable pull-up on GPIO52 (EQEP1S)
GpioCtrlRegs.GPBPUD.bit.GPIO53 = 0; // Enable pull-up on GPIO53 (EQEP1I)
// Inputs are synchronized to SYSCLKOUT by default.
// Comment out other unwanted lines.
// GpioCtrlRegs.GPAQSEL2.bit.GPIO20 = 0; // Sync to SYSCLKOUT GPIO20 (EQEP1A)
// GpioCtrlRegs.GPAQSEL2.bit.GPIO21 = 0; // Sync to SYSCLKOUT GPIO21 (EQEP1B)
// GpioCtrlRegs.GPAQSEL2.bit.GPIO22 = 0; // Sync to SYSCLKOUT GPIO22 (EQEP1S)
// GpioCtrlRegs.GPAQSEL2.bit.GPIO23 = 0; // Sync to SYSCLKOUT GPIO23 (EQEP1I)
GpioCtrlRegs.GPBQSEL2.bit.GPIO50 = 0; // Sync to SYSCLKOUT GPIO50 (EQEP1A)
GpioCtrlRegs.GPBQSEL2.bit.GPIO51 = 0; // Sync to SYSCLKOUT GPIO51 (EQEP1B)
GpioCtrlRegs.GPBQSEL2.bit.GPIO52 = 0; // Sync to SYSCLKOUT GPIO52 (EQEP1S)
GpioCtrlRegs.GPBQSEL2.bit.GPIO53 = 0; // Sync to SYSCLKOUT GPIO53 (EQEP1I)
/* Configure eQEP-1 pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be eQEP1 functional pins.
// Comment out other unwanted lines.
// GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 1; // Configure GPIO20 as EQEP1A
// GpioCtrlRegs.GPAMUX2.bit.GPIO21 = 1; // Configure GPIO21 as EQEP1B
// GpioCtrlRegs.GPAMUX2.bit.GPIO22 = 1; // Configure GPIO22 as EQEP1S
// GpioCtrlRegs.GPAMUX2.bit.GPIO23 = 1; // Configure GPIO23 as EQEP1I
GpioCtrlRegs.GPBMUX2.bit.GPIO50 = 1; // Configure GPIO50 as EQEP1A
GpioCtrlRegs.GPBMUX2.bit.GPIO51 = 1; // Configure GPIO51 as EQEP1B
GpioCtrlRegs.GPBMUX2.bit.GPIO52 = 1; // Configure GPIO52 as EQEP1S
GpioCtrlRegs.GPBMUX2.bit.GPIO53 = 1; // Configure GPIO53 as EQEP1I
EDIS;
}
void InitEPwm1Gpio(void)
{
EALLOW;
/* Enable internal pull-up for the selected pins */
// Pull-ups can be enabled or disabled by the user.
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.
GpioCtrlRegs.GPAPUD.bit.GPIO0 = 0; // Enable pull-up on GPIO0 (EPWM1A)
GpioCtrlRegs.GPAPUD.bit.GPIO1 = 0; // Enable pull-up on GPIO1 (EPWM1B)
/* Configure ePWM-1 pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be ePWM1 functional pins.
// Comment out other unwanted lines.
GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; // Configure GPIO0 as EPWM1A
GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1; // Configure GPIO1 as EPWM1B
EDIS;
}
void EPwm1Setup(void)
{
InitEPwm1Gpio();
EALLOW;
GpioCtrlRegs.GPADIR.bit.GPIO4 = 1; // GPIO4 as output simulates Index signal
GpioDataRegs.GPACLEAR.bit.GPIO4 = 1; // Normally low
EDIS;
EPwm1Regs.TBSTS.all=0;
EPwm1Regs.TBPHS.half.TBPHS =0;
EPwm1Regs.TBCTR=0;
EPwm1Regs.CMPCTL.all=0x50; // immediate mode for CMPA and CMPB
EPwm1Regs.CMPA.half.CMPA=SP/2;
EPwm1Regs.CMPB=0;
EPwm1Regs.AQCTLA.all=0x60; // CTR=CMPA when inc->EPWM1A=1, when dec->EPWM1A=0
EPwm1Regs.AQCTLB.all=0x09; // CTR=PRD ->EPWM1B=1, CTR=0 ->EPWM1B=0
EPwm1Regs.AQSFRC.all=0;
EPwm1Regs.AQCSFRC.all=0;
EPwm1Regs.TZSEL.all=0;
EPwm1Regs.TZCTL.all=0;
EPwm1Regs.TZEINT.all=0;
EPwm1Regs.TZFLG.all=0;
EPwm1Regs.TZCLR.all=0;
EPwm1Regs.TZFRC.all=0;
EPwm1Regs.ETSEL.all=0x0A; // Interrupt on PRD
EPwm1Regs.ETPS.all=1;
EPwm1Regs.ETFLG.all=0;
EPwm1Regs.ETCLR.all=0;
EPwm1Regs.ETFRC.all=0;
EPwm1Regs.PCCTL.all=0;
EPwm1Regs.TBCTL.all=0x0010+TBCTLVAL; // Enable Timer
EPwm1Regs.TBPRD=SP;
EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.EPWM1_INT= &prdTick;
EDIS;
IER |= M_INT3;
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
}
void EQEP1_Init(void)
{
EALLOW; // This is needed to write to EALLOW protected registers
SysCtrlRegs.PCLKCR1.bit.EQEP1ENCLK = 1; // eQEP1
EDIS;
InitEQep1Gpio();
EPwm1Setup();
qep_posspeed.init(&qep_posspeed);
}
interrupt void prdTick(void) // EPWM1 Interrupts once every 4 QCLK counts (one period)
{
Uint16 i;
// Position and Speed measurement
qep_posspeed.calc(&qep_posspeed);
// Control loop code for position control & Speed contol
Interrupt_Count++;
if (Interrupt_Count==1000) // Every 1000 interrupts(4000 QCLK counts or 1 rev.)
{
EALLOW;
GpioDataRegs.GPASET.bit.GPIO4 = 1; // Pulse Index signal (1 pulse/rev.)
for (i=0; i<700; i++){
}
GpioDataRegs.GPACLEAR.bit.GPIO4 = 1;
Interrupt_Count = 0; // Reset count
EDIS;
}
// Acknowledge this interrupt to receive more interrupts from group 1
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
EPwm1Regs.ETCLR.bit.INT=1;
}
void main()
{
Uint16 i=0;
InitSysCtrl();
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
LED_Init();
TIM0_Init(150,200000);//200ms
UARTa_Init(4800);
EQEP1_Init();
while(1)
{
}
}
版权声明:本文为CSDN博主「时光话」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u012616827/article/details/122182224
暂无评论