在STM32中控制舵机,实际上就是开发STM32上的PWM功能,这部分功能需要配置STM32的定时器和GPIO复用共功能,然后就是通过修改定时器计数器的比较寄存器的数值来达到控制PWM的高电平占空比的目的;
这里以stm32f103c8t6t定时器2为例,说明一下具体的实现
tim2.c
//头文件
#include "tim2.h"
#include "stm32f10x.h"
#include "stm32f10x_tim.h"
void TIM2_Init(void)//定时器2
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
//定时器2配置
TIM_TimeBaseStructure.TIM_Period =20000-1; //自动重装载值
TIM_TimeBaseStructure.TIM_Prescaler = 72-1;//预分频系数
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
//PWM配置
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//pwm1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OCInitStructure.TIM_OCPolarity =TIM_OCPolarity_High;
//tim2通道
TIM_OC1Init(TIM2, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable); //ʹÄÜTIM2ÔÚCCR1ÉϵÄԤװÔؼĴæÆ÷
TIM_OC2Init(TIM2, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable); //ʹÄÜTIM2ÔÚCCR2ÉϵÄԤװÔؼĴæÆ÷
TIM_OC3Init(TIM2, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable); //ʹÄÜTIM2ÔÚCCR3ÉϵÄԤװÔؼĴæÆ÷
TIM_OC4Init(TIM2, &TIM_OCInitStructure);
TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable); //ʹÄÜTIM2ÔÚCCR4ÉϵÄԤװÔؼĴæÆ÷
TIM_ARRPreloadConfig(TIM2, ENABLE);
TIM_Cmd(TIM2, ENABLE);
}
void GPIO_Init(void)//GPIO
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void dj(int l1,int l2,int r1,int r2)//舵机控制函数
{
TIM2->CCR1 = l1; //A0
TIM2->CCR2 = l2; //A1
TIM2->CCR3 = r1; //A2
TIM2->CCR4 = r2; //A3
}//end
在代码中要特别注意的是时基结构体的TIM_Period(自动重装载寄存器值,简称arr)和TIM_Prescaler(预分频寄存器值,简称psc),因为这两个决定了输出PWM信号的周期。具体的周期计算公式为:周期=(arr+1)*(psc+1)/CLK。其中CLK为计数器的时钟频率,我的是72MHZ,也就是72000000。最后计算结果单位为秒,结果为0.02s,也就是20ms。这样的配置就是为了让输出的PWM信号达到舵机要求的20ms周期。
tim2.h
#ifndef __TIM2_h
#define __TIM2_h
void TIM2_Init(void); //定时器2
void dj(int l1,int l2,int r1,int r2);//舵机控制函数
void GPIO_Init(void); //GPIO
#endif
主函数
#include "tim2.h"
//#include "delay.h"
int main(void)//主函数
{
GPIO_Init();
TIM2_Init();
dj(1500,1500,2500,1500);
while(1)//´óÑ»·
{
dj(1000,1500,2500,1500);
}
}