当前位置: 首页 > news >正文

基于STM32F103ZET6实现6路舵机控制

一、硬件连接

1. 电路连接
定时器通道对应引脚舵机编号
TIM2CH1PA0舵机1
TIM2CH2PA1舵机2
TIM2CH3PA2舵机3
TIM2CH4PA3舵机4
TIM3CH1PC6舵机5
TIM3CH2PC7舵机6
2. 电源要求
  • 每个舵机需独立供电(建议5V/2A)
  • 逻辑部分供电3.3V

二、软件实现代码

1. 定时器初始化(TIM2+TIM3)
#include "stm32f10x.h"#define SERVO_PWM_FREQ 50    // 50Hz
#define SERVO_PULSE_MIN 500  // 0.5ms
#define SERVO_PULSE_MAX 2500 // 2.5msvoid TIM2_TIM3_PWM_Init() {GPIO_InitTypeDef GPIO_InitStruct;TIM_TimeBaseInitTypeDef TIM_InitStruct;TIM_OCInitTypeDef TIM_OCInitStruct;// 使能时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM3, ENABLE);// GPIO配置(复用推挽输出)GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;// TIM2通道配置 (PA0-PA3)GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;GPIO_Init(GPIOA, &GPIO_InitStruct);// TIM3通道配置 (PC6-PC7)GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;GPIO_Init(GPIOC, &GPIO_InitStruct);// 定时器基础配置TIM_InitStruct.TIM_Prescaler = 72 - 1;          // 预分频 1MHzTIM_InitStruct.TIM_CounterMode = TIM_CounterMode_Up;TIM_InitStruct.TIM_Period = 20000 - 1;          // 20ms周期TIM_InitStruct.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseInit(TIM2, &TIM_InitStruct);TIM_TimeBaseInit(TIM3, &TIM_InitStruct);// PWM模式配置TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;TIM_OCInitStruct.TIM_Pulse = SERVO_PULSE_MIN;TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;// 配置TIM2通道TIM_OC1Init(TIM2, &TIM_OCInitStruct);TIM_OC2Init(TIM2, &TIM_OCInitStruct);TIM_OC3Init(TIM2, &TIM_OCInitStruct);TIM_OC4Init(TIM2, &TIM_OCInitStruct);// 配置TIM3通道TIM_OC1Init(TIM3, &TIM_OCInitStruct);TIM_OC2Init(TIM3, &TIM_OCInitStruct);// 使能定时器TIM_Cmd(TIM2, ENABLE);TIM_Cmd(TIM3, ENABLE);
}
2. 舵机控制核心代码
typedef struct {uint16_t target_pulse;  // 目标脉宽uint16_t current_pulse; // 当前脉宽float angle;            // 当前角度
} ServoCtrl;ServoCtrl servos[6] = {0};// 角度转脉宽
uint16_t AngleToPulse(float angle) {return SERVO_PULSE_MIN + (angle / 180.0f) * (SERVO_PULSE_MAX - SERVO_PULSE_MIN);
}// 初始化舵机参数
void Servo_Init() {for(int i=0; i<6; i++) {servos[i].angle = 0.0f;servos[i].current_pulse = AngleToPulse(0.0f);servos[i].target_pulse = AngleToPulse(0.0f);}
}// 设置舵机角度
void Servo_SetAngle(uint8_t index, float angle) {if(index >= 6) return;angle = angle > 180.0f ? 180.0f : angle < 0.0f ? 0.0f : angle;servos[index].target_pulse = AngleToPulse(angle);
}// PWM中断服务函数
void TIM2_IRQHandler() {if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) {static uint8_t channel = 0;// 更新各通道占空比TIM_ClearITPendingBit(TIM2, TIM_IT_Update);switch(channel) {case 0: TIM_SetCompare1(TIM2, servos[0].current_pulse); break;case 1: TIM_SetCompare2(TIM2, servos[1].current_pulse); break;case 2: TIM_SetCompare3(TIM2, servos[2].current_pulse); break;case 3: TIM_SetCompare4(TIM2, servos[3].current_pulse); break;case 4: TIM_SetCompare1(TIM3, servos[4].current_pulse); break;case 5: TIM_SetCompare2(TIM3, servos[5].current_pulse); break;}channel = (channel + 1) % 6;}
}

三、关键参数配置

