1.关于DSP28335的内部ePWM模块
PWM的4要素:周期,脉宽,脉冲相位,脉冲个数。
DSP中共有6个EPWM模块,每个EPWM模块有两路输出ePWMxA和ePWMxB。它们两者之间可以是两路独立单边沿PWM输出;可以是两路独立对称的双边沿PWM输出;可以是一对双边沿非对称PWM输出。
每组ePWM包括时基TB;计数比较模块CC;动作模块AQ,死区产生模块DB,PWM斩波模块PC,错误联防TZ,时基触发ET。
简要介绍模块的功能:
TB:
确定TBCLK,即与载波的周期有关
工作模式:增,减,增减
产生事件:CTR=PRD;CTR=0、
相位关系
管理ePWM模块间的同步性
如何使用:使能ePWM式中PCLKER;禁用时基时钟TBCLKSYNC=0;设置分频值(HSPCLKDIV,CLKDIV)和ePWM工作模式CTRMODE;启用时基时钟TBCLKSYNC=1;
CC:
输入是时基计数器的值,将其与CMPA,CMPB比较。主要是影子寄存器和活动寄存器的使用。一种是直接加载,一种是CTR=PRD,CTR=ZERO加载。
AQ:
根据事件选择对应的ePWMxA,ePWMxB是高还是低。有ZRO,CAU,CAD,CBU,CBD。Clear和set就行。
DB:
死区控制。选择不同的模式,对ePWMxA和ePWMxB的上下沿做一个延时处理。
PC:
斩波,可以降低开关管的损耗。相当于与,将一个高电平,分成很多小份,可以降低开关管的损耗,此模块可以设置第一个小份脉冲的宽度,打开开关管。然后后边的小份目的在于维持管子的导通。
TZ:
错误联防,是6个GPIO口,可以是周期触发也可以是单次触发,两种方式均可以产生中断,周期触发的中断标志可以自动清,单次触发的中断标志需要手动清。一旦错误发生,TZCTL寄存器中的值立刻输出到ePWMxA和ePWMxB引脚上。
ET:
事件触发。
2.关于SPWM
什么是调制波和正弦波?
一般SPWM里,调制波=正弦波,载波=三角波
橙色线模拟的就是DSP中的TB模块“增减”计数模式。清晰可见它不是从0开始的,峰值为TBPRD。因此需要改变调制波的值。原本幅值为1的正弦波,使用公式
注意TBPRD是峰值。橙色三角波的顶点值。
什么是调制比?
调制比是调制波幅值和载波幅值之比,同时调制所得到的基波分量的幅值也与调制比成正比,在双极性SPWM下,得到基波分量的幅值等于调制比M与输入直流电的二分之一的乘积。因此调制比是一个很重要的概念,它决定了所得到正弦基波的幅值。补充一下,还有一个重要的概念是载波比,载波比决定最低谐波次数,单极性与双极性得到的最低谐波次数是不同的。
3.PWM的实现
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
InitSysCtrl();
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
// LED_Init();
EPWM6_Init(500);
EPwm6A_SetCompare(300); //300/500=0.6
EPwm6B_SetCompare(300); //i值最大可以取499,因为ARR最大值是499.
}
void EPWM6_Init(Uint16 tbprd)
{
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Disable TBCLK within the ePWM
SysCtrlRegs.PCLKCR1.bit.EPWM6ENCLK = 1; // 使能epwm外设时钟
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; //不分频即TBCLK=150M
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; //设置占空比
}
采用增计数模式,150M的TBCLK,150个是1us,现在500个,就是(1/150)*500us,换成频率就是300M。此处周期500,占空比300,所以0.6的占空比。更改CLKDIV,HSPCLKDIV可以将周期变长。如CLKDIV=2时,频率为150Mkhz
4.SPWM的实现
利用中断,每次进中断,都改变CMPA或CMPB的值(根据调整后的正弦表,前边提到过(公式))。
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File
#include "Math.h"
interrupt void epwm6_timer_isr(void); //函数的声明,因为函数体的定义在最后,这个是自己定义的
void EPWM6_Init(Uint16 tbprd);
int k,N=128;
float m=1;//设置调制度
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
InitSysCtrl();
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
EALLOW;
PieVectTable.EPWM6_INT =&epwm6_timer_isr;
EDIS;
// LED_Init();
EPWM6_Init(7500);
IER |= M_INT3;
PieCtrlRegs.PIEIER3.bit.INTx6 = 1; //外部中断 使能第三组中断的第6个小中断
EINT; //开CPU级中断响应
ERTM;
}
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_UPDOWN; // 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.CAU = AQ_CLEAR; // Set PWM1A on Zero
EPwm6Regs.AQCTLA.bit.CAD = AQ_SET; // Clear PWM1A on event A, up count
EPwm6Regs.AQCTLB.bit.CBU = AQ_CLEAR; // Set PWM1B on Zero
EPwm6Regs.AQCTLB.bit.CBD = 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;
}
interrupt void epwm6_timer_isr(void) //中断服务程序
{
if(k >= N)
{
k = 0;
}
EPwm6Regs.CMPA.half.CMPA = EPwm6Regs.TBPRD*(1+m*sin(2*3.14159*k/N))/2;
EPwm6Regs.CMPB=EPwm6Regs.TBPRD*(1+m*sin(2*3.14159*k/N))/2;
k++;
EPwm6Regs.ETCLR.bit.INT = 1; //中断标志位清零才能进入下一次的中断,在PWM的ET模块中
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; //使能中断 PIEACK_GROUP3
}
TBCLK是150Mhz,tbprd=7500;增减计数。计数150次是1us,得到周期为1/150*(7500*2)us,频率为10k。
改变N,改变调制波的频率。
1.关于DSP28335的内部ePWM模块
PWM的4要素:周期,脉宽,脉冲相位,脉冲个数。
DSP中共有6个EPWM模块,每个EPWM模块有两路输出ePWMxA和ePWMxB。它们两者之间可以是两路独立单边沿PWM输出;可以是两路独立对称的双边沿PWM输出;可以是一对双边沿非对称PWM输出。
每组ePWM包括时基TB;计数比较模块CC;动作模块AQ,死区产生模块DB,PWM斩波模块PC,错误联防TZ,时基触发ET。
简要介绍模块的功能:
TB:
确定TBCLK,即与载波的周期有关
工作模式:增,减,增减
产生事件:CTR=PRD;CTR=0、
相位关系
管理ePWM模块间的同步性
如何使用:使能ePWM式中PCLKER;禁用时基时钟TBCLKSYNC=0;设置分频值(HSPCLKDIV,CLKDIV)和ePWM工作模式CTRMODE;启用时基时钟TBCLKSYNC=1;
CC:
输入是时基计数器的值,将其与CMPA,CMPB比较。主要是影子寄存器和活动寄存器的使用。一种是直接加载,一种是CTR=PRD,CTR=ZERO加载。
AQ:
根据事件选择对应的ePWMxA,ePWMxB是高还是低。有ZRO,CAU,CAD,CBU,CBD。Clear和set就行。
DB:
死区控制。选择不同的模式,对ePWMxA和ePWMxB的上下沿做一个延时处理。
PC:
斩波,可以降低开关管的损耗。相当于与,将一个高电平,分成很多小份,可以降低开关管的损耗,此模块可以设置第一个小份脉冲的宽度,打开开关管。然后后边的小份目的在于维持管子的导通。
TZ:
错误联防,是6个GPIO口,可以是周期触发也可以是单次触发,两种方式均可以产生中断,周期触发的中断标志可以自动清,单次触发的中断标志需要手动清。一旦错误发生,TZCTL寄存器中的值立刻输出到ePWMxA和ePWMxB引脚上。
ET:
事件触发。
2.关于SPWM
什么是调制波和正弦波?
一般SPWM里,调制波=正弦波,载波=三角波
橙色线模拟的就是DSP中的TB模块“增减”计数模式。清晰可见它不是从0开始的,峰值为TBPRD。因此需要改变调制波的值。原本幅值为1的正弦波,使用公式
注意TBPRD是峰值。橙色三角波的顶点值。
什么是调制比?
调制比是调制波幅值和载波幅值之比,同时调制所得到的基波分量的幅值也与调制比成正比,在双极性SPWM下,得到基波分量的幅值等于调制比M与输入直流电的二分之一的乘积。因此调制比是一个很重要的概念,它决定了所得到正弦基波的幅值。补充一下,还有一个重要的概念是载波比,载波比决定最低谐波次数,单极性与双极性得到的最低谐波次数是不同的。
3.PWM的实现
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
InitSysCtrl();
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
// LED_Init();
EPWM6_Init(500);
EPwm6A_SetCompare(300); //300/500=0.6
EPwm6B_SetCompare(300); //i值最大可以取499,因为ARR最大值是499.
}
void EPWM6_Init(Uint16 tbprd)
{
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Disable TBCLK within the ePWM
SysCtrlRegs.PCLKCR1.bit.EPWM6ENCLK = 1; // 使能epwm外设时钟
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; //不分频即TBCLK=150M
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; //设置占空比
}
采用增计数模式,150M的TBCLK,150个是1us,现在500个,就是(1/150)*500us,换成频率就是300M。此处周期500,占空比300,所以0.6的占空比。更改CLKDIV,HSPCLKDIV可以将周期变长。如CLKDIV=2时,频率为150Mkhz
4.SPWM的实现
利用中断,每次进中断,都改变CMPA或CMPB的值(根据调整后的正弦表,前边提到过(公式))。
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File
#include "Math.h"
interrupt void epwm6_timer_isr(void); //函数的声明,因为函数体的定义在最后,这个是自己定义的
void EPWM6_Init(Uint16 tbprd);
int k,N=128;
float m=1;//设置调制度
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
InitSysCtrl();
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
EALLOW;
PieVectTable.EPWM6_INT =&epwm6_timer_isr;
EDIS;
// LED_Init();
EPWM6_Init(7500);
IER |= M_INT3;
PieCtrlRegs.PIEIER3.bit.INTx6 = 1; //外部中断 使能第三组中断的第6个小中断
EINT; //开CPU级中断响应
ERTM;
}
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_UPDOWN; // 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.CAU = AQ_CLEAR; // Set PWM1A on Zero
EPwm6Regs.AQCTLA.bit.CAD = AQ_SET; // Clear PWM1A on event A, up count
EPwm6Regs.AQCTLB.bit.CBU = AQ_CLEAR; // Set PWM1B on Zero
EPwm6Regs.AQCTLB.bit.CBD = 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;
}
interrupt void epwm6_timer_isr(void) //中断服务程序
{
if(k >= N)
{
k = 0;
}
EPwm6Regs.CMPA.half.CMPA = EPwm6Regs.TBPRD*(1+m*sin(2*3.14159*k/N))/2;
EPwm6Regs.CMPB=EPwm6Regs.TBPRD*(1+m*sin(2*3.14159*k/N))/2;
k++;
EPwm6Regs.ETCLR.bit.INT = 1; //中断标志位清零才能进入下一次的中断,在PWM的ET模块中
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; //使能中断 PIEACK_GROUP3
}
TBCLK是150Mhz,tbprd=7500;增减计数。计数150次是1us,得到周期为1/150*(7500*2)us,频率为10k。
改变N,改变调制波的频率。
1
举报