我現在要用AT9S PRO 跟R9DS加上SBUS轉UART模組 控制我的馬達前進後退左右轉 你可以教我怎麼設定嗎 一樣用UART4
时间: 2025-08-22 21:59:07 浏览: 3
<think>我們將使用SBUS協議來接收遙控器的信號。SBUS是一種串行通信協議,通常使用倒極性UART(即高電平為0,低電平為1),波特率為100000,8位數據,偶校驗(EVEN),2個停止位(通常描述為8E2)。但是,STM32的UART不支持直接設置倒極性,因此我們需要使用一個轉換模塊(硬體)將SBUS信號轉換為標準UART信號(通常為3.3V TTL電平)。
接線:
SBUS接收機(R9DS的SBUS輸出) -> SBUS轉UART模塊 -> STM32F407的UART4
注意:SBUS轉UART模塊會將SBUS信號轉換為標準UART信號(非倒極性),因此我們可以直接使用STM32的UART接收。
步驟:
1. 配置UART4為100000波特率,8位數據,偶校驗(EVEN),2個停止位(在STM32中,偶校驗和2停止位可以通過設置UART_CR1和UART_CR2來實現)。
2. 接收SBUS數據包(25字節,包括起始字節0x0F,22個通道數據(每個通道11位),標誌字節和結束字節0x00)。
3. 解析SBUS數據包,提取出各個通道的值(通常為16個通道,但SBUS數據包包含22個通道的數據,我們可以只取前4個通道)。
4. 將通道值轉換為電機控制信號(例如,通道1控制左右轉向,通道3控制前進後退)。
假設我們使用以下映射:
- 通道1(搖桿左右):控制轉向(左轉/右轉)
- 通道3(搖桿上下):控制前進後退
注意:SBUS通道值範圍通常為0-2047(11位),但實際使用中,搖桿中立點在992-1008左右,最小值約為352,最大值約為1696(不同遙控器可能有所不同,需要校準)。
我們將通道值轉換為電機控制速度:
- 前進後退:通道3的值,映射到電機速度(例如,中立點附近停止,向上推前進,向下拉後退)。
- 轉向:通道1的值,映射到左右電機差速(例如,向左推則左輪減速、右輪加速,實現左轉)。
我們需要設計一個混合控制(混控):
左側電機速度 = 前進速度 - 轉向量
右側電機速度 = 前進速度 + 轉向量
具體步驟如下:
1. UART4配置:100000波特率,8數據位,偶校驗,2停止位(在STM32中,偶校驗設置為UART_PARITY_EVEN,停止位設置為UART_STOPBITS_2)。
2. 接收數據:使用DMA或中斷接收25字節的SBUS數據包。注意:SBUS數據包每14ms發送一次(約72Hz),但也可以配置為7ms。
3. 解析數據包:根據SBUS協議解析。
4. 混控計算:將通道3和通道1的值轉換為電機速度。
5. 控制電機:根據計算出的速度設置電機PWM。
代碼實現:
首先,我們配置UART4:
在CubeMX中設置UART4:
- Baud Rate: 100000
- Word Length: 8 Bits
- Parity: Even
- Stop Bits: 2
- Receiver: Enable
或者使用代碼配置:
我們假設使用HAL庫。
定義SBUS數據包結構:
SBUS數據包共25字節:
Byte[0]: 起始字節 0x0F
Byte[1-22]: 22個通道的數據(每個通道11位,共22*8=176位,但實際用於16個通道,每個通道11位,共176位,但SBUS有18個通道,其中16個標準通道,2個數字通道,所以22字節可以容納)
Byte[23]: 標誌位(包括數字通道17和18,以及幀丟失和故障安全信息)
Byte[24]: 結束字節 0x00
注意:SBUS數據包是25字節,但我們需要連續接收,並且要處理同步(即找到起始字節0x0F和結束字節0x00)。
由於SBUS數據包是定長的,我們可以每次接收25字節,然後檢查起始和結束字節。
我們使用UART接收中斷,每次接收25字節,並在回調函數中解析。
在main.c中:</think>### SBUS遥控系统集成方案(STM32F407 + AT9S PRO + R9DS + SBUS转UART)
#### 系统架构
```
AT9S PRO遥控器 → R9DS接收机 → SBUS转UART模块 → UART4 (STM32F407) → 电机控制
```
#### 一、硬件连接与配置
1. **硬件接线**:
```
R9DS接收机 SBUS输出 → SBUS转UART模块 RX
SBUS转UART模块 TX → STM32F407 UART4_RX (PC11)
SBUS转UART模块 GND → STM32 GND
```
2. **遥控器设置**:
- 在AT9S PRO上进入「系统设置」→「接收机设置」
- 选择输出协议:SBUS
- 设置通道顺序(默认AETR):
- 通道1:方向左右(左摇杆X轴)
- 通道2:方向前后(左摇杆Y轴)
- 通道3:油门(右摇杆Y轴)
- 通道4:转向(右摇杆X轴)
3. **SBUS模块配置**:
- 确保模块设置为100kbps波特率
- 输出格式:标准UART(非反相)
#### 二、STM32代码实现
```c
#include "stm32f4xx_hal.h"
// UART4 句柄
UART_HandleTypeDef huart4;
// SBUS 协议参数
#define SBUS_PACKET_LEN 25
#define SBUS_HEADER 0x0F
#define SBUS_FOOTER 0x00
uint8_t sbus_data[SBUS_PACKET_LEN];
uint16_t channels[16]; // 16个通道数据
// 电机控制参数
int throttle = 0; // 油门值
int steering = 0; // 转向值
// UART4初始化
void MX_UART4_Init(void) {
huart4.Instance = UART4;
huart4.Init.BaudRate = 100000; // SBUS标准波特率
huart4.Init.WordLength = UART_WORDLENGTH_8B;
huart4.Init.StopBits = UART_STOPBITS_2; // SBUS需要2个停止位
huart4.Init.Parity = UART_PARITY_EVEN; // SBUS偶校验
huart4.Init.Mode = UART_MODE_RX;
huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart4.Init.OverSampling = UART_OVERSAMPLING_16;
HAL_UART_Init(&huart4);
// 启动DMA接收
HAL_UART_Receive_DMA(&huart4, sbus_data, SBUS_PACKET_LEN);
}
// SBUS数据解析
void Parse_SBUS(void) {
// 检查包头和包尾
if(sbus_data[0] != SBUS_HEADER || sbus_data[24] != SBUS_FOOTER)
return;
// 提取通道数据(11位/通道)
channels[0] = (sbus_data[1] | (sbus_data[2] << 8)) & 0x07FF;
channels[1] = ((sbus_data[2]>>3) | (sbus_data[3] << 5)) & 0x07FF;
channels[2] = ((sbus_data[3]>>6) | (sbus_data[4] << 2) | (sbus_data[5]<<10)) & 0x07FF;
channels[3] = ((sbus_data[5]>>1) | (sbus_data[6] << 7)) & 0x07FF;
// 获取油门和转向值(映射到-1000~1000)
throttle = (int)((channels[2] - 172) * 2000.0 / (1811 - 172) - 1000);
steering = (int)((channels[3] - 172) * 2000.0 / (1811 - 172) - 1000);
// 设置死区(防止摇杆微动)
if(abs(throttle) < 50) throttle = 0;
if(abs(steering) < 50) steering = 0;
}
// UART DMA接收完成回调
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
if(huart == &huart4) {
Parse_SBUS(); // 解析SBUS数据
HAL_UART_Receive_DMA(&huart4, sbus_data, SBUS_PACKET_LEN); // 重新启动接收
}
}
// 混控函数(根据油门和转向计算电机速度)
void Mixer_Control(void) {
int left_speed = throttle - steering;
int right_speed = throttle + steering;
// 限制速度范围
left_speed = (left_speed > 1000) ? 1000 : (left_speed < -1000) ? -1000 : left_speed;
right_speed = (right_speed > 1000) ? 1000 : (right_speed < -1000) ? -1000 : right_speed;
// 设置电机速度
Set_Motor(1, left_speed); // 左前
Set_Motor(2, left_speed); // 左后
Set_Motor(3, right_speed); // 右前
Set_Motor(4, right_speed); // 右后
}
// 主循环
int main(void) {
// 初始化代码...
while(1) {
Mixer_Control(); // 更新电机控制
HAL_Delay(10); // 10ms控制周期
}
}
```
### 三、关键代码解释
1. **SBUS协议解析**:
- SBUS使用100kbps波特率,8位数据,偶校验,2停止位
- 数据包固定25字节:0x0F(包头) + 22字节通道数据 + 1字节标志 + 0x00(包尾)
- 每个通道11位数据(范围172-1811,中立点992)
2. **通道映射**:
```c
// 典型通道映射
#define CH_THROTTLE 2 // 油门通道
#define CH_STEERING 3 // 转向通道
```
3. **混控算法**:
- 差速转向:`左速 = 油门 - 转向`,`右速 = 油门 + 转向`
- 速度范围限制在-1000~1000(对应PWM占空比)
4. **死区处理**:
```c
// 防止摇杆微动导致电机抖动
if(abs(throttle) < 50) throttle = 0;
```
### 四、调试步骤
1. **硬件测试**:
```mermaid
graph LR
A[AT9S PRO] -->|SBUS| B[R9DS接收机]
B -->|SBUS信号| C[SBUS转UART模块]
C -->|TTL UART| D[STM32 UART4]
D -->|逻辑分析仪| E[验证数据包]
```
2. **通道校准**:
```c
// 在main函数中添加调试输出
printf("Throttle: %d, Steering: %d\n", throttle, steering);
```
3. **遥控器校准**:
- 打开AT9S PRO菜单
- 进入「舵机行程」设置
- 将油门和转向摇杆推到最大位置进行校准
### 五、常见问题解决
1. **数据包不完整**:
- 检查接线是否正确(TX→RX,GND→GND)
- 确认SBUS模块供电稳定(3.3V)
- 添加硬件滤波电容(10uF)
2. **通道值跳动**:
```c
// 添加软件滤波
#define FILTER_SAMPLES 5
static int throttle_history[FILTER_SAMPLES] = {0};
// 中值滤波函数
int Median_Filter(int new_val) {
// 更新历史记录
for(int i=1; i<FILTER_SAMPLES; i++) {
throttle_history[i-1] = throttle_history[i];
}
throttle_history[FILTER_SAMPLES-1] = new_val;
// 排序并取中值
// ... 实现排序算法 ...
return throttle_history[FILTER_SAMPLES/2];
}
```
3. **响应延迟**:
- 使用DMA接收代替中断
- 优化控制循环周期(建议10-20ms)
### 六、安全机制
1. **故障保护**:
```c
// 在Parse_SBUS函数中添加
uint8_t flags = sbus_data[23];
// 检查故障安全标志
if(flags & 0x08) { // 故障安全激活
Set_Motor(1, 0);
// ... 停止所有电机 ...
}
```
2. **信号丢失检测**:
```c
static uint32_t last_packet_time = 0;
// 主循环中添加
if(HAL_GetTick() - last_packet_time > 200) { // 200ms超时
Set_Motor(1, 0); // 停止所有电机
}
```
阅读全文
相关推荐

















