①8位PWM

8位PWM的缺点是频率范围小,且不太精准。

Ⅰ.独立输出

SetSysClock(CLK_SOURCE_PLL_60MHz);
#if PWM8
GPIOA_ModeCfg(GPIO_Pin_12, GPIO_ModeOut_PP_5mA); // PA12 - PWM4
PWMX_CLKCfg(4); // cycle = 4/Fsys
PWMX_CycleCfg(PWMX_Cycle_64); // 周期 = 64*cycle
PWMX_ACTOUT(CH_PWM4, 64 / 2, Low_Level, ENABLE); // 25% 占空比
#endif
while(1);

库函数解析:

1.设置对应的PWM引脚为输出方向,设置I/O驱动能力,

2.设置寄存器R8_PWM_CLOCK_DIV(范围1-255),配置PWM 的基准时钟频率;

3.设置PWM配置控制寄存器R8_PWM_CONFIG,设置PWM的模式、数据位宽、周期;

4.设置PWM输出极性配置寄存器R8_PWM_POLAR,配置对应PWMx的输出极性;

5.根据需要的占空比计算出数据,写入对应的数据保持寄存器R8_PWMx_DATA;

6.设置PWM输出使能寄存器R8_PWM_OUT_EN,开启对应的PWMx输出使能;

调整R8_PWMx_DATA寄存器可修改输出PWM的占空比,占空比计算公式:
Ncyc = RB_PWM_CYCLE_SEL ? (2^n-1) : (2^n)
(其中n=数据位宽),Ncyc 结果在31~256 之间。
PWMx输出有效电平的占空比 = R8_PWMx_DATA / Ncyc * 100%
PWMx输出频率Fpwmout = Fpwm / Ncyc = Fsys/R8_PWM_CLOCK_DIV / Ncyc

如果跑蓝牙功能,Fsys设置为60M,R8_PWM_CLOCK_DIV 范围是1-255,Ncyc为8档可调(31/32,63/64,127/128,255/256),所以频率不可以随意配置。

主频60M:PWM最低频率为60M/255/256=919.12 约1k

​PWM最高频率为60M/1/31=1935483.87 约2M

支持16位PWM的芯片,一般Ncyc为6档可调(63/64,127/128,255/256)

主频60M:PWM最低频率为60M/255/256=919.12 约1k

​ PWM最高频率为60M/1/63=952380.95 约1M

 

Ⅱ.交错输出

#if PWM8
GPIOA_ModeCfg(GPIO_Pin_12, GPIO_ModeOut_PP_5mA); // PA12 - PWM4
GPIOA_ModeCfg(GPIO_Pin_13, GPIO_ModeOut_PP_5mA); // PA13 - PWM5
PWMX_CLKCfg(255); // cycle = 4/Fsys
PWMX_CycleCfg(PWMX_Cycle_128); // 周期 = 64*cycle
R8_PWM_CONFIG |= RB_PWM4_5_STAG_EN;
PWMX_ACTOUT(CH_PWM4, 64, Low_Level, ENABLE); // 25% 占空比
PWMX_ACTOUT(CH_PWM5, 64, Low_Level, ENABLE); // 25% 占空比
while(1);
#endif

代码运行结果波形输出结果为PWM4输出一个周期,PWM5不输出;PWM5输出一个周期,PWM4不输出,以此类推。

 

②16位PWM

相对8位的PWM频率范围较广,且相对精准。

#if PWM16
GPIOA_ModeCfg(GPIO_Pin_12, GPIO_ModeOut_PP_5mA); // PA12 - PWM4
PWMX_CLKCfg(1); // cycle = 1/Fsys
PWMX_16bit_CycleCfg(1); // 16 数据宽度时的PWM时钟周期(1-65535)
PWMX_16bit_ACTOUT(CH_PWM4, 1, Low_Level, ENABLE); // 50%占空比
#endif
while(1);

库函数解析:

1.设置对应的PWM引脚为输出方向,设置I/O驱动能力,

2.设置寄存器R8_PWM_CLOCK_DIV(范围1-255),配置PWM 的基准时钟频率;

3.设置PWM配置控制寄存器R8_PWM_CONFIG,设置PWM的模式、数据位宽、周期;

4.设置PWM输出极性配置寄存器R8_PWM_POLAR,配置对应PWMx的输出极性;

5.根据需要的占空比计算出数据,写入对应的数据保持寄存器R16_PWMx_DATA;

6.设置PWM输出使能寄存器R8_PWM_OUT_EN,开启对应的PWMx输出使能;

调整R16_PWMx_DATA寄存器可修改输出PWM的占空比,占空比计算公式:

Ncyc = R32_PWM_REG_CYCLE+1
R32_PWM_REG_CYCLE范围是1-66535
PWMx输出有效电平的占空比 = R16_PWMx_DATA/ Ncyc * 100%
PWMx输出频率Fpwmout = Fpwm / Ncyc = Fsys/R8_PWM_CLOCK_DIV / Ncyc

如果跑蓝牙功能,Fsys设置为60M,R8_PWM_CLOCK_DIV 范围是1-255,Ncyc范围是2-65536,频率相对8位更好配置。

主频60M:PWM最低频率为60M/255/65536=3.59Hz

​ PWM最高频率为60M/1/2=30MHz

 

 

③PWM中断

#if PWM16
GPIOA_ModeCfg(GPIO_Pin_12, GPIO_ModeOut_PP_5mA); // PA12 - PWM4
PWMX_CLKCfg(1); // cycle = 1/Fsys
PWMX_16bit_CycleCfg(1); // 16 数据宽度时的PWM时钟周期(1-65535)
PWMX_16bit_ACTOUT(CH_PWM4, 1, Low_Level, ENABLE); // 50%占空比
R8_PWM_INT_CTRL |= RB_PWM_IE_CYC|RB_PWM_IF_CYC;
PFIC_EnableIRQ(PWMX_IRQn);
while(1);
#endif

__INTERRUPT
__HIGH_CODE
void PWMX_IRQHandler(void)
{
R8_PWM_INT_CTRL |= RB_PWM_IF_CYC;
}

代码运行结果:每个PWM周期会进入一次PWM中断,可用于记录PWM输出次数,若只是关闭PWM输出每个周期还是会进入中断的,需关闭PWM功能。

posted on 2025-03-28 17:05  WCH蓝牙应用分享  阅读(35)  评论(0)    收藏  举报