STM32
Contents
原理概述
CubeMX配置
HAL库编程实现
MCU型号:STM32F103RCT6
1 原理概述
利用定时器输出比较模式的翻转功能来输出PWM,即当CNT 计数到CCR 时,翻转一次OCx 电平:
注意:不能使能输出比较预装载功能,否则向CCR寄存器写入值是不会立即生效,需要等待下次更新事件触发时才生效。
2 CubeMX配置
配置TIM3_CH1通道:
- 选择TIM_CLK为内部时钟源(pclk2),同时设置CH1通道为输出比较模式
- 将PSC设为71,即用1M频率去计数
- 自动重装载值ARR设为最大
- 输出比较模式设为翻转模式
- Pulse即CRR寄存器值,默认为0即可,后面软件编程修改
- Output compare preload输出比较预装载:disable(修改CCR值立即生效)
使能定时器中断:
3 HAL库编程实现
uint16_t period_val, duty_val;
void compare_pwm_set(uint32_t freq, uint8_t duty)
{
period_val = 1000000 / freq;
duty_val = period_val * duty / 100;
htim3.Instance->CCR1 = period_val;
}
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{
static uint8_t pwm_flag = 1;
if (htim == &htim3)
{
if (pwm_flag)
htim3.Instance->CCR1 += duty_val;
else
htim3.Instance->CCR1 += period_val - duty_val;
pwm_flag = !pwm_flag;
}
}
第一次进入输出比较回调函数时,由于定时器翻转前的电平为低电平,因此会翻转为高电平,因此先将CCR1 寄存器值设为脉宽值,即高电平持续时间
第二次进入输出比较回调函数时,将先前的高电平翻转为低电平,因此将CCR1 值设为period_val - duty_val ,即低电平持续时间
int main(void)
{
[...]
MX_TIM3_Init();
compare_pwm_set(100000, 30);
HAL_TIM_OC_Start_IT(&htim3, TIM_CHANNEL_1);
while (1)
{
}
}
测试结果:
周期10us换算为频率即为100000HZ。
注意:由于最大计数频率为1MHZ,此时100K HZ的频率已为极限值,因为period_val 为10,即此时占空比的精度已达到了10%,对于不能被10整除的占空比已无法实现了。
period_val = 1000000 / freq
duty_val = period_val * duty / 100
例如将占空比修改为35%compare_pwm_set(100000, 35) :
最终结果还是30%。
如果需要再提高频率,可以减小PSC数值,把计数频率提上去。
END
|