From 68c43c5adef03f00836d83b37cb83a294d8b0354 Mon Sep 17 00:00:00 2001
From: yincheng.zhong <634916154@qq.com>
Date: 星期四, 13 十一月 2025 17:04:28 +0800
Subject: [PATCH] 晚上SBUS信号解析,成功控制车走

---
 STM32H743/FML/SBUS_使用说明.md |  412 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 412 insertions(+), 0 deletions(-)

diff --git "a/STM32H743/FML/SBUS_\344\275\277\347\224\250\350\257\264\346\230\216.md" "b/STM32H743/FML/SBUS_\344\275\277\347\224\250\350\257\264\346\230\216.md"
new file mode 100644
index 0000000..7a32083
--- /dev/null
+++ "b/STM32H743/FML/SBUS_\344\275\277\347\224\250\350\257\264\346\230\216.md"
@@ -0,0 +1,412 @@
+# SBUS 鑸ā閬ユ帶鍣ㄦ帴鏀舵ā鍧椾娇鐢ㄨ鏄�
+
+## 姒傝堪
+鏈ā鍧楀疄鐜颁簡 SBUS 鍗忚锛團utaba SBUS锛夌殑瑙f瀽锛岀敤浜庢帴鏀惰埅妯¢仴鎺у櫒淇″彿銆�
+
+### 纭欢閰嶇疆
+- **UART**: UART4 (STM32H743)
+- **娉㈢壒鐜�**: 100kbps
+- **鏍煎紡**: 8E2 (8 鏁版嵁浣�, 鍋舵牎楠�, 2 鍋滄浣�)
+- **鎺ユ敹妯″紡**: DMA 寰幆鎺ユ敹
+- **淇″彿鍙嶅悜**: 宸插惎鐢� RX 鍙嶅悜鍔熻兘锛堥�傞厤 SBUS 鍙嶅悜閫昏緫锛�
+
+### 鍗忚瑙勬牸
+- **甯ч暱搴�**: 25 瀛楄妭
+- **甯уご**: 0x0F
+- **甯у熬**: 0x00
+- **閫氶亾鏁�**: 16 涓ā鎷熼�氶亾 (11-bit, 0~2047) + 2 涓暟瀛楅�氶亾 (CH17/CH18)
+- **鏍囧織浣�**: Frame Lost銆丗ailsafe
+- **甯х巼**: 绾� 7~14 ms/甯� (鍙栧喅浜庡彂灏勬満)
+
+---
+
+## API 鎺ュ彛
+
+### 1. 鍒濆鍖�
+```c
+#include "SBUS.h"
+
+void app_task(void *pvParameters)
+{
+    // 鍦ㄤ换鍔″垵濮嬪寲闃舵璋冪敤锛堝凡闆嗘垚鍒� app.c锛�
+    SBUS_Init();
+    
+    while(1)
+    {
+        // 涓诲惊鐜疆璇�
+        SBUS_Poll();
+        // ...
+    }
+}
+```
+
+### 2. 鑾峰彇瀹屾暣閫氶亾鏁版嵁
+```c
+ST_SBUSData sbusData;
+
+if (SBUS_GetData(&sbusData) == HIDO_TRUE)
+{
+    // 鎴愬姛鑾峰彇鏁版嵁锛堜俊鍙锋湁鏁堬級
+    printf("CH0: %u, CH1: %u, CH2: %u\n",
+           sbusData.m_au16Channels[0],
+           sbusData.m_au16Channels[1],
+           sbusData.m_au16Channels[2]);
+    
+    // 妫�鏌ュけ鎺т繚鎶ゆ爣蹇�
+    if (sbusData.m_u8Failsafe)
+    {
+        printf("WARNING: Failsafe activated!\n");
+    }
+    
+    // 妫�鏌ュ抚涓㈠け鏍囧織
+    if (sbusData.m_u8FrameLost)
+    {
+        printf("WARNING: Frame lost!\n");
+    }
+    
+    // 鏁板瓧閫氶亾
+    printf("CH17: %u, CH18: %u\n", sbusData.m_u8Ch17, sbusData.m_u8Ch18);
+}
+else
+{
+    // 淇″彿瓒呮椂鎴栨棤鏁版嵁
+    printf("SBUS signal lost\n");
+}
+```
+
+### 3. 鑾峰彇鍗曚釜閫氶亾鍊�
+```c
+// 鑾峰彇娌归棬閫氶亾 (鍋囪 CH2 涓烘补闂�)
+HIDO_UINT16 throttle = SBUS_GetChannel(2);  // 0~2047
+
+// 褰掍竴鍖栧埌 [-1.0, 1.0]
+float throttle_normalized = (throttle - 1024.0f) / 1024.0f;
+
+// 鏄犲皠鍒扮數鏈洪�熷害 (0~100%)
+uint8_t motor_speed = (throttle * 100) / 2047;
+```
+
+### 4. 鑾峰彇鏁板瓧閫氶亾
+```c
+// 鑾峰彇寮�鍏崇姸鎬� (CH17 閫氬父瀵瑰簲閬ユ帶鍣ㄥ紑鍏�)
+HIDO_UINT8 switch_state = SBUS_GetDigitalChannel(17);  // 0 鎴� 1
+
+if (switch_state == 1)
+{
+    printf("Switch ON\n");
+}
+else
+{
+    printf("Switch OFF\n");
+}
+```
+
+### 5. 妫�鏌ヤ俊鍙锋湁鏁堟��
+```c
+// 妫�鏌ユ渶杩� 100ms 鍐呮槸鍚︽敹鍒� SBUS 甯�
+if (SBUS_IsSignalValid(100) == HIDO_TRUE)
+{
+    printf("SBUS signal OK\n");
+}
+else
+{
+    printf("SBUS signal LOST (timeout)\n");
+    // 杩涘叆澶辨帶淇濇姢妯″紡
+    // ...
+}
+```
+
+### 6. 鑾峰彇缁熻淇℃伅
+```c
+HIDO_UINT32 frameCount, errorCount;
+
+SBUS_GetStats(&frameCount, &errorCount);
+
+printf("Total frames: %u, Errors: %u (%.2f%%)\n",
+       frameCount, errorCount,
+       (frameCount > 0) ? (errorCount * 100.0f / frameCount) : 0.0f);
+```
+
+---
+
+## 鏁版嵁缁撴瀯璇﹁В
+
+### ST_SBUSData
+```c
+typedef struct
+{
+    HIDO_UINT16 m_au16Channels[16];      // 16 涓ā鎷熼�氶亾, 鑼冨洿 0~2047
+    HIDO_UINT8  m_u8Ch17;                 // 鏁板瓧閫氶亾 17, 鍊� 0 鎴� 1
+    HIDO_UINT8  m_u8Ch18;                 // 鏁板瓧閫氶亾 18, 鍊� 0 鎴� 1
+    HIDO_UINT8  m_u8FrameLost;            // 甯т涪澶辨爣蹇� (鍙戝皠鏈烘爣璁�)
+    HIDO_UINT8  m_u8Failsafe;             // 澶辨帶淇濇姢鏍囧織 (鎺ユ敹鏈烘爣璁�)
+    HIDO_UINT32 m_u32LastUpdateTick;      // 鏈�鍚庢洿鏂版椂鍒� (HAL_GetTick)
+    HIDO_UINT32 m_u32FrameCount;          // 绱鎺ユ敹甯ф暟
+    HIDO_UINT32 m_u32ErrorCount;          // 绱閿欒甯ф暟 (甯уご/甯у熬鏍¢獙澶辫触)
+} ST_SBUSData;
+```
+
+### 閫氶亾鏄犲皠绀轰緥锛堝父瑙侀仴鎺у櫒甯冨眬锛�
+| 閫氶亾 | 甯歌鍔熻兘 | 鍊艰寖鍥� | 涓績鍊� |
+|------|----------|--------|--------|
+| CH0  | 妯粴 (Aileron) | 0~2047 | 1024 |
+| CH1  | 淇话 (Elevator) | 0~2047 | 1024 |
+| CH2  | 娌归棬 (Throttle) | 0~2047 | 172 (鏈�浣�) |
+| CH3  | 鏂瑰悜 (Rudder) | 0~2047 | 1024 |
+| CH4  | 杈呭姪寮�鍏� 1 | 0~2047 | - |
+| CH5  | 杈呭姪寮�鍏� 2 | 0~2047 | - |
+| ...  | 鍏朵粬鑷畾涔� | 0~2047 | - |
+| CH17 | 鏁板瓧寮�鍏� 1 | 0/1 | - |
+| CH18 | 鏁板瓧寮�鍏� 2 | 0/1 | - |
+
+---
+
+## 鍏稿瀷搴旂敤鍦烘櫙
+
+### 鍦烘櫙1锛氭墜鍔ㄩ仴鎺ц崏鍧満
+```c
+void Manual_Control_Task(void)
+{
+    ST_SBUSData sbus;
+    
+    if (SBUS_GetData(&sbus) != HIDO_TRUE)
+    {
+        // 淇″彿涓㈠け锛屽仠姝㈢數鏈�
+        Motor_Stop();
+        return;
+    }
+    
+    // 澶辨帶淇濇姢瑙﹀彂锛屽仠姝�
+    if (sbus.m_u8Failsafe)
+    {
+        Motor_Stop();
+        return;
+    }
+    
+    // 鎻愬彇鎺у埗閲� (鍋囪 CH1=鍓嶈繘/鍚庨��, CH3=宸﹀彸杞悜)
+    int16_t forward = (int16_t)sbus.m_au16Channels[1] - 1024;  // -1024~+1023
+    int16_t turn = (int16_t)sbus.m_au16Channels[3] - 1024;     // -1024~+1023
+    
+    // 褰掍竴鍖栧埌 [-100, 100]
+    int8_t forward_cmd = (forward * 100) / 1024;
+    int8_t turn_cmd = (turn * 100) / 1024;
+    
+    // 鍙戦�佸埌宸�熺數鏈烘帶鍒跺櫒
+    DiffDrive_SetCommand(forward_cmd, turn_cmd);
+}
+```
+
+### 鍦烘櫙2锛氭ā寮忓垏鎹紙鑷姩/鎵嬪姩锛�
+```c
+void Mode_Switch_Task(void)
+{
+    static uint8_t last_switch = 0;
+    uint8_t current_switch = SBUS_GetDigitalChannel(17);
+    
+    // 妫�娴嬪紑鍏崇姸鎬佸彉鍖�
+    if (current_switch != last_switch)
+    {
+        if (current_switch == 1)
+        {
+            // 鍒囨崲鍒拌嚜鍔ㄦā寮�
+            System_SetMode(MODE_AUTO);
+            printf("Switched to AUTO mode\n");
+        }
+        else
+        {
+            // 鍒囨崲鍒版墜鍔ㄦā寮�
+            System_SetMode(MODE_MANUAL);
+            printf("Switched to MANUAL mode\n");
+        }
+        last_switch = current_switch;
+    }
+}
+```
+
+### 鍦烘櫙3锛氬け鎺т繚鎶ょ洃鎺�
+```c
+void Failsafe_Monitor_Task(void)
+{
+    static uint32_t last_valid_tick = 0;
+    
+    if (SBUS_IsSignalValid(200) == HIDO_TRUE)
+    {
+        last_valid_tick = HAL_GetTick();
+    }
+    else
+    {
+        uint32_t lost_duration = HAL_GetTick() - last_valid_tick;
+        
+        if (lost_duration > 1000)  // 淇″彿涓㈠け瓒呰繃 1 绉�
+        {
+            // 瑙﹀彂绱ф�ュ仠姝�
+            Emergency_Stop();
+            printf("EMERGENCY: SBUS signal lost for %u ms\n", lost_duration);
+        }
+    }
+}
+```
+
+---
+
+## 璋冭瘯涓庤瘖鏂�
+
+### 鎵撳嵃瀹炴椂閫氶亾鍊�
+```c
+void SBUS_Debug_Print(void)
+{
+    ST_SBUSData sbus;
+    
+    if (SBUS_GetData(&sbus) == HIDO_TRUE)
+    {
+        printf("SBUS Channels:\n");
+        for (uint8_t i = 0; i < 16; i++)
+        {
+            printf("  CH%02u: %4u", i, sbus.m_au16Channels[i]);
+            if ((i + 1) % 4 == 0) printf("\n");
+        }
+        printf("  CH17: %u, CH18: %u\n", sbus.m_u8Ch17, sbus.m_u8Ch18);
+        printf("  FrameLost: %u, Failsafe: %u\n", sbus.m_u8FrameLost, sbus.m_u8Failsafe);
+        printf("  Stats: Frames=%u, Errors=%u\n", sbus.m_u32FrameCount, sbus.m_u32ErrorCount);
+    }
+    else
+    {
+        printf("SBUS: No signal\n");
+    }
+}
+```
+
+### 淇″彿璐ㄩ噺妫�娴�
+```c
+void SBUS_Quality_Check(void)
+{
+    HIDO_UINT32 frames, errors;
+    SBUS_GetStats(&frames, &errors);
+    
+    if (frames > 1000)  // 绱Н瓒冲鏍锋湰
+    {
+        float error_rate = (errors * 100.0f) / frames;
+        
+        if (error_rate > 5.0f)
+        {
+            printf("WARNING: High SBUS error rate: %.2f%%\n", error_rate);
+            printf("  -> Check cable connection\n");
+            printf("  -> Check RX pin inversion setting\n");
+        }
+        else
+        {
+            printf("SBUS quality: Good (error rate: %.2f%%)\n", error_rate);
+        }
+    }
+}
+```
+
+---
+
+## 娉ㄦ剰浜嬮」
+
+### 1. 淇″彿鍙嶅悜
+- SBUS 鍗忚浣跨敤鍙嶅悜閫昏緫锛坕dle high = 0V, idle low = 3.3V锛�
+- STM32H7 UART4 宸插惎鐢� `UART_ADVFEATURE_RXINV_ENABLE`
+- 濡傛灉鏀跺埌鐨勬暟鎹叏鏄敊璇抚锛屾鏌ユ槸鍚﹂渶瑕佺鐢ㄥ弽鍚戝姛鑳�
+
+### 2. 娉㈢壒鐜囧宸�
+- SBUS 鏍囧噯娉㈢壒鐜囦负 100kbps
+- STM32 鍐呴儴鏃堕挓璇樊闇�鎺у埗鍦� 卤2% 浠ュ唴
+- 濡傛灉甯ч敊璇巼楂橈紝鍙井璋冩尝鐗圭巼 (99000 鎴� 101000)
+
+### 3. DMA 缂撳啿鍖哄ぇ灏�
+- 褰撳墠璁剧疆涓� 128 瀛楄妭锛堝彲瀹圭撼 5 甯э級
+- 濡傛灉涓诲惊鐜疆璇㈤棿闅旇緝闀匡紙>50ms锛夛紝寤鸿澧炲ぇ缂撳啿鍖�
+
+### 4. 甯х巼涓庡欢杩�
+- SBUS 甯ч棿闅旂害 7~14ms
+- `SBUS_Poll()` 搴旇嚦灏戜互 20Hz 棰戠巼璋冪敤锛堝綋鍓� app_task 绾� 74Hz锛�
+- 鎺у埗寤惰繜: 閲囨牱寤惰繜 + 瑙f瀽寤惰繜 < 20ms
+
+### 5. 澶辨帶淇濇姢绛栫暐
+- 寤鸿鍚屾椂鐩戞帶 `m_u8Failsafe` 鏍囧織鍜� `SBUS_IsSignalValid()` 瓒呮椂
+- 澶辨帶鏃剁珛鍗冲仠姝㈡墍鏈夎繍鍔ㄨ緭鍑�
+- 鎭㈠淇″彿鍚庨渶鎵嬪姩閲嶆柊浣胯兘锛堥槻姝㈡剰澶栧惎鍔級
+
+### 6. 澶氱嚎绋嬪畨鍏�
+- 褰撳墠瀹炵幇鏈娇鐢ㄤ复鐣屽尯淇濇姢
+- 濡傞渶鍦� ISR 鎴栧叾浠栭珮浼樺厛绾т换鍔′腑璁块棶锛岄渶娣诲姞浜掓枼閿�
+
+---
+
+## 鏁呴殰鎺掓煡
+
+| 闂 | 鍙兘鍘熷洜 | 瑙e喅鏂规 |
+|------|----------|----------|
+| 鏃犳硶鎺ユ敹鏁版嵁 | UART4 鏈纭垵濮嬪寲 | 妫�鏌� `MX_UART4_Init()` 璋冪敤椤哄簭 |
+| 甯ч敊璇巼 100% | RX 淇″彿鍙嶅悜璁剧疆閿欒 | 鍒囨崲 `UART_ADVFEATURE_RXINV` 鐘舵�� |
+| 淇″彿瓒呮椂 | 鍙戝皠鏈烘湭寮�鍚垨璺濈杩囪繙 | 妫�鏌ラ仴鎺у櫒鐢垫簮鍜屽ぉ绾� |
+| 閫氶亾鍊兼姈鍔� | 骞叉壈鎴栨帴瑙︿笉鑹� | 妫�鏌ユ帴绾垮睆钄藉拰鎺ュ湴 |
+| 閮ㄥ垎閫氶亾鏃犳晥 | 鍙戝皠鏈洪�氶亾鏈縺娲� | 妫�鏌ュ彂灏勬満閫氶亾閰嶇疆 |
+| DMA 鏈Е鍙� | DMA 鍒濆鍖栨湭瀹屾垚 | 纭 `HAL_UART_Receive_DMA()` 宸茶皟鐢� |
+
+---
+
+## 鎺ョ嚎鍙傝��
+
+### 鏍囧噯 SBUS 鎺ュ彛锛�3 绾匡級
+```
+SBUS 妯″潡        STM32H743
+---------        ----------
+  GND    ------->   GND
+  5V     ------->   5V (鎴� VCC)
+  SBUS   ------->   UART4_RX (PA1 鎴栨牴鎹疄闄呭紩鑴�)
+```
+
+### 娉ㄦ剰
+- SBUS 淇″彿鐢靛钩涓� 3.3V TTL锛堥儴鍒嗘ā鍧楅渶瑕佺數骞宠浆鎹級
+- 纭繚 SBUS 杈撳嚭绔笌 STM32 RX 寮曡剼鐩磋繛锛堟棤闇�涓婃媺/涓嬫媺鐢甸樆锛�
+
+---
+
+## 鎵╁睍鍔熻兘寤鸿
+
+### 1. 涓綅鏍″噯
+```c
+void SBUS_CalibrateCenter(uint8_t channel)
+{
+    uint16_t center_value = SBUS_GetChannel(channel);
+    // 淇濆瓨鍒� Flash 鎴栭厤缃枃浠�
+    Config_SetChannelCenter(channel, center_value);
+}
+```
+
+### 2. 閫氶亾鏄犲皠閲嶅畾涔�
+```c
+typedef enum {
+    RC_AILERON = 0,
+    RC_ELEVATOR = 1,
+    RC_THROTTLE = 2,
+    RC_RUDDER = 3,
+    RC_SWITCH_A = 4,
+    RC_SWITCH_B = 5,
+} E_RCChannel;
+
+uint16_t RC_GetMappedChannel(E_RCChannel ch)
+{
+    return SBUS_GetChannel(g_channel_map[ch]);
+}
+```
+
+### 3. 鎸囨暟鏇茬嚎璋冩暣
+```c
+int16_t RC_ApplyExpo(int16_t raw_value, float expo_factor)
+{
+    float normalized = raw_value / 1024.0f;  // -1.0 ~ 1.0
+    float expo = expo_factor * normalized * normalized * normalized +
+                 (1 - expo_factor) * normalized;
+    return (int16_t)(expo * 1024.0f);
+}
+```
+
+---
+
+鐢熸垚鏃堕棿锛�2025-11-13  
+妯″潡鐗堟湰锛歷1.0  
+缁存姢鑰咃細椤圭洰鍥㈤槦

--
Gitblit v1.9.3