1. 定时器计算
系统时钟:72MHz
预分频:72-11MHz计数频率
周期值:2000020ms周期
占空比范围:500-2500(对应0.5ms-2.5ms)
2. 角度控制算法
// 平滑角度过渡(增量控制)
void Servo_Update() {for(int i=0; i<6; i++) {float error = servos[i].target_pulse - servos[i].current_pulse;float step = error * 0.1f;  // 调整步长(0.1-0.5)if(step > 0) {servos[i].current_pulse += (uint16_t)step;if(servos[i].current_pulse > servos[i].target_pulse)servos[i].current_pulse = servos[i].target_pulse;} else {servos[i].current_pulse += (uint16_t)step;if(servos[i].current_pulse < servos[i].target_pulse)servos[i].current_pulse = servos[i].target_pulse;}}
}

四、主程序流程

int main() {// 系统初始化NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);Delay_Init();Servo_Init();TIM2_TIM3_PWM_Init();// 设置初始角度Servo_SetAngle(0, 90.0f);  // 舵机1→90°Servo_SetAngle(3, 45.0f);  // 舵机4→45°while(1) {Servo_Update();  // 更新角度Delay_ms(20);    // 20ms刷新周期}
}

五、扩展

1. 多机同步控制
// 同步更新所有通道
void Servo_SyncUpdate() {TIM_SetCompare1(TIM2, servos[0].current_pulse);TIM_SetCompare2(TIM2, servos[1].current_pulse);TIM_SetCompare3(TIM2, servos[2].current_pulse);TIM_SetCompare4(TIM2, servos[3].current_pulse);TIM_SetCompare1(TIM3, servos[4].current_pulse);TIM_SetCompare2(TIM3, servos[5].current_pulse);
}
2. 连续旋转模式
// 设置连续旋转速度(0-200rpm)
void Servo_SetSpeed(uint8_t index, int16_t speed) {if(speed > 0) {servos[index].target_pulse = SERVO_PULSE_MIN + (speed * 2000 / 200);} else {servos[index].target_pulse = SERVO_PULSE_MAX + (speed * 2000 / 200);}
}

参考代码 STM32F103ZET6同时控制6个舵机的程序 www.youwenfan.com/contentcsj/71392.html

六、完整工程结构

├── Drivers/
│   ├── CMSIS/
│   └── STM32F10x_HAL_Driver/
├── Middlewares/
│   └── Servo_Control/      # 舵机控制库
│       ├── servo.c
│       └── servo.h
├── Applications/
│   └── main.c            # 主程序入口
└── Projects/└── STM32F103ZET6/├── startup_stm32f10x_hd.s└── system_stm32f10x.c
http://www.dtcms.com/a/506723.html

相关文章:

  • 【案例实战】鸿蒙分布式智能办公应用的架构设计与性能优化
  • 嘉兴网站排名优化价格环保网站 中企动力建设
  • 网站注册页面html网站建设邀标书
  • spring AOP失效的原因
  • 阿里云国际代理:阿里云备份如何保障数据安全?
  • Elasticsearch面试精讲 Day 25:Elasticsearch SQL与数据分析
  • Spring Boot 3零基础教程,WEB 开发 Thymeleaf 总结 热部署 常用配置 笔记44
  • 从概念到代码:4A架构(业务架构、数据架构、应用架构、技术架构)全景落地指南
  • 深入解析 ZeroMQ 请求-应答模式:服务端实现与全链路测试指南 || 测试ZMQ重连重试机制
  • 五行八卦知识介绍和科学的关系
  • 做公司网站客户群体怎么找数据库怎么存储wordpress
  • 拉力猫指纹浏览器配置 Novproxy 代理 IP 教程:从参数设置到连接验证全流程
  • 深圳购物网站建设公司wordpress插件无法安装
  • 内网用户无法通过公网IP访问内网服务器:NAT回流问题
  • 【高并发服务器】Socket套接字类 Channel事件管理类设计与实现
  • Linux服务器编程实践52-SO_LINGER选项:控制close关闭TCP连接的行为
  • 【Docusaurus】子路径配置后,build 报错 Error: Unable to build website for locale en
  • wordpress 网站变慢深圳龙华邮政编码是多少
  • 【服务器】服务器被攻击植入了挖矿病毒,CPU一直占用100%,@monthly /root/.cfg/./dealer病毒清除
  • DevExpress WinForms v25.1亮点 - 电子表格组件、富文档编辑器全新升级
  • SVN冲突处理相关,标识 C 语言源文件(.c)的不同版本或冲突状态
  • 《掰开揉碎讲编程-长篇》重生之哈希表易如放掌
  • 【Python】绘制椭圆眼睛跟随鼠标交互算法配图详解
  • 【C++模版进阶】如何理解非类型模版参数、特化与分离编译?
  • 字符串专题总结:从模拟运算到模板掌握
  • 【Java链表】从概念结构到单向链表创建,增删查改全流程实战
  • 从C10K到Reactor:事件驱动,如何重塑高并发服务器的网络架构
  • 顺义做网站公司重庆企业网络推广软件
  • 淘宝怎么做网站郑州网站开发公
  • input + React自定义上传组件【可自定义拓展】