一、01Demo-Epwm_Time_Interrupt
1、主函数
void main()
{
DINT;//关闭所有中断
SysCtrlInit(); //初始化时钟
InitPieCtrl();//复位中断向量
InitPieVectTable();//初始化中断向量表
//将程序复制至RAM内存中运行-此程序可以不需要
memcpy((Uint16 *)&RamfuncsRunStart,(Uint16 *)&RamfuncsLoadStart,(unsigned long)&RamfuncsLoadSize);
InitFlash();
GPIOInit();
EPWM1_Init(15000);
for(;;)
{
DELAY_US(500000);//500mS
//GpioDataRegs.GPBTOGGLE.bit.GPIO39 = 1;//绿灯亮
GpioDataRegs.GPASET.bit.GPIO22 = 1;//黄灯亮
GpioDataRegs.GPBSET.bit.GPIO33 = 1;//红灯亮
}
}
2、EPWM配置部分
void EPWM1_Init(Uint16 tbprd)
{
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Disable TBCLK within the ePWM
SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1; // ePWM1
EDIS;
// 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.EPWM1_INT = &epwm1_timer_isr;
EDIS; // This is needed to disable write to EALLOW protected registers
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Stop all the TB clocks
EDIS;
// Setup Sync
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // Pass through
// Allow each timer to be sync'ed
EPwm1Regs.TBCTL.bit.PHSEN = TB_ENABLE;
EPwm1Regs.TBPHS.half.TBPHS = 0;
EPwm1Regs.TBPRD = tbprd;
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up
EPwm1Regs.TBCTL.bit.HSPCLKDIV=TB_DIV1;
EPwm1Regs.TBCTL.bit.CLKDIV=TB_DIV1;
EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event
EPwm1Regs.ETSEL.bit.INTEN = 1; // Enable INT
EPwm1Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on 1st event
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Start all the timers synced
EDIS;
// Enable CPU INT3 which is connected to EPWM1-6 INT:
IER |= M_INT3;
// Enable EPWM INTn in the PIE: Group 3 interrupt 1-6
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
// Enable global Interrupts and higher priority real-time debug events:
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
}
(1)时钟初始化
关闭时钟基准,开启pwm时钟。
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1; // ePWM1
TBCLKSYNC :对应PCLKCR0;
ePWM模块时间基准时钟(TBCLK)同步允许用户全局同步所有启用的ePWM模块到时间基准时钟(TBCLK):
- 0:每个启用的ePWM模块内的TBCLK(时间基准时钟)被停止。(默认值)。但是,如果在PCLKCR1寄存器中设置了ePWM时钟使能位,则即使TBCLKSYNC为0,ePWM模块仍将由SYSCLKOUT提供时钟。
- 1:所有启用的ePWM模块时钟在第一个上升沿对齐的同时启动。对于完全同步的TBCLK,每个ePWM模块的TBCTL寄存器中的分频器位必须设置为相同的值。启用ePWM时钟的正确程序如下:
• 在PCLKCR1寄存器中启用ePWM模块时钟。
• 将TBCLKSYNC设置为0。
• 配置分频器值和ePWM模式。
• 将TBCLKSYNC设置为1。
EPWM1ENCLK:对应PCLKCR1
(2)epwm波中断
PieVectTable.EPWM1_INT = &epwm1_timer_isr;
(3)模块设置
EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.EPWM1_INT = &epwm1_timer_isr;
EDIS; // This is needed to disable write to EALLOW protected registers
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Stop all the TB clocks
EDIS;
// Setup Sync
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // Pass through
// Allow each timer to be sync'ed
EPwm1Regs.TBCTL.bit.PHSEN = TB_ENABLE;
EPwm1Regs.TBPHS.half.TBPHS = 0;
EPwm1Regs.TBPRD = tbprd;
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up
EPwm1Regs.TBCTL.bit.HSPCLKDIV=TB_DIV1;
EPwm1Regs.TBCTL.bit.CLKDIV=TB_DIV1;
EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event
EPwm1Regs.ETSEL.bit.INTEN = 1; // Enable INT
EPwm1Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on 1st event
TB模块进行时间周期与频率设置:
EPwm1Regs.TBCTL.bit.SYNCOSEL = 0x0;
EPwm1Regs.TBCTL.bit.PHSEN = 0x1;
SYNCOSEL位:同步输出选择。这些位选择EPWMxSYNCO信号的来源。
- 00:EPWMxSYNC。
- 01:CTR = 0:时间基准计数器等于零(TBCTR = 0x0000)。
- 10:CTR = CMPB:时间基准计数器等于计数-比较B(TBCTR = CMPB)。
- 11:禁用EPWMxSYNCO信号。
EPwmSYNCO信号可以用于同步其他模块或设备。当SYNCOSEL位为0时,TBCTR为零(起始状态)时,会生成一个EPwmSYNC信号,并且该信号会在TBCTR到达计数器上限时告诉其他模块它必须更新其状态。
PHSEN 位 :计数器寄存器从相位寄存器中启用加载;
- 0:不要从时间基准相位寄存器(TBPHS)加载时间基准计数器(TBCTR)寄存器;
- 1:当发生EPWMxSYNCI输入信号或由SWFSYNC位强制进行软件同步时,将时间基准计数器从相位寄存器中加载。
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up
EPwm1Regs.TBCTL.bit.HSPCLKDIV=TB_DIV1;
EPwm1Regs.TBCTL.bit.CLKDIV=TB_DIV1;
CTRMODE位:时间基准计数器模式通常只在配置期间设置,不在正常操作中改变。如果更改计数器的模式,则更改将在下一个TBCLK边沿生效,并且当前计数器值应从模式更改之前的值增加或减少。这些位按以下方式设置计数器的时间基准模式:
00 上计数模式
01 下计数模式
10 上下计数模式
11 停止计数器操作(复位时默认)
HSPCLKDIV:这些位决定时间基准时钟预分频值的一部分。
TBCLK = SYSCLKOUT / (HSPCLKDIV × CLKDIV)
这个除法器模拟了在TMS320x281x系统中Event Manager (EV) 外设中使用的HSPCLK。
000 /1
001 /2 (复位时的默认值)
010 /4
011 /6
100 /8
101 /10
110 /12
111 /14
CLKDIV:这些位决定时间基准时钟预分频值的一部分。
TBCLK = SYSCLKOUT / (HSPCLKDIV × CLKDIV)
000 /1 (复位时的默认值)
001 /2
010 /4
011 /8
100 /16
101 /32
110 /64
111 /128
EPwm1Regs.TBPHS.half.TBPHS = 0;
TBPHS.half.TBPHS,这些位设置所选ePWM相对于提供同步输入信号的时间基准计数器的相位。
• 如果TBCTL [PHSEN] = 0,则忽略同步事件,时间基准计数器不加载相位。
• 如果TBCTL [PHSEN] = 1,则当发生同步事件时,时间基准计数器(TBCTR)将被加载相位(TBPHS)。同步事件可以由输入同步信号(EPWMxSYNCI)或软件强制同步引发。
此处设置加载相位为0.
EPwm1Regs.TBPRD = tbprd;
设置计数周期数字。
EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event
EPwm1Regs.ETSEL.bit.INTEN = 1; // Enable INT
ETSEL事件触发选择寄存器及触发子模块的寄存器。
INTEN:启用ePWM中断(EPWMx_INT)发生生成
0 禁用EPWMx_INT生成
1 启用EPWMx_INT生成
INTSEL:ePWM中断(EPWMx_INT)选择选项
000 保留
001 启用事件时间基准计数器等于零。(TBCTR = 0x0000)
010 启用事件时间基准计数器等于周期(TBCTR = TBPRD)
011 保留
100 当计时器递增时,启用事件时间基准计数器等于CMPA。
101 当计时器递减时,启用事件时间基准计数器等于CMPA。
110 当计时器递增时,启用事件时间基准计数器等于CMPB。
111 当计时器递减时,启用事件时间基准计数器等于CMPB。
此处设计INTSEL=0x1;
EPwm1Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on 1st event
// Enable CPU INT3 which is connected to EPWM1-6 INT:
IER |= M_INT3;
// Enable EPWM INTn in the PIE: Group 3 interrupt 1-6
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
PIEIER3>INT3,使能中断向量。
3、EPWM波中断检测
这部分主要是通过亮灯来进行检测,epwm波中断。
interrupt void epwm1_timer_isr(void)
{
static Uint16 cnt=0;
cnt++;
if(cnt==3000)
{
cnt=0;
GpioDataRegs.GPBTOGGLE.bit.GPIO39 = 1;
}
// Clear INT flag for this timer
EPwm1Regs.ETCLR.bit.INT = 1;
// Acknowledge this interrupt to receive more interrupts from group 3
PieCtrlRegs.PIEACK.bit.ACK3 = 1;
}
二、02Demo-ePWM_Up_AQ
void main()
{
int i=0;
unsigned char fx=0;
InitSysCtrl();
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
// LED_Init();
EPWM6_Init(500);
while(1)
{
if(fx==0)
{
i++;
if(i==300)
{
fx=1;
}
}
else
{
i--;
if(i==0)
{
fx=0;
}
}
EPwm6A_SetCompare(i); //i值最大可以取499,因为ARR最大值是499.
EPwm6B_SetCompare(300-i); //i值最大可以取499,因为ARR最大值是499.
DELAY_US(10*1000);
}
}
void EPWM6_Init(Uint16 tbprd)
{
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Disable TBCLK within the ePWM
SysCtrlRegs.PCLKCR1.bit.EPWM6ENCLK = 1; // ePWM6
EDIS;
InitEPwm6Gpio();
// Setup Sync
EPwm6Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE; // Pass through
// Allow each timer to be sync'ed
EPwm6Regs.TBCTL.bit.PHSEN = TB_DISABLE;
EPwm6Regs.TBPHS.half.TBPHS = 0;
EPwm6Regs.TBCTR = 0x0000; // Clear counter
EPwm6Regs.TBPRD = tbprd;
EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up
EPwm6Regs.TBCTL.bit.HSPCLKDIV=TB_DIV1;
EPwm6Regs.TBCTL.bit.CLKDIV=TB_DIV1;
// Setup shadow register load on ZERO
EPwm6Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm6Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm6Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm6Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
// Set Compare values
EPwm6Regs.CMPA.half.CMPA = 0; // Set compare A value
EPwm6Regs.CMPB = 0; // Set Compare B value
// Set actions
EPwm6Regs.AQCTLA.bit.ZRO = AQ_CLEAR; // Set PWM1A on Zero
EPwm6Regs.AQCTLA.bit.CAU = AQ_SET; // Clear PWM1A on event A, up count
EPwm6Regs.AQCTLB.bit.ZRO = AQ_CLEAR; // Set PWM1B on Zero
EPwm6Regs.AQCTLB.bit.CBU = AQ_SET; // Clear PWM1B on event B, up count
EPwm6Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event
EPwm6Regs.ETSEL.bit.INTEN = 1; // Enable INT
EPwm6Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on 1st event
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Start all the timers synced
EDIS;
}
void EPwm6A_SetCompare(Uint16 val)
{
EPwm6Regs.CMPA.half.CMPA = val; //设置占空比
}
void EPwm6B_SetCompare(Uint16 val)
{
EPwm6Regs.CMPB = val; //设置占空比
}
三、03Demo-PWM_updowm_AQ
void main()
{
int i=0;
InitSysCtrl();
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
LED_Init();
TIM0_Init(150,200000);//200ms
EPWM1_Init(15000);
while(1)
{
EPwm1A_SetCompare(7500);
}
}
void EPWM1_Init(Uint16 tbprd)
{
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Disable TBCLK within the ePWM
SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1; // ePWM1
EDIS;
InitEPwm1Gpio();
// 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.EPWM1_INT = &epwm1_isr;
EDIS; // This is needed to disable write to EALLOW protected registers
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Stop all the TB clocks
EDIS;
// Setup Sync
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE; // Pass through
// Allow each timer to be sync'ed
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;
EPwm1Regs.TBPHS.half.TBPHS = 0;
EPwm1Regs.TBCTR = 0x0000; // Clear counter
EPwm1Regs.TBPRD = tbprd;
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
EPwm1Regs.TBCTL.bit.HSPCLKDIV=TB_DIV1;
EPwm1Regs.TBCTL.bit.CLKDIV=TB_DIV1;
// Setup shadow register load on ZERO
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
// Set Compare values
EPwm1Regs.CMPA.half.CMPA = 0; // Set compare A value
EPwm1Regs.CMPB = 0; // Set Compare B value
// Set actions
EPwm1Regs.AQCTLA.bit.ZRO = AQ_CLEAR; // Set PWM1A on Zero
EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; // Clear PWM1A on event A, up count
EPwm1Regs.AQCTLB.bit.ZRO = AQ_SET; // Set PWM1B on Zero
EPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR; // Clear PWM1B on event B, up count
EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event
EPwm1Regs.ETSEL.bit.INTEN = 1; // Enable INT
EPwm1Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on 1st event
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Start all the timers synced
EDIS;
// Enable CPU INT3 which is connected to EPWM1-3 INT:
IER |= M_INT3;
// Enable EPWM INTn in the PIE: Group 3 interrupt 1-3
PieCtrlRegs.PIEIER3.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 epwm1_isr(void)
{
static Uint16 cnt=0;
cnt++;
if(cnt==5000)
{
cnt=0;
LED3_TOGGLE;
}
// Clear INT flag for this timer
EPwm1Regs.ETCLR.bit.INT = 1;
// Acknowledge this interrupt to receive more interrupts from group 3
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
}
void EPwm1A_SetCompare(Uint16 val)
{
EPwm1Regs.CMPA.half.CMPA = val; //设置占空比
}
void EPwm1B_SetCompare(Uint16 val)
{
EPwm1Regs.CMPB = val; //设置占空比
}
四、04Demo-PWM_deadband
void main()
{
int i=0;
InitSysCtrl();
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
LED_Init();
TIM0_Init(150,200000);//200ms
EPWM1_Init(15000);
while(1)
{
EPwm1A_SetCompare(7500);
}
}
interrupt void epwm1_isr(void);
void EPWM1_Init(Uint16 tbprd)
{
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Disable TBCLK within the ePWM
SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1; // ePWM1
EDIS;
InitEPwm1Gpio();
// 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.EPWM1_INT = &epwm1_isr;
EDIS; // This is needed to disable write to EALLOW protected registers
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Stop all the TB clocks
EDIS;
// Setup Sync
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE; // Pass through
// Allow each timer to be sync'ed
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;
EPwm1Regs.TBPHS.half.TBPHS = 0;
EPwm1Regs.TBCTR = 0x0000; // Clear counter
EPwm1Regs.TBPRD = tbprd;
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;
EPwm1Regs.TBCTL.bit.HSPCLKDIV=TB_DIV1;
EPwm1Regs.TBCTL.bit.CLKDIV=TB_DIV1;
// Setup shadow register load on ZERO
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
// Set Compare values
EPwm1Regs.CMPA.half.CMPA = 0; // Set compare A value
EPwm1Regs.CMPB = 0; // Set Compare B value
// Set actions
EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; // Set PWM1A on Zero
EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Clear PWM1A on event A, up count
EPwm1Regs.AQCTLB.bit.ZRO = AQ_CLEAR; // Set PWM1B on Zero
EPwm1Regs.AQCTLB.bit.CBU = AQ_SET; // Clear PWM1B on event B, up count
// Active Low PWMs - Setup Deadband
EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_LO;
EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL;
EPwm1Regs.DBRED = 1000;
EPwm1Regs.DBFED = 0;
EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event
EPwm1Regs.ETSEL.bit.INTEN = 1; // Enable INT
EPwm1Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on 1st event
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Start all the timers synced
EDIS;
// Enable CPU INT3 which is connected to EPWM1-3 INT:
IER |= M_INT3;
// Enable EPWM INTn in the PIE: Group 3 interrupt 1-3
PieCtrlRegs.PIEIER3.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 epwm1_isr(void)
{
static Uint16 cnt=0;
cnt++;
if(cnt==5000)
{
cnt=0;
LED3_TOGGLE;
}
// Clear INT flag for this timer
EPwm1Regs.ETCLR.bit.INT = 1;
// Acknowledge this interrupt to receive more interrupts from group 3
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
}
五、05Demo-PWM_trip_zone
void main()
{
int i=0;
InitSysCtrl();
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
LED_Init();
TIM0_Init(150,200000);//200ms
EPWM1_Init(15000);
while(1)
{
EPwm1A_SetCompare(7500);
}
}
interrupt void epwm1_tzint_isr(void);
void EPWM1_Init(Uint16 tbprd)
{
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Disable TBCLK within the ePWM
SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1; // ePWM1
EDIS;
InitEPwm1Gpio();
InitTzGpio();
//以下3个IO口设置为输出,作为列扫描
EALLOW;
//初始化行1的GPIO48
GpioCtrlRegs.GPBPUD.bit.GPIO48 = 0; // Enable pullup on GPIO48
GpioDataRegs.GPBCLEAR.bit.GPIO48 = 1; // Load output latch
GpioCtrlRegs.GPBMUX2.bit.GPIO48 = 0; // GPIO48 = GPIO
GpioCtrlRegs.GPBDIR.bit.GPIO48 = 1; // GPIO48 = output
//初始化行2的GPIO49
GpioCtrlRegs.GPBPUD.bit.GPIO49 = 0; // Enable pullup on GPIO49
GpioDataRegs.GPBCLEAR.bit.GPIO49 = 1; // Load output latch
GpioCtrlRegs.GPBMUX2.bit.GPIO49 = 0; // GPIO49 = GPIO
GpioCtrlRegs.GPBDIR.bit.GPIO49 = 1; // GPIO49 = output
//初始化行3的GPIO50
GpioCtrlRegs.GPBPUD.bit.GPIO50 = 0; // Enable pullup on GPIO50
GpioDataRegs.GPBCLEAR.bit.GPIO50 = 1; // Load output latch
GpioCtrlRegs.GPBMUX2.bit.GPIO50 = 0; // GPIO50 = GPIO
GpioCtrlRegs.GPBDIR.bit.GPIO50 = 1; // GPIO50 = output
EDIS;
// 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.EPWM1_TZINT = &epwm1_tzint_isr;
EDIS; // This is needed to disable write to EALLOW protected registers
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Stop all the TB clocks
EDIS;
// Enable TZ1 and TZ2 as one shot trip sources
EALLOW;
EPwm1Regs.TZSEL.bit.OSHT1 = 1;
EPwm1Regs.TZSEL.bit.OSHT2 = 1;
// What do we want the TZ1 and TZ2 to do?
EPwm1Regs.TZCTL.bit.TZA = TZ_FORCE_HI;
EPwm1Regs.TZCTL.bit.TZB = TZ_FORCE_LO;
// Enable TZ interrupt
EPwm1Regs.TZEINT.bit.OST = 1;
EDIS;
// Setup Sync
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE; // Pass through
// Allow each timer to be sync'ed
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;
EPwm1Regs.TBPHS.half.TBPHS = 0;
EPwm1Regs.TBCTR = 0x0000; // Clear counter
EPwm1Regs.TBPRD = tbprd;
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;
EPwm1Regs.TBCTL.bit.HSPCLKDIV=TB_DIV1;
EPwm1Regs.TBCTL.bit.CLKDIV=TB_DIV1;
// Setup shadow register load on ZERO
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
// Set Compare values
EPwm1Regs.CMPA.half.CMPA = 0; // Set compare A value
EPwm1Regs.CMPB = 0; // Set Compare B value
// Set actions
EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; // Set PWM1A on Zero
EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Clear PWM1A on event A, up count
EPwm1Regs.AQCTLB.bit.ZRO = AQ_CLEAR; // Set PWM1B on Zero
EPwm1Regs.AQCTLB.bit.CAU = AQ_SET; // Clear PWM1B on event B, up count
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Start all the timers synced
EDIS;
// Enable CPU INT3 which is connected to EPWM1-3 INT:
IER |= M_INT2;
// Enable EPWM INTn in the PIE: Group 3 interrupt 1-3
PieCtrlRegs.PIEIER2.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 epwm1_tzint_isr(void)
{
EALLOW;
EPwm1Regs.TZCLR.bit.OST = 1;
EPwm1Regs.TZCLR.bit.INT = 1;
EDIS;
// Acknowledge this interrupt to receive more interrupts from group 3
PieCtrlRegs.PIEACK.all = PIEACK_GROUP2;
}
void EPwm1A_SetCompare(Uint16 val)
{
EPwm1Regs.CMPA.half.CMPA = val; //设置占空比
}
void EPwm1B_SetCompare(Uint16 val)
{
EPwm1Regs.CMPB = val; //设置占空比
}
六、06Demo-PWM_dc_motor
void main()
{
int i=0;
InitSysCtrl();
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
LED_Init();
TIM0_Init(150,200000);//200ms
KEY_Init();
DCMotor_ePWM2_Init();
while(1)
{
}
}
#include "dc_motor.h"
#include "key.h"
void DC_Motor_Init(void)
{
EALLOW;
//DC_MOTOR端口配置--1路
GpioCtrlRegs.GPAMUX1.bit.GPIO2=0;
GpioCtrlRegs.GPADIR.bit.GPIO2=1;
GpioCtrlRegs.GPAMUX1.bit.GPIO3=0;
GpioCtrlRegs.GPADIR.bit.GPIO3=1;
//DC_MOTOR端口配置--2路
GpioCtrlRegs.GPAMUX1.bit.GPIO4=0;
GpioCtrlRegs.GPADIR.bit.GPIO4=1;
GpioCtrlRegs.GPAMUX1.bit.GPIO5=0;
GpioCtrlRegs.GPADIR.bit.GPIO5=1;
EDIS;
GpioDataRegs.GPACLEAR.bit.GPIO2=1;
GpioDataRegs.GPACLEAR.bit.GPIO3=1;
GpioDataRegs.GPACLEAR.bit.GPIO4=1;
GpioDataRegs.GPACLEAR.bit.GPIO5=1;
}
// 宏定义每个定时器周期寄存器的周期值;
#define EPWM2_TIMER_TBPRD 3750 // 周期值
#define EPWM2_MAX_CMPA 3700
#define EPWM2_MIN_CMPA 0
#define EPWM2_MAX_CMPB 3700
#define EPWM2_MIN_CMPB 0
/***************全局变量定义****************/
Uint16 pwm_stepValue=0; //高电平时间
Uint16 Direction=0;//转速方向
interrupt void epwm2_isr(void);
void DCMotor_ePWM2_Init(void)
{
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Disable TBCLK within the ePWM
SysCtrlRegs.PCLKCR1.bit.EPWM2ENCLK = 1; // ePWM2
EDIS;
InitEPwm2Gpio();
// 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.EPWM2_INT = &epwm2_isr;
EDIS; // This is needed to disable write to EALLOW protected registers
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
EDIS;
// 设置时间基准的时钟信号(TBCLK)
EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // 递增计数模式
EPwm2Regs.TBPRD = EPWM2_TIMER_TBPRD; // 设置定时器周期
EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE; // 禁止相位加载
EPwm2Regs.TBPHS.half.TBPHS = 0x0000; // 时基相位寄存器的值赋值0
EPwm2Regs.TBCTR = 0x0000; // 时基计数器清零
EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV2; // 设置时基时钟速率为系统时钟SYSCLKOUT/4=37.5MHZ;
EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV2;//由时基时钟频率和时基周期可知PWM1频率=10KHZ;
// 设置比较寄存器的阴影寄存器加载条件:时基计数到0
EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
// 设置比较寄存器的值
EPwm2Regs.CMPA.half.CMPA = EPWM2_MIN_CMPA; // 设置比较寄存器A的值
EPwm2Regs.CMPB = EPWM2_MIN_CMPB; // 设置比较寄存器B的值
// 设置动作限定;首先默认为转动方向为正转,这时只有PWM1A输出占空比;
EPwm2Regs.AQCTLA.bit.ZRO = AQ_SET; // 计数到0时PWM1A输出高电平
EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR; // 递增计数时,发生比较寄存器A匹配时清除PWM1A输出
EPwm2Regs.AQCTLB.bit.ZRO = AQ_CLEAR; // 计数到0时PWM1B输出低电平
EPwm2Regs.AQCTLB.bit.CBU = AQ_CLEAR; // 递增计数时,发生比较寄存器A匹配时清除PWM1B输出
// 3次0匹配事件发生时产生一个中断请求;一次匹配是100us,一共300us产生一次中断;
EPwm2Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // 选择0匹配事件中断
EPwm2Regs.ETSEL.bit.INTEN = 1; // 使能事件触发中断
EPwm2Regs.ETPS.bit.INTPRD = ET_3RD; // 3次事件产生中断请求
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
EDIS;
IER |= M_INT3;
PieCtrlRegs.PIEIER3.bit.INTx2 = 1;
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
}
interrupt void epwm2_isr(void)
{
static unsigned char key=0;
key=KEY_Scan(0);
if(key==KEY1_PRESS||key==KEY2_PRESS||key==KEY3_PRESS)
{
if(key==KEY3_PRESS)
{
//保证下面EPWMA和EPWMB相互切换同时输出0电平;
EPwm2Regs.CMPA.half.CMPA = 0;//改变脉宽
EPwm2Regs.CMPB = 0;//改变脉宽
if(Direction==0)
{
// 设置动作限定;首先默认为转动方向为反转,这时只有PWM1B输出占空比;
EPwm2Regs.AQCTLA.bit.ZRO = AQ_CLEAR; // 计数到0时PWM1A输出低电平
EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR; // 递增计数时,发生比较寄存器A匹配时清除PWM1A输出
EPwm2Regs.AQCTLB.bit.ZRO = AQ_SET; // 计数到0时PWM1B输出高电平
EPwm2Regs.AQCTLB.bit.CBU = AQ_CLEAR; // 递增计数时,发生比较寄存器A匹配时清除PWM1B输出
Direction=1;
}
else
{
// 设置动作限定;首先默认为转动方向为正转,这时只有PWM1A输出占空比;
EPwm2Regs.AQCTLA.bit.ZRO = AQ_SET; // 计数到0时PWM1A输出高电平
EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR; // 递增计数时,发生比较寄存器A匹配时清除PWM1A输出
EPwm2Regs.AQCTLB.bit.ZRO = AQ_CLEAR; // 计数到0时PWM1B输出低电平
EPwm2Regs.AQCTLB.bit.CBU = AQ_CLEAR; // 递增计数时,发生比较寄存器A匹配时清除PWM1B输出
Direction=0;
}
pwm_stepValue=0;
}
else
{
if(key==KEY1_PRESS)
{
if(pwm_stepValue!=3500)
pwm_stepValue+=500;
}
else if(key==KEY2_PRESS)
{
if(pwm_stepValue!=0)
pwm_stepValue=pwm_stepValue-500;
}
}
EPwm2Regs.CMPA.half.CMPA = pwm_stepValue;//改变脉宽
EPwm2Regs.CMPB = pwm_stepValue;//改变脉宽
}
// 清除这个定时器的中断标志位
EPwm2Regs.ETCLR.bit.INT = 1;
// 清除PIE应答寄存器的第三位,以响应组3内的其他中断请求;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
}