stm32 pwm同时输出输出四道方波
主要是在正点原子PWM输出实验的基础上修改所得
原本的代码
while(1)
{
delay_ms(10);
if(dir)led0pwmval++;
else led0pwmval--;
if(led0pwmval>300)dir=0;
if(led0pwmval==0)dir=1;
TIM_SetCompare2(TIM3,led0pwmval);
}
}
通过if判断led0pwmval的值实现从0到300的占空比的改变,这里着重强调一下TIM_SetCompare2函数的2指的是输出TIM3的通道2的波,若要使用其他通道则使用TIM_SetCompare1||TIM_SetCompare3||TIM_SetCompare4。
这次的作业要求是输出四路同步的PWM波要求两路为100KHz,占空比为25%,两路为2KHz,占空比为50%;整个周期分为四个阶段sig1在T1为高电平,sig2在T2为高电平,sig3在T1~T2为高电平, sig4在T3~T4为高电平.
首先根据输出频率的不同,我们在main中,额外添加TIM3_PWM_Init(720-1,0); TIM2_PWM_Init(36000-1,0);
分别配置定时器2与定时器3的输出频率为2k和100k;
在while中我们添加了`:
TIM_SetCompare2(TIM3,180);
TIM_SetCompare1(TIM3,540);
TIM_SetCompare3(TIM2,18000);
TIM_SetCompare4(TIM2,18000);
来配置定时器2的通道3和通道4;定时器3的通道1和通道2;这时我们已经打完了在主函数中的内容。
接下来我们开始写timer.c中的内容
有关定时器2中断的配置与定时器3基本相似,这里不再进行赘述。
在timer.c中主要修改的内容在TIM3_PWM_Init()
我们将在这个函数中通过
RCC_APB1PeriphClockCmd //使能定时器时钟
RCC_APB2PeriphClockCmd //使能GPIO外设与IO口的复用
GPIO_PinRemapConfig() //将Timer3的部分重映射到GPIO口上
GPIO_Init() //配置IO口
TIM_TimeBaseInit() //设置时钟频率、预分频等 初始化TIM3
TIM_OC1PreloadConfig() //注意这里是使能通道1,不同的通道 TIM_OCx x的数值不同要与在main.c中的通道匹配 初始其PWM模式
这里的这个函数时可以重复使用的比如先配置完定时器2的通道1后再使用一次去配置定时器3的通道1,这
里的变量设置我在后面的代码片里会贴出来
以上为timer.c中需要配置的全部内容,主要要注意的方面
- 注意输出的IO口要与定时器的通道匹配
- IO口与定时器的重映射模式要改为FullRemap(完全重映射)
GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE); //我也不知道为啥部分重映射不行,希望了解的大佬能在评论区讲下,多谢。
TIM_OC1PreloadConfig
注意使能的通道要与使用的通道相匹配。
关于PWM波的具体配置
配置PWM波主要配置的就是几个参数
TIM3_PWM_Init(arr,psc)
中的arr寄存器设置PWM波频率TIM_SetCompare1(TIMx,ccr)
中的ccr寄存器设置PWM波的占空比,占空比=ccr/arr- 在timer.c中对变量TIM_OCInitStructure的配置
分别为TIM_OCMode //定时器模式 TIM_OutputState //比较输出使能 TIM_OCPolarity //输出极性
其中关于定时器模式和输出极性的配置和TIM_TimeBaseStructure.TIM_CounterMode
是影响GPIO输出高低电平的主要参数
具体参看正点原子的PWM输出实验PPT或中文参考手册里面写的很详细。
以下为timer.c中的部分配置代码
void TIM2_PWM_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
GPIO_PinRemapConfig(GPIO_FullRemap_TIM2, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11; //TIM_CH2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
TIM_TimeBaseStructure.TIM_Period = arr;
TIM_TimeBaseStructure.TIM_Prescaler =psc;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC3Init(TIM2, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OC4Init(TIM2, &TIM_OCInitStructure);
TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable);
TIM_Cmd(TIM2, ENABLE);
}
另外非常感谢hxl学长提供的帮助
以上