一:简单介绍

PWM寄存器操作写顺序
PWM周期
PWM占空比
系统时钟频率的改变
这些文字光看可能看不太懂,但是后面结合代码一起就明白了。
二:PWM
相关寄存器
PWMCON0:配置PWM的时钟分频和使能/失能PWM,例程代码配置为PWMCON0=0B00111111,即1分频,使能所有PWM
PWMCON1:配置PWM0和PWM1的引脚,使能/失能PWM0和PWM2的死区功能,配置死区的时钟分频,例程代码配置为PWMCON1=0B00000000,即PWM01位置选择为RB5/RB4,失能死区功能

PWMCON2:配置PWM的输出模式,例程代码配置为PWMCON2=0B00000000,即正常输出

PWMTL、PWMT4L:配置PWM的周期低8位,其中PWM0-3共用PWMTL,PWM4独立使用PWMT4L,例程代码配置为PWMTL=0x8F PWMT4L=0x8F ,即PWM0-4的周期低8位配置为8F
PWMTH:这个寄存器的值较为复杂,Bit5-Bit4配置PWM4的占空比高2位,Bit3-Bit2配置PWM4的周期高2位,Bit1-Bit0配置PWM0-3的周期高2位,例程代码配置为PWMTH=0B00001101,即PWM4占空比高2位为00,PWM4的周期高2位为11,PWM0-2的周期高2位为01
PWMD0L、PWMD1L、PWMD2L、PWMD3L、PWMD4L:这5个寄存器是配置PWM0-4的占空比的低8位,例程代码配置为PWMD0L=0x4F PWMD1L=0x9F PWMD2L=0xEF PWMD3L=0x3F PWMD4L=0xE3 ,即PWM0-4的占低8位配置分别为4F、9F、EF、3F、E3
PWM01DT、PWM23DT:配置PWM0-3的死区时间,例程代码配置为PWM01DT=0x3F PWM23DT=0 ,即PWM0-1的死区时间配置为3F,PWM2-3的死区时间配置为0
代码部分
头文件
#include <cms.h>
主函数
TRISB为PORTB的方向寄存器,用来配置PORTB的输入输出,设置为0代表配置PORTB的所有引脚为输出
void main()
{
asm("nop");
asm("clrwdt");
OSCCON = 0X71; //内部振荡器用作系统时钟
TRISB = 0; //配置PWM引脚为输出脚
Set_PWM(); //设置PWM周期50us,占空比PWM0-20%、PWM1-40%、PWM2-60%、PWM3-80%、PWM4-50%
while(1)
{
asm("clrwdt");
}
}
PWM部分
PWMTL = 0x8f;
PWMT4L = 0x8f;
PWMTH = 0B00001101;
这部分是配置PWM0-4的周期低8位和高2位,还有PWM4的占空比高2位
中间部分代码以PWM0为例,PWM0的占空比高2位是00,低8位是0100 1111,即0x04F,十进制为79,PWM0的周期高2位是01,低8位是1000 1111,即0x18F,十进制为399,根据公式3占空比=(PWMDx[9:0]+1)/(PWMT[9:0]+1),可以计算出占空比为(79+1)/(399+1)=20%,PWM1-4的计算方式同理
死区部分代码可以看到PWM01DT的值为0x3F,根据死区宽度 = (PWMxDT[5:0]+1)*TOSC*(DT_DIV分频值),TOSC=1/FOSC,可以计算出死区宽度为(63+1)x(1/16)x1=4us
最后部分的代码则是配置PWM为正常输出模式,选择PWM01的输出脚,失能PWM0-4死区,PWM分频为Fosc/2,使能所有PWM
void Set_PWM()
{
PWMTL = 0x8f; //PWM0~3共周期,周期低位
PWMT4L = 0x8f; //PWM4独立周期,周期低位
PWMTH = 0B00001101; //周期高两位及PWM4占空比高两位
//PWM0~3周期为:(0B110001111+1)*(1/16)*2 =50uS
//PWM4周期为:(0B1110001111+1)*(1/16)*2 =114uS
PWMD01H = 0x00; //高位改变后不能立即生效,需要给占空比的低位寄存器后才能加载
//PWM0 占空比设置为20%
PWMD0L = 0x4F; //(79+1)/(399+1) = 20%
//PWM1 占空比设置为40%
PWMD1L = 0x9F; //(159+1)/(399+1) = 40%
PWMD23H = 0x10;
//PWM2 占空比设置为60%
PWMD2L = 0xEF; //(239+1)/(399+1) = 60%
//PWM3 占空比设置为80%
PWMD3L = 0x3F; //(319+1)/(399+1) = 80%
//PWM4 占空比设置为25%
PWMD4L = 0xE3; //(227+1)/(911+1) = 25%
PWM01DT = 0x3F; //死区时间,低6位有效位=(0B00111111+1)*(1/16)*1 =4uS
PWM23DT = 0;
PWMCON2 = 0B00000000; //正常输出
PWMCON1 = 0B00000000; //PWM01位置选择为RB5/RB4;禁止死区;可使能PWM0/1互补,PWM2/3互补
PWMCON0 = 0B00111111; //PWM分频Fosc/2,使能PWM0、PWM1、PWM2、PWM3、PWM4
}