前言:写上一篇单一定时器输出四路PWM时就想过能否输出四路不同频率及占空比的PWM波形,最近有空就花时间研究了一下,首先定时器的频率在ARR和PSC设置好之后就已经锁定了,要输出不同频率的波形需要使用TIM_OCMode_Toggle电平翻转模式,在中断中动态修改CRR比较寄存器的值来控制电平不断翻转实现不同频率波形
程序效果演示
STM32单一定时器输出四路不同频率及占空比的PWM波
一、程序思路
因为定时器只有一个CNT计数器所以只能有一个输出频率,若要实现多路不同频率波形,只能通过在当前CNT计数器的基础上不断累加自身CCR寄存器的值来触发中断在中断中翻转波形的方式,此时中断触发的频率即为波形的频率(CLOCK/PSC/ARR*(ARR/CRR每次加的数字大小));PS:CNT计数器与CCR寄存器都不存在数据溢出的风险,当数据值大于65535后会自动将多出的不分从0开始计数,所以不需要单独处理这部分数据。
二、程序实现
1、创建所需变量数组
//定义通道1的CCR比较值
uint16_t CCR_Value[4] = {
5000,10000,15000,20000};
//设置各通道的占空比大小
float Duty_Ratio[4] = {
0.5,0.6,0.7,0.8};
//定义一个标志位用于存放是高电平中断还是低电平中断,初始为高电平
uint8_t flag[4] = {
0,0,0,0};
//用于存放各个通道中断时的CNT计数器值
uint32_t CNT[4] = {
0,0,0,0};
2、配置GPIO
//开启相关GPIO外设时钟
RCC_AHB1PeriphClockCmd (RCC_AHB1Periph_GPIOA, ENABLE);
RCC_AHB1PeriphClockCmd (RCC_AHB1Periph_GPIOB, ENABLE);
// 定时器3引脚复用 注:引脚复用函数参数只能有一个引脚不能同一个方法填写多个
GPIO_PinAFConfig(GPIOA,GPIO_PinSource6,GPIO_AF_TIM3);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource7,GPIO_AF_TIM3);
GPIO_PinAFConfig(GPIOB,GPIO_PinSource0,GPIO_AF_TIM3);
GPIO_PinAFConfig(GPIOB,GPIO_PinSource1,GPIO_AF_TIM3);
//定义结构体用于初始化GPIO
GPIO_InitTypeDef GPIO_InitStructure;
//初始化GPIOA
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed