这是本文档旧的修订版!
PWM控制SG90舵机
// main.c #include "stm32f10x.h" // Device header #include "PWM.h" int main(void) { PWM_Init(); while(1); }
// PWM.c #include "stm32f10x.h" // Device header void PWM_Init(void) { // 时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); TIM_InternalClockConfig(TIM2); // 可不写这一句,上电默认内部时钟源 // 时基单元 TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStrucure; TIM_TimeBaseInitStrucure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInitStrucure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInitStrucure.TIM_Period = 359; // 【ARR】 TIM_TimeBaseInitStrucure.TIM_Prescaler = 3999; // 【PSC】 TIM_TimeBaseInitStrucure.TIM_RepetitionCounter = 0; //通用定时器没有重复计数器 TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStrucure); // 初始化输出比较OC TIM_OCInitTypeDef TIM_OCInitStruture; TIM_OCStructInit(&TIM_OCInitStruture); // 给结构体赋初始值,因为下面用不到结构体的全部成员 TIM_OCInitStruture.TIM_OCMode = TIM_OCMode_PWM1; // 模式PWM1 TIM_OCInitStruture.TIM_OCPolarity = TIM_OCPolarity_High; // REF有效时输出高电平(有效电平为高电平) TIM_OCInitStruture.TIM_OutputState = TIM_OutputState_Enable; // 输出使能 TIM_OCInitStruture.TIM_Pulse = 27; // 【CCR】 TIM_OC2Init(TIM2, &TIM_OCInitStruture); // 现在OC2就初始化好了,下面还需要初始化TIM2的OC2对应的GPIO口 // 不同定时器不同OC对应的GPIO是不同的,是固定的,需要查表,得是PA1口 // 配置GPIOA PIN1 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 要设置为复用推挽输出,原因看GPIO结构 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 启动定时器 TIM_Cmd(TIM2, ENABLE); /* 【计算公式】: Freq = CK_PSC / (PSC+1)*(ARR+1) 其中CK_PSC是72Mhz Duty = CCR / (ARR+1) Reso = 1 / (ARR+1) 注意:PSC,ARR,CCR都是16位的,在0-FFFF(0-65535)之间。 要输出频率50Hz,占空比5%,分辨率360的PWM波形: PSC = 3999,ARR = 359,CCR = 18 保持上述频率和分辨率不变,输出占空比10%的PWM波形,只需修改CCR = 36。 */ }