dspic33fj PWM 时钟配置
- 为什么要关注PWM时钟配置?
后期要研发一拖一400W 500W 600W 的设备,在变压器不变的情况下,改变输出大功率的的方式是改变PWM频率。为了灵活配置PWM,需要熟悉 PWM 时钟,
- 过程中遇到哪些困难?
输出频率与 设想的不一致,
dspic33fj的 CPU外部晶振是8MHz,经过PLL 40倍频 2*2 分频,之后的频率是 80Mhz
系统指令时钟是80Mhz/2 为40Mhz,
如果想获得200khz的频率,只需要向 PWM周期寄存器输入40M/200k=200
实际上,输入200,得到的是另外一个频率跟200K相差很大。
- 如何解决
咨询了技术交流群的群主,给解答了疑惑 ,dspic33fj使用另外一套辅助时钟,
辅助时钟 震荡源选择 FRC ----> 16倍频------>APLL 16倍频------->1/2分频
FRC是7.37Mhz 辅助时钟的频率7.371616/2=943.36M 约为 1.06ns
PWM周期寄存器的值设置就是(1/200k)/1.06ns
/*****************ACLKCON?????????????************************************/
ACLKCONbits.FRCSEL=1; // 1 = Selects FRC clock for auxiliary PLL
//0 = Input clock source is determined by the ASRCSEL bit setting
ACLKCONbits.SELACLK=1; //
//1 = Auxiliary oscillators provide the source clock for the auxiliary clock divider
//0 = Primary PLL (FVCO) provides the source clock for the auxiliary clock divider
ACLKCONbits.APSTSCLR=7; //Auxiliary Clock Output Divider bits 111 = Divided by 1
//110 = Divided by 2
//101 = Divided by 4
//100 = Divided by 8
//011 = Divided by 16
//010 = Divided by 32
//001 = Divided by 64
//000 = Divided by 256
ACLKCONbits.ENAPLL=1; //Auxiliary PLL Enable bit
while(ACLKCONbits.APLLCK!=1); //Wait for Auxiliary PLL to Lock
/*** PTCON2?PWM ?????????? 2********************************/
PTCON2bits.PCLKDIV2=0; //PWM Input Clock Prescaler (Divider) Select bits
//110 = Divide-by-64, maximum PWM timing resolution
//101 = Divide-by-32, maximum PWM timing resolution
//100 = Divide-by-16, maximum PWM timing resolution
//011 = Divide-by-8, maximum PWM timing resolution
// 010 = Divide-by-4, maximum PWM timing resolution
//001 = Divide-by-2, maximum PWM timing resolution
//000 = Divide-by-1, maximum PWM timing resolution
PTCON2bits.PCLKDIV1=0;
PTCON2bits.PCLKDIV0=1;
//PTPER=4800; //??pwm??10khz
IOCON1bits.SWAP=0; //PWM1H?PWM1L??
IOCON1bits.PMOD0=1; //pwm i/o????????
IOCON1bits.PMOD1=1;
IOCON1bits.PENH=1; //pwm????pwml??
IOCON1bits.OVRENH=0; //pwm????pwmxl??????
PWMCON1bits.MDCS=0; //PDC set PWM
PWMCON1bits.MTBS=0;
PWMCON1bits.DTC1=1; //??????
PWMCON1bits.DTC0=0;
PWMCON1bits.ITB=1;
PWMCON1bits.CLIEN=1; //??current limit intterrupt
PHASE1=2404;
PDC1=500;
输出结果 200KHZ
- 100us计数器的设置
工频50HZ 20ms 半周期 10ms ,把10ms分成100份,一份100us,每隔100us 在timer中断程序里跟新一次PWM占空比 实现正弦输出
int LED_STATUS=0;
#include "xc.h"
void Timer2_Timing_Init(void)//?????
{
T2CONbits.TON = 0;//??16?Timer1
T2CONbits.TCS = 0;//????Fosc/2
T2CONbits.TGATE = 0;//??????? ??
T2CONbits.TCKPS = 0x00;//????????1:1
T2CONbits.TSIDL = 0;//????????
/// T2CONbits.TSYNC = 0;//???????????????????????
TMR2 = 0x00;//???
PR2 = 4000;//???
IPC1bits.T2IP= 0x01; // ???1
IFS0bits.T2IF = 0; // Timer1??????? ??
IEC0bits.T2IE = 1; // Timer1????? ??
T2CONbits.TON = 1;//????16?Timer1
}
void __attribute__((__interrupt__, auto_psv)) _T2Interrupt(void)
{
IFS0bits.T2IF = 0; //???
if(LED_STATUS==0)
{
LATDbits.LATD5=1;
LED_STATUS=1;
}
if(LED_STATUS==1)
{
LATDbits.LATD5=0;
LED_STATUS=0;
}
}
- 输出效果