在PA0引脚输出PWM波驱动LED,这里的接法是正极性驱动:高电平点亮、低电平熄灭
初始化PWM
![](https://i-blog.csdnimg.cn/blog_migrate/66aa40bf2d164412ea7b5b380e1b5066.png)
第一步,开启RCC时钟,把TIM外设和GPIO的外设时钟打开
第二步,配置时基单元,包括时钟源选择
第三步,配置输出比较单元,包括CCR的值、输出比较模式、极性选择、输出使能这些参数,库函数里也是统一用结构体来配置的
第四步,配置GPIO,把PWM对应的GPIO口,初始化复用推挽输出的配置
第五步,运行控制,启动计数器,这样才能输出PWM
void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
*用来配置输出比较模块的
void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct);
*给输出比较结构体赋一个默认值的
void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState);
*这个函数是专门给高级定时器使用的,高级定时器输出PWM,需调用使能主输出,否则PWM无法正常输出
void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
*用来配置强制输出模式,运行中强制暂停输出高电平或者低电平可用,但用得不多,因为强制输出高电平和占空比100%是一样的,强制输出低电平和占空比0%是一样的
void TIM_CCPreloadControl(TIM_TypeDef* TIMx, FunctionalState NewState);
void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
*用来配置CCR寄存器预装功能,预装功能就是影子寄存器,写入的值不会立即生效,而是会在更新事件后生效,一般也不用
void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
*用来快速使能的,用得也不多
void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
*手册中,外部事件时清除REF信号这一节有介绍
void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC2NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC3NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
*单独设置输出比较功能极性的,带N的就是高级定时器输出互补通道的配置,这里设置极性和在结构体设置作用是一样的
void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx);
void TIM_CCxNCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCxN);
*单独修改输出使能参数
void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode);
*选择输出比较模式
void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);
void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2);
void TIM_SetCompare3(TIM_TypeDef* TIMx, uint16_t Compare3);
void TIM_SetCompare4(TIM_TypeDef* TIMx, uint16_t Compare4);
*单独更改CCR寄存器值,在运行时,更改占空比要用到
该初始化哪个GPIO口?
![](https://i-blog.csdnimg.cn/blog_migrate/ece82ff9c0b2dcf64cf414ba515ad614.png)
为什么GPIO口配置为复用推挽输出?
如何使用端口重映射?
![](https://i-blog.csdnimg.cn/blog_migrate/628b2aed025ff90a46325486856c757c.png)
PWM驱动舵机
频率=1/时间(秒)
20ms是舵机的要求
PWM驱动直流电机
电机会发生蜂鸣器的声音,因为电机里面也是线圈和磁铁,在PWM驱动下就会发生蜂鸣器的声音
如何解决?加大PWM频率,超出人耳的范围20Hz~20KHz