STMF103C8T6的舵机转动教程

前情提要

对于市面上的舵机,所要求的周期基本都为20ms。

对应的转动角度,0°->0.5ms,180°->2.5ms

CubeMX配置单片机

1.通用配置

首先就是设置高速时钟,选择第三个。

然后就是设置Debug模式了,这里是serial wire 模式,一般我们就用STLINK进行调试烧录就行了。当然了STM32也有无线烧录器,但是太贵了,我买不起(bushi)。

2.时钟设置

首先是设置时钟频率,直接设置最大72MHZ就好了,这里时钟频率越大,单片机的运算速率也就越大,所以我们在使用F1或者其他种类的单片机时,当然是单片机的运算速率越快越好。

时钟源选择内部时钟 Internal clock 。我们这里pwm输出引脚就选择Channel1吧,如图进行设置,然后可以在右图单片机的示意图中看到PA8点亮了。所以PA8引脚就是TIM1的CH1的输出引脚,当然一个引脚常常是有多种功能的,此处就不过多展开了。

再看后续的PSC(预分频系数)与ARR(自动重载值)

我们要求舵机转动的周期为20ms也就是50HZ

那么f=72000000/(PSC+1)*(ARR+1)   这里72000000就是前面设置的72MHZ了。

那么如何理解PSC和ARR呢?

PSC就相当于将原本的72M分为PSC+1份,ARR就是吧PSC又分了为ARR+1份;

3.其他设置

单片机的开发一般主流为KEIL 或者说配套的cubeIDE 或者说小众的Clion.

对于toolchain第一种软件要选择MDK-ARM,后两者就选择CubeIDE

注意:项目名只能是英文,不能有空格

在设置时最好将头文件与代码主题分离,便于后续大项目的操作,或者“借鉴他人代码”。

代码解释与占空比的理解

这里作者使用HAL库进行开发。

HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1)开启时钟;

__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,15)设置引脚输出电压;

占空比就位这个函数最后一个整数值15/200,此时占空比就位7.5%。

即占空比=x/ARR,那么前面说的0°对应的0.5ms又是什么呢?

就是计数器的周期(1/f)乘以占空比。

#include "servo.h" unsigned int Servo_Angle = 0;//舵机角度 /****************************************************************** * 函 数 名 称:SG90_Init * 函 数 说 明:PWM配置 * 函 数 形 参: pre定时器时钟预分频值 per周期 * 函 数 返 回:无 * 作 者:LC * 备 注:PWM频率=84 000 000 /( (pre+1) * (per+1) ) 配置占空比 范围 0 ~ (per-1) // t = 0.5ms——————-舵机转动 0 ° // t = 1.0ms——————-舵机转动 45° // t = 1.5ms——————-舵机转动 90° // t = 2.0ms——————-舵机转动 135° // t = 2.5ms——————-舵机转动180° // 1.我该如何计算括号里的数,从而实现我想要的功能? // 此处以90度为例。 // 答:PWM周期为20ms,所以占空比就应该为1.5ms/20ms = 7.5%, // 所以 TIMx 捕获比较 1 寄存器值就为period-period*7.5% = 84-84*7.5%=77.7 ******************************************************************/ void SG90_Init(void) { /* 配置定时器参数 */ // 频率f =系统时钟 / ( (prescaler+1) * (period+1) ) // 频率f = 84,000,000/ (8400 * 200) = 50hz // 周期T = 1/f = 1/50 = 0.02S = 20ms GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器3时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能GPIO外设 //设置该引脚为复用输出功能,输出TIM3 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStructure);//初始化GPIO // GPIO_PinAFConfig(PORT_SIG, GPIO_SIG_SOURCE, AF_SIG); //复用 //初始化TIM3 //配置占空比 范围 0 ~ (per-1) // t = 0.5ms——————-舵机转动 0 ° // t = 1.0ms——————-舵机转动 45° // t = 1.5ms——————-舵机转动 90° // t = 2.0ms——————-舵机转动 135° // t = 2.5ms——————-舵机转动180° // 1.我该如何计算括号里的数,从而实现我想要的功能? // 此处以90度为例。 // 答:PWM周期为20ms,所以占空比就应该为1.5ms/20ms = 7.5%, // 所以 TIMx 捕获比较 1 寄存器值就为period-period*7.5% = 84-84*7.5%=77.7 TIM_TimeBaseStructure.TIM_Period = 2000-1; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 TIM_TimeBaseStructure.TIM_Prescaler =72-1; //设置用来作为TIMx时钟频率除数的预分频值 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // 时钟分频 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式 TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位 //初始化TIM3 Channel1 PWM模式 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能 TIM_OCInitStructure.TIM_Pulse = 0; //设置占空比大小,在主函数compare中又设置一遍 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性 TIM_OC1Init(TIM3 ,&TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC1 TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR1上的预装载寄存器 TIM_Cmd(TIM3, ENABLE); //使能TIM3 } /****************************************************************** * 函 数 名 称:Set_Servo_Angle * 函 数 说 明:设置角度 * 函 数 形 参:angle=要设置的角度,范围0-180 * 函 数 返 回:无 * 作 者:LC * 备 注:无 ******************************************************************/ void Set_Servo_Angle(unsigned int angle) { if(angle > 180) { angle = 180; // 限制角度在0到180度之间 } // 计算PWM占空比 // 注意:这里的200是基于TIM_Period设置为199的(200-1) // 0.5ms对应的计数 = (0.5 / 20) * 200 // 2.5ms对应的计数 = (2.5 / 20) * 200 // 因此,角度从0到180度时,占空比应该从0.5ms到2.5ms线性变化 unsigned int ServoAngle = (unsigned int)((0.5 + (angle / 180.0) * 2.0) / 20.0 * 200); TIM_SetCompare1(TIM3, ServoAngle); } /****************************************************************** * 函 数 名 称:读取当前角度 * 函 数 说 明:Get_Servo_Angle * 函 数 形 参:无 * 函 数 返 回:当前角度 * 作 者:LC * 备 注:使用前必须确保之前使用过 void Set_Servo_Angle(unsigned int angle) 函数设置过角度 ******************************************************************/ unsigned int Get_Servo_Angle(void) { return Servo_Angle; } STMF103C8T6控制舵机 改错 库函数
最新发布
06-19
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值