本次项目中遇到了定时器的PWM功能,之前没有使用过这个功能,调试好后做以下记录。
我使用的是STM32F103RCT6单片机,使用了PB0引脚。工程需求是通过PB0的PWM输出50Hz,占空比可调的波形。
理论部分不多说,网上有很多好的资源,以及ST官方的文档描述的很详尽。
STM32 PWM功能,可以引用一个图片:
下面贴上测试的代码
#ifndef __STM32F10X_H#define __STM32F10X_H#include "stm32f10x.h"#endif#ifndef __Z_HARDWARE_PWM_H#define __Z_HARDWARE_PWM_H#include "z_hardware_pwm.h"#endifint main(){init_hardware_pwm(59999, 23);//72*10^6/(59999+1)/(23+1)=50Hzfunc_set_pwm_compare(70);for(;;);}
驱动C代码如下:
#ifndef __Z_HARDWARE_PWM_H#define __Z_HARDWARE_PWM_H#include "z_hardware_pwm.h"#endifvoid init_hardware_pwm(uint16_t arr, uint16_t psc){GPIO_InitTypeDef GPIO_InitStructure;//PB0 -> TIM3TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_OCInitTypeDef TIM_OCInitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);//GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;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 = TIM_CKD_DIV1;TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;TIM_OC3Init(TIM3, &TIM_OCInitStructure);//TIM_OC3 ͨµÀ3TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);TIM_Cmd(TIM3, ENABLE);}void func_pwm_enable(void){TIM_Cmd(TIM3, ENABLE);}void func_pwm_disable(void){TIM_Cmd(TIM3, DISABLE);}void func_set_pwm_compare(uint8_t rate)//, uint16_t psc{long tmp = 60000;if(rate == 0){func_pwm_disable();return;}if(rate > 100){return;}func_pwm_enable();tmp = tmp * rate / 100;TIM_SetCompare3(TIM3, tmp);}
驱动的H文件如下:
#ifndef __STM32F10X_H#define __STM32F10X_H#include "stm32f10x.h"#endifvoid init_hardware_pwm(u16 arr, u16 psc);void func_pwm_enable(void);void func_pwm_disable(void);void func_set_pwm_compare(u8 rate);
按照上述文件,即可以现实PB0端口的PWM输出,通过 func_set_pwm_compare(70); 来设置占空比。
需要注意的是 使用的端口,是对应哪个定时器的那个通道的。例如TIM_OC3Init(TIM3, &TIM_OCInitStructure);//TIM_OC3的设置,设置了PB0使用定时器3通道3。