stm32f103c8t6标准库舵机
时间: 2025-01-17 07:04:36 浏览: 36
STM32F103C8T6 使用标准库控制舵机
对于STM32F103C8T6单片机而言,通过PWM信号来实现对舵机的精确控制是一种常见的方式。下面提供一段基于STM32标准库编写的用于控制舵机转动角度的示例代码。
初始化配置
为了使能定时器通道作为PWM输出端口,在main()
函数之前定义必要的头文件并完成相应的初始化设置:
#include "stm32f10x.h"
// 定义其他所需的头文件...
void TIM_PWMInit(void){
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO ,ENABLE);
// 配置PA0为复用推挽输出模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
// 设置自动重装载寄存器ARR和预分频系数PSC
TIM_TimeBaseStructure.TIM_Period = 999; /* 自动重载值 */
TIM_TimeBaseStructure.TIM_Prescaler = 71; /* 预分配值 */
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
// PWM模式1配置
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
}
此部分完成了硬件资源的基础设定工作,包括但不限于开启时钟、指定I/O引脚功能以及调整计数器参数等操作[^1]。
主程序逻辑
接下来展示如何利用上述已准备好的环境编写主循环中的业务处理流程:
int main(void) {
float angle = 0.0f;
// 启动前先做一次完整的初始化动作
TIM_PWMInit();
OLED_Init(); // 假设有OLED显示屏辅助显示当前状态
key_init(); // 键盘扫描模块启动
while (true) {
static uint8_t last_key_state = 0;
// 获取按键输入情况
int8_t current_key = key_getnumber();
if(current_key != last_key_state && current_key == 1){
angle += 30.0f;
// 边界条件判断
if(angle >= 180.0f || angle < 0.0f){
angle -= 30.0f;
}
// 更新PWM占空比以改变舵机位置
UpdateServoPosition(angle);
}
// 显示实时的角度信息到屏幕
DisplayAngleOnScreen(angle);
last_key_state = current_key;
}
}
/**
* @brief 根据给定的角度更新PWM波形从而移动舵机至目标方位
*
* @param[in] target_angle 目标旋转角(单位:度)
*/
static void UpdateServoPosition(float target_angle){
uint16_t pulse_width_us = MapDegreeToMicroseconds(target_angle);
SetPWMPulseWidth(pulse_width_us);
}
/**
* @brief 将角度映射成对应的微秒级脉冲宽度
*
* @param[in] degree 输入的角度范围应位于[0~180]
* @return 对应于该角度下的脉宽时间(us)
*/
uint16_t MapDegreeToMicroseconds(float degree){
const float min_pulse_width = 544.f; // 最小有效脉宽约为0.5ms
const float max_pulse_width = 2400.f; // 最大有效脉宽约等于2.4ms
return lround(min_pulse_width + ((max_pulse_width-min_pulse_width)/180.f)*degree);
}
/**
* @brief 设定PWM周期内的高电平持续时间为pulse_width_us微秒
*
* @param[in] pulse_width_us 待设定位宽的时间长度(μs)
*/
void SetPWMPulseWidth(uint16_t pulse_width_us){
// 计算CCR寄存器数值...
uint16_t CCRValue = ... ; // 这里省略具体计算过程
// 应用新的比较匹配值
TIM_SetCompare1(TIM2, CCRValue);
}
以上代码片段展示了从接收外部指令到最后执行实际运动命令的整体架构。其中涉及到几个重要的概念转换环节,比如将物理世界里的角度变换成为电子器件能够理解的形式——即特定频率范围内变化着的方波信号;再者就是针对不同型号舵机产品可能存在的差异性做出适当调整[^2]。
相关推荐



















