1. TIM定时器
可用的TIM从2-7. 而且不像STM32这样子的MCU,这些TIM只支持单通道。就是不能使用1个TIM来控制多路PWM输出。如果你想输出一个色温亮度灯的话,你就要使用两个TIM来分别控制不同的PWM调光电路。
#define TIM0 ((TIM_TypeDef *) TIM0_REG_BASE)
#define TIM1 ((TIM_TypeDef *) TIM1_REG_BASE)
#define TIM2 ((TIM_TypeDef *) TIM2_REG_BASE)
#define TIM3 ((TIM_TypeDef *) TIM3_REG_BASE)
#define TIM4 ((TIM_TypeDef *) TIM4_REG_BASE)
#define TIM5 ((TIM_TypeDef *) TIM5_REG_BASE)
#define TIM6 ((TIM_TypeDef *) TIM6_REG_BASE)
#define TIM7 ((TIM_TypeDef *) TIM7_REG_BASE)
/* TIM */
TIM_TimeBaseInitTypeDef TIM_InitStruct;
TIM_StructInit(&TIM_InitStruct);
TIM_InitStruct.TIM_PWM_En = PWM_ENABLE;
/*<! PWM output freqency = 40M/(TIM_PWM_High_Count + TIM_PWM_Low_Count) */
/*<! PWM duty cycle = TIM_PWM_High_Count/(TIM_PWM_High_Count + TIM_PWM_Low_Count) */
uint32_t high_count = 10000;
if (light->pin_high_on)
{
TIM_InitStruct.TIM_PWM_High_Count = high_count;
TIM_InitStruct.TIM_PWM_Low_Count = total_pwm_count - high_count;
}
else
{
TIM_InitStruct.TIM_PWM_High_Count = total_pwm_count - high_count;
TIM_InitStruct.TIM_PWM_Low_Count = high_count;
}
MZ_DEBUG("------> pwmout high_H: %d high_L: %d \r\n",
TIM_InitStruct.TIM_PWM_High_Count,TIM_InitStruct.TIM_PWM_Low_Count);
TIM_InitStruct.TIM_Mode = TIM_Mode_UserDefine;
// TIM_CLOCK_DIVIDER_1 40M时钟源
TIM_InitStruct.TIM_SOURCE_DIV = TIM_CLOCK_DIVIDER_1;
TIM_TimeBaseInit(light->tim_id, &TIM_InitStruct);
/* Enable PWM output */
TIM_Cmd(light->tim_id, ENABLE);
2. PWM引脚初始化
#define timer_pwm0 13
#define timer_pwm1 14
#define timer_pwm2 15
#define timer_pwm3 16
#define timer_pwm4 17
#define timer_pwm5 18
#define timer_pwm6 19
#define timer_pwm7 20
Pad_Config(light->pin_num, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,
PAD_OUT_LOW);
Pinmux_Config(light->pin_num, timer_pwm2);
3. PWM调光
动态改变占空比,可以通过1个timer,循环去改变占空比。设定当前值和目标值,timer运行直到两者相等。几乎大部分的调光逻辑都是这样子。就是线性调光,可以通过其他的曲线去实现。比如贝塞尔曲线。
if (light->pin_high_on)
{
TIM_PWMChangeFreqAndDuty(light->tim_id, high_count, total_pwm_count - high_count);
}
else
{
TIM_PWMChangeFreqAndDuty(light->tim_id, total_pwm_count - high_count, high_count);
}
4. PWM互补输出
什么叫互补输出。我的理解是两路PWM, PWM1和PWM2。 这两路PWM1+PWM2的占空比合起来是100%。并且PWM1输出高的时候,PWM2输出低电平。
互补输出的应用场景暂时没有设计。
RTL8762C只有TIM2是支持互补输出的。可以参考SDK里面的demo例子。
5.RTL8762C在PWM占空比上的缺陷
RTL8762C这款芯片的PWM有一个BUG,就是无法达到100%或者0%占空比。如果要在100%亮度时让PWM输出全高电平,只能通过切换pad引脚的功能来实现。
#if MZ_FIX_PWM_100
if (lightness == 0 || 0xffff == lightness) {
light->lightness = lightness;
if (!light->gpio_func) {
light->gpio_func = 1;
light_pin_config_gpio(light, lightness == 0 ? 0 : 1);
}
return;
} else {
if (light->gpio_func) {
light->gpio_func = 0;
light_pin_config(light);
}
}
#endif