dspic33系列编程之PWM篇

dspic33F系列共有3个PWM模块,还有一个额外的其它引脚形成的PWM4,PWM4需要额外设置。PWM1~PWM3是通用的告诉PWM模块,每个PWM模块有两个输出口,以输出PWM信号,芯片引脚上用PWMxL和PWMxH(x为1~3)表示。
PWM模块在很多领域都得到使用:AC/DC转换器,DC/DC转换器,UPS,电池管理,逆变器等等。以下是dipic33F的PWM功能介绍:可触发ADC中断、有四种工作模式(独立模式,互补模式,推挽模式,冗余模式),可产生过流保护及中断,可产生特殊事件中断(定时)等等功能。本PWM最高频率可达250khz,并由以下寄存器控制其功能:PTCON、PTCON2、PTPER,SEVTCMP,MDC,PWMCONX,PDCX,PHASEX,DTRX,ALTDTRX,
SDCX,SPHASE,TRGCONX,IOCONX,FCLCONX,TRIGX,STRIGX,LEBCONX,PWMCAP这些。有X代表其控制的是1~3的单独工作。
各个寄存器每位功能及其作用见官方资料。以下是具体的例子,实现各种配合。
  例子1:利用PWM产生器产生固定占空比30%,并PWMH,PWML互补的信号。存在3%的死区。
    代码:void   pwm_init()
                              {    
PTPER=0X0800;                           //时基设为56KHZ,作为周期
PDC3=0X0267;                              //占空比设置为30%
IOCON3bits.PENH=1;      //pwm3h高电平有效
   IOCON3bits.PENL=1;             //pwm3L高电平有效
             IOCON3bits.PMOD=3; //互补模式
DTR3=0X003D;                        //死区设为3%
PTCONbits.PTEN=1;                //开启PWM模块
}
例子2:利用pwm及其中断产生每个周期更新的SPWM驱动信号,设正弦表已知,为sintab
代码:void   pwm_init()
{
PTPER=0x0800; //设置PWM周期56Khz 
PTCON2bits.PCLKDIV=0; //设置预分频为1:4,Tcy=16*Tsy,频率为56KHZ 
PWMCON1bits.MDCS=0; //占空比由各自MDC决定 PDC1=0x0100; //初始化占空比为0               IOCON1bits.PENH=1; 
IOCON1bits.PENL=1; 
IOCON1bits.PMOD=0; //互补模式 
PWMCON1bits.IUE=1; //立即改变占空比
PWMCON1bits.TRGIEN=1; //允许中断
TRIG1=0x0800;          //每个周期内产生中断
PTCONbits.SEIEN=1; //特殊事件触发 
PTCONbits.PTEN=1; //开启PWM模块
}
     void   pwm_isrinit()
{
CORCONbits.IPL3=0;
SRbits.IPL=0;      //CPU优先级设为0
IPC23bits.PWM1IP=2;    
IEC5bits.PWM1IE=1;          //设置PWM中断1优先级
void __attribute__((interrupt, no_auto_psv)) _PWM1Interrupt()
{
PDC1=sinetab[i];
IFS5bits.PWM1IF=0;
i++;
if(i>280)
i=0;
}
例子3:利用PI调节与SPWM实现闭环控制(应用AD中断)
void pwm_init()
{
PTPER=0x0800;      //设置PWM周期56Khz
PTCON2bits.PCLKDIV=0;    //设置预分频为1:4,Tcy=16*Tsy,频率为56KHZ
PWMCON1bits.MDCS=0;               //占空比由各自MDC决定
PDC1=0x0000;                                    //初始化占空比为0
IOCON1bits.PENH=1;
IOCON1bits.PENL=1;
IOCON1bits.PMOD=0;                   //互补模式
TRIG1=0x0008;                         //触发AD采样的时间
// PWM1H rising and falling edges trigger LEB counter (240ns)
// LEB is applied to current limit input
LEBCON1 = 0xC4F0;
// PWM 限流设置
FCLCON1bits.FLTMOD = 0; // Latched Fault Mode
FCLCON1bits.CLMOD = 1; // 限流使能
FCLCON1bits.CLSRC = 1; // Current Limit Source is Fault 2
FCLCON1bits.CLPOL = 0; // Current Limit Source is Active High

TRGCON1bits.TRGDIV = 0; // Trigger ADC every PWM Period
TRGCON1bits.TRGSTRT = 0; // Wait 0 PWM cycles before generating first PWM trigger       
PTCONbits.SEIEN=1;
PTCONbits.PTEN=1;                      //开启PWM模块
}
void ad_init()
{
      ADCONbits.SLOWCLK = 1;               // ADC辅助始终
      ADCONbits.FORM = 0;                   // 输出格式右对齐 
ADCONbits.EIE = 1;                     // 2次转换后中断 
ADCONbits.ORDER = 0;                  // 偶数通道优先
ADCONbits.SEQSAMP = 0;               // Simultaneus Sampling Enabled 
ADCONbits.ASYNCSAMP = 1; // Asynchronous Sampling Enableed 
ADCONbits.ADCS = 4;                   // 时钟设为5分频
ADSTAT = 0;                               // 清除数据状态位     
      ADPCFGbits.PCFG1 = 0;                // AN1 反激1电流
ADPCFGbits.PCFG2 = 0; // AN2 反激2电流
      ADCPC0bits.TRGSRC0 = 4;      // AN0 and AN1 由PWM1触发 
}
void isrinit()
{
CORCONbits.IPL3=0;
SRbits.IPL=0;                  //CPU优先级设为0
IPC27bits.ADCP0IP = 6;               // Set ADC Pair0 Interrupt Priority (2nd highest priority)
IFS6bits.ADCP0IF = 0;       // Clear ADC Pair0 Interrupt Flag 
IEC6bits.ADCP0IE = 1;                // Enable ADC Pair0 Interrupt at start 
}
void __attribute__((interrupt, no_auto_psv)) _ADCP0Interrupt()
{
int duty;
fbcurrent[0]=(ADCBUF1 << 5);
PDC1=dctab[i]+PIcalculate(1,1,sintab[i],fbcurrent[0]);
if(duty>UK_DC_MAX)
duty=UK_DC_MAX;
PDC1=duty;
i++;
if(i>280)
i=0;
IFS6bits.ADCP0IF = 0;                            // Clear ADC Interrupt Flag
}
int main()
{
pwminit();
adinit();
ADCONbits.ADON = 1;          // Enable the ADC Module early for ADC Settling Time

isrinit();
while(1)
{ ;
}
}
  • 4
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值