diff --git a/boards/e3_176_ref/app_demo/eth-xip/sf/IAR_Norflash/FlashDebug/Obj/build.ninja b/boards/e3_176_ref/app_demo/eth-xip/sf/IAR_Norflash/FlashDebug/Obj/build.ninja
index c6750b1..73b1f9b 100644
--- a/boards/e3_176_ref/app_demo/eth-xip/sf/IAR_Norflash/FlashDebug/Obj/build.ninja
+++ b/boards/e3_176_ref/app_demo/eth-xip/sf/IAR_Norflash/FlashDebug/Obj/build.ninja
@@ -29,6 +29,7 @@ build app_light.pbi : index app_light.xcl
build app_param_manage.pbi : index app_param_manage.xcl
build app_pid.pbi : index app_pid.xcl
build app_power.pbi : index app_power.xcl
+build app_rc.pbi : index app_rc.xcl
build app_request.pbi : index app_request.xcl
build app_temp.pbi : index app_temp.xcl
build app_test.pbi : index app_test.xcl
@@ -121,17 +122,17 @@ build timeouts.pbi : index timeouts.xcl
build udelay.pbi : index udelay.xcl
build udp.pbi : index udp.xcl
build device_init.pbi : index device_init.xcl
-build sf_part0.pbi : link app_brake.pbi app_differential_drive.pbi app_frm_monitor.pbi app_frm_signal.pbi app_frm_timer.pbi app_light.pbi app_param_manage.pbi app_pid.pbi app_power.pbi app_request.pbi
-build sf_part1.pbi : link app_temp.pbi app_test.pbi app_ultrasonic.pbi arm_faults.pbi arm_fpu.pbi arm_irq.pbi arm_mpu.pbi arm_tcm.pbi board.pbi clock_cfg.pbi
-build sf_part2.pbi : link eth_cfg.pbi flexcan_cfg.pbi pinmux_cfg.pbi reset_cfg.pbi scr_cfg.pbi clock_default_cfg.pbi clock_ip.pbi dp83848.pbi irq.pbi phy.pbi
-build sf_part3.pbi : link reset_ip.pbi rtl9010.pbi sdrv_btm.pbi sdrv_btm_hw.pbi sdrv_ckgen.pbi sdrv_ckgen_hw_access.pbi sdrv_eth.pbi sdrv_flexcan.pbi sdrv_fs24m_hw_access.pbi sdrv_fs32k_hw_access.pbi
-build sf_part4.pbi : link sdrv_gpio.pbi sdrv_i2c.pbi sdrv_mac_lld.pbi sdrv_pinctrl.pbi sdrv_pll_hw_access.pbi sdrv_rstgen.pbi sdrv_scr.pbi sdrv_spi.pbi sdrv_uart.pbi sdrv_vic.pbi
-build sf_part5.pbi : link sdrv_watchdog.pbi interface.pbi interface_24c02.pbi interface_boot.pbi interface_btm.pbi interface_can.pbi interface_ethernet.pbi interface_gpio.pbi main.pbi acd.pbi
-build sf_part6.pbi : link altcp.pbi altcp_alloc.pbi altcp_tcp.pbi autoip.pbi bridgeif.pbi CLI_console.pbi def.pbi dhcp.pbi dns.pbi etharp.pbi
-build sf_part7.pbi : link ethernet.pbi FreeRTOS_CLI.pbi icmp.pbi igmp.pbi inet_chksum.pbi init.pbi ip.pbi ip4.pbi ip4_addr.pbi ip4_frag.pbi
-build sf_part8.pbi : link lwiperf.pbi mem.pbi memp.pbi net_tool.pbi netdev.pbi netif.pbi pbuf.pbi ping.pbi printf.pbi raw.pbi
-build sf_part9.pbi : link rom_ctrl.pbi stats.pbi sys.pbi sys_arch.pbi tcp.pbi tcp_in.pbi tcp_out.pbi timeouts.pbi udelay.pbi udp.pbi
-build sf_part10.pbi : link device_init.pbi
+build sf_part0.pbi : link app_brake.pbi app_differential_drive.pbi app_frm_monitor.pbi app_frm_signal.pbi app_frm_timer.pbi app_light.pbi app_param_manage.pbi app_pid.pbi app_power.pbi app_rc.pbi
+build sf_part1.pbi : link app_request.pbi app_temp.pbi app_test.pbi app_ultrasonic.pbi arm_faults.pbi arm_fpu.pbi arm_irq.pbi arm_mpu.pbi arm_tcm.pbi board.pbi
+build sf_part2.pbi : link clock_cfg.pbi eth_cfg.pbi flexcan_cfg.pbi pinmux_cfg.pbi reset_cfg.pbi scr_cfg.pbi clock_default_cfg.pbi clock_ip.pbi dp83848.pbi irq.pbi
+build sf_part3.pbi : link phy.pbi reset_ip.pbi rtl9010.pbi sdrv_btm.pbi sdrv_btm_hw.pbi sdrv_ckgen.pbi sdrv_ckgen_hw_access.pbi sdrv_eth.pbi sdrv_flexcan.pbi sdrv_fs24m_hw_access.pbi
+build sf_part4.pbi : link sdrv_fs32k_hw_access.pbi sdrv_gpio.pbi sdrv_i2c.pbi sdrv_mac_lld.pbi sdrv_pinctrl.pbi sdrv_pll_hw_access.pbi sdrv_rstgen.pbi sdrv_scr.pbi sdrv_spi.pbi sdrv_uart.pbi
+build sf_part5.pbi : link sdrv_vic.pbi sdrv_watchdog.pbi interface.pbi interface_24c02.pbi interface_boot.pbi interface_btm.pbi interface_can.pbi interface_ethernet.pbi interface_gpio.pbi main.pbi
+build sf_part6.pbi : link acd.pbi altcp.pbi altcp_alloc.pbi altcp_tcp.pbi autoip.pbi bridgeif.pbi CLI_console.pbi def.pbi dhcp.pbi dns.pbi
+build sf_part7.pbi : link etharp.pbi ethernet.pbi FreeRTOS_CLI.pbi icmp.pbi igmp.pbi inet_chksum.pbi init.pbi ip.pbi ip4.pbi ip4_addr.pbi
+build sf_part8.pbi : link ip4_frag.pbi lwiperf.pbi mem.pbi memp.pbi net_tool.pbi netdev.pbi netif.pbi pbuf.pbi ping.pbi printf.pbi
+build sf_part9.pbi : link raw.pbi rom_ctrl.pbi stats.pbi sys.pbi sys_arch.pbi tcp.pbi tcp_in.pbi tcp_out.pbi timeouts.pbi udelay.pbi
+build sf_part10.pbi : link udp.pbi device_init.pbi
build sf.pbd : link sf_part0.pbi sf_part1.pbi sf_part2.pbi sf_part3.pbi sf_part4.pbi sf_part5.pbi sf_part6.pbi sf_part7.pbi sf_part8.pbi sf_part9.pbi sf_part10.pbi
build sf.pbw : browsedata sf.pbd
diff --git a/boards/e3_176_ref/app_demo/eth-xip/sf/IAR_Norflash/settings/sf_EncodingOverride.xml b/boards/e3_176_ref/app_demo/eth-xip/sf/IAR_Norflash/settings/sf_EncodingOverride.xml
index ad2d5aa..d35c279 100644
--- a/boards/e3_176_ref/app_demo/eth-xip/sf/IAR_Norflash/settings/sf_EncodingOverride.xml
+++ b/boards/e3_176_ref/app_demo/eth-xip/sf/IAR_Norflash/settings/sf_EncodingOverride.xml
@@ -400,6 +400,14 @@
D:\20240905-e3_176_ref\e3_176_ref\middleware\lwip\src\include\lwip\raw.h
System
+
+ D:\code\7-8\boards\e3_176_ref\app_demo\eth-xip\sf\interface_can.c
+ System
+
+
+ D:\code\7-8\boards\e3_176_ref\app_demo\eth-xip\sf\interface_ethernet.c
+ System
+
D:\code\7-8car\test\boards\e3_176_ref\app_demo\eth-xip\sf\interface_can.c
System
diff --git a/boards/e3_176_ref/app_demo/eth-xip/sf/IAR_Norflash/sf.ewp b/boards/e3_176_ref/app_demo/eth-xip/sf/IAR_Norflash/sf.ewp
index 244b591..56fa2f9 100644
--- a/boards/e3_176_ref/app_demo/eth-xip/sf/IAR_Norflash/sf.ewp
+++ b/boards/e3_176_ref/app_demo/eth-xip/sf/IAR_Norflash/sf.ewp
@@ -2185,6 +2185,9 @@
$PROJ_DIR$\..\app\app_power.c
+
+ $PROJ_DIR$\..\app\app_rc.c
+
$PROJ_DIR$\..\app\app_request.c
diff --git a/boards/e3_176_ref/app_demo/eth-xip/sf/IAR_Norflash/sf.ewt b/boards/e3_176_ref/app_demo/eth-xip/sf/IAR_Norflash/sf.ewt
index 49e3ad2..f5e7182 100644
--- a/boards/e3_176_ref/app_demo/eth-xip/sf/IAR_Norflash/sf.ewt
+++ b/boards/e3_176_ref/app_demo/eth-xip/sf/IAR_Norflash/sf.ewt
@@ -2868,6 +2868,9 @@
$PROJ_DIR$\..\app\app_power.c
+
+ $PROJ_DIR$\..\app\app_rc.c
+
$PROJ_DIR$\..\app\app_request.c
diff --git a/boards/e3_176_ref/app_demo/eth-xip/sf/app/app_rc.c b/boards/e3_176_ref/app_demo/eth-xip/sf/app/app_rc.c
new file mode 100644
index 0000000..2f9617b
--- /dev/null
+++ b/boards/e3_176_ref/app_demo/eth-xip/sf/app/app_rc.c
@@ -0,0 +1,295 @@
+/**
+ * @file app_rc.c
+ * @brief 遥控器应用模块实现文件
+ * @description 实现遥控器数据处理功能
+ */
+
+#include "app_rc.h"
+
+/** 定时器 */
+static Timer rc_timer;
+
+/** 遥控器应用模块状态实例 */
+static RcAppState rc_app_state = {0};
+
+/**
+ * @brief 计算CRC16校验值
+ * @param data 数据指针
+ * @param len 数据长度
+ * @param crc_init 初始CRC值
+ * @return uint16_t CRC16校验值
+ */
+static uint16_t rcCrc16Calculate(const uint8_t* data, uint32_t len, uint16_t crc_init)
+{
+ static const uint16_t crc16_tab[256] = {
+ 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
+ 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
+ 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
+ 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
+ 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
+ 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
+ 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
+ 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
+ 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x840, 0x1861, 0x2802, 0x3823,
+ 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
+ 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0xa50, 0x3a33, 0x2a12,
+ 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
+ 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0xc60, 0x1c41,
+ 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
+ 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
+ 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
+ 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
+ 0x1080, 0xa1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
+ 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
+ 0x2b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
+ 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
+ 0x34e2, 0x24c3, 0x14a0, 0x481, 0x7466, 0x6447, 0x5424, 0x4405,
+ 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
+ 0x26d3, 0x36f2, 0x691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
+ 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
+ 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x8e1, 0x3882, 0x28a3,
+ 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
+ 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0xaf1, 0x1ad0, 0x2ab3, 0x3a92,
+ 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
+ 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0xcc1,
+ 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
+ 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0xed1, 0x1ef0
+ };
+
+ uint16_t crc = crc_init;
+ while (len-- != 0)
+ {
+ uint8_t temp = (crc >> 8) & 0xff;
+ uint16_t oldcrc16 = crc16_tab[(*data ^ temp)];
+ crc = (crc << 8) ^ oldcrc16;
+ data++;
+ }
+ return crc;
+}
+
+/**
+ * @brief 校验CRC16
+ * @param data 数据指针
+ * @param len 数据长度
+ * @return uint8_t 1=校验通过,0=校验失败
+ */
+static uint8_t rcCrc16Check(const uint8_t* data, uint32_t len)
+{
+ uint16_t received_crc = (uint16_t)data[len - 2] | ((uint16_t)data[len - 1] << 8);
+ uint16_t calculated_crc = rcCrc16Calculate(data, len - 2, 0);
+ return (received_crc == calculated_crc) ? 1 : 0;
+}
+
+/**
+ * @brief 检测遥控器节点状态
+ * @param current_seq 当前帧序列号
+ * @param last_seq 上次帧序列号(传入指针,函数会更新)
+ * @param enable 使能状态(1=使能,0=未使能)
+ * @return RcNodeState 节点状态(RC_NODE_ONLINE/RC_NODE_OFFLINE)
+ * @details
+ * 通用遥控器节点状态检测函数:
+ * - 检查使能信号是否有效
+ * - 比较当前序列号和上次序列号是否更新
+ * - 更新 last_seq 指针指向的值
+ * @note
+ * - 节点在线条件:使能信号有效且序列号正常更新
+ */
+RcNodeState rcCheckNodeState(uint16_t current_seq, uint16_t *last_seq, uint8_t enable)
+{
+ // 检查使能信号是否有效
+ if (enable == 0)
+ {
+ return RC_NODE_OFFLINE;
+ }
+
+ // 比较当前序列号和上次序列号
+ if (current_seq != *last_seq)
+ {
+ // 序列号更新,节点在线
+ *last_seq = current_seq;
+ return RC_NODE_ONLINE;
+ }
+ else
+ {
+ // 序列号未更新,节点离线
+ return RC_NODE_OFFLINE;
+ }
+}
+
+/**
+ * @brief 遥控器节点状态检测函数(定时调用)
+ * @param signal_id 信号ID(未使用)
+ * @details
+ * 定时调用此函数检测遥控器节点状态:
+ * - 检测16通道遥控器状态
+ * - 检测传统遥控器状态
+ */
+void rcNodeCheck(void *signal_id)
+{
+ (void)signal_id; // 标记变量为已使用,避免编译器警告
+
+ // 检测16通道遥控器状态
+ rc_app_state.rc_16ch_state = rcCheckNodeState(
+ rc_app_state.rc_16ch_current_seq,
+ &rc_app_state.rc_16ch_last_seq,
+ rc_app_state.rc_16ch_enable
+ );
+
+ // 检测传统遥控器状态
+ rc_app_state.rc_traditional_state = rcCheckNodeState(
+ rc_app_state.rc_traditional_current_seq,
+ &rc_app_state.rc_traditional_last_seq,
+ rc_app_state.rc_traditional_enable
+ );
+}
+
+
+/**
+ * @brief 遥控器输入处理函数(统一处理)
+ * @param signal_id 信号ID(用于判断是哪个遥控器数据更新)
+ * @details
+ * 统一处理遥控器输入数据更新:
+ * - 通过信号地址判断是哪个遥控器
+ * - 更新对应的序列号和使能状态
+ * - 进行节点在线判断和数据输出
+ */
+void rcInputHandler(void *signal_id)
+{
+ if (signal_id == &remote_control_16ch_output)
+ {
+ // 16通道遥控器数据更新,先进行CRC校验
+ if (rcCrc16Check(remote_control_16ch_output.data, sizeof(RemoteControl16ChUnion)))
+ {
+ // CRC校验通过,更新序列号和使能状态
+ rc_app_state.rc_16ch_current_seq = remote_control_16ch_output.frame.SEQ;
+ rc_app_state.rc_16ch_enable = 1;
+ }
+ else
+ {
+ // CRC校验失败,不更新数据
+ rc_app_state.rc_16ch_enable = 0;
+ }
+ }
+ else if (signal_id == &un_remote_control_input_can)
+ {
+ // 传统遥控器数据更新
+ rc_app_state.rc_traditional_current_seq++;
+ rc_app_state.rc_traditional_enable = un_remote_control_input_can.bit_data.enable;
+ }
+
+ // 节点在线判断和数据输出
+ if (rc_app_state.rc_traditional_state == RC_NODE_ONLINE)
+ {
+ // 传统遥控器在线,优先使用传统遥控器数据
+ for (uint8_t i = 0; i < sizeof(UnRemoteControlInput); i++)
+ {
+ un_remote_control_input.arr[i] = un_remote_control_input_can.arr[i];
+ }
+ }
+ else if (rc_app_state.rc_16ch_state == RC_NODE_ONLINE)
+ {
+ // 16通道遥控器在线,使用16通道遥控器数据
+ // 通道2(CH2):速度,映射 -2000~2000
+ int16_t processed_ch2 = remote_control_16ch_output.frame.CH2 - RC_CH_MID_VALUE;
+ if (processed_ch2 < -RC_DEADZONE)
+ {
+ un_remote_control_input.bit_data.speed = (int16_t)(processed_ch2 * 2000.0f / (RC_CH_MAX_VALUE - RC_CH_MID_VALUE));
+ }
+ else if (processed_ch2 > RC_DEADZONE)
+ {
+ un_remote_control_input.bit_data.speed = (int16_t)(processed_ch2 * 2000.0f / (RC_CH_MAX_VALUE - RC_CH_MID_VALUE));
+ }
+ else
+ {
+ un_remote_control_input.bit_data.speed = 0;
+ }
+
+ // 通道1(CH1):转向,映射 -20000~20000
+ int16_t processed_ch1 = remote_control_16ch_output.frame.CH1 - RC_CH_MID_VALUE;
+ if (processed_ch1 < -RC_DEADZONE)
+ {
+ un_remote_control_input.bit_data.curvature = (int16_t)(processed_ch1 * 20000.0f / (RC_CH_MAX_VALUE - RC_CH_MID_VALUE));
+ }
+ else if (processed_ch1 > RC_DEADZONE)
+ {
+ un_remote_control_input.bit_data.curvature = (int16_t)(processed_ch1 * 20000.0f / (RC_CH_MAX_VALUE - RC_CH_MID_VALUE));
+ }
+ else
+ {
+ un_remote_control_input.bit_data.curvature = 0;
+ }
+
+ // 通道14(CH14):电源开关,自复位,映射 0/1
+ if (remote_control_16ch_output.frame.CH14 > (RC_CH_MID_VALUE + RC_DEADZONE))
+ {
+ un_remote_control_input.bit_data.switch_d = 1;
+ }
+ else
+ {
+ un_remote_control_input.bit_data.switch_d = 0;
+ }
+
+ // 通道9(CH9):刹车开关,三档,映射 0/1/2
+ if (remote_control_16ch_output.frame.CH9 < (RC_CH_MID_VALUE - RC_DEADZONE))
+ {
+ un_remote_control_input.bit_data.switch_b = 0;
+ }
+ else if (remote_control_16ch_output.frame.CH9 > (RC_CH_MID_VALUE + RC_DEADZONE))
+ {
+ un_remote_control_input.bit_data.switch_b = 2;
+ }
+ else
+ {
+ un_remote_control_input.bit_data.switch_b = 1;
+ }
+
+ // 通道8(CH8):模式开关,三档,映射 0/1/2
+ if (remote_control_16ch_output.frame.CH8 < (RC_CH_MID_VALUE - RC_DEADZONE))
+ {
+ un_remote_control_input.bit_data.switch_c = 0;
+ }
+ else if (remote_control_16ch_output.frame.CH8 > (RC_CH_MID_VALUE + RC_DEADZONE))
+ {
+ un_remote_control_input.bit_data.switch_c = 2;
+ }
+ else
+ {
+ un_remote_control_input.bit_data.switch_c = 1;
+ }
+
+ un_remote_control_input.bit_data.switch_a = 0;
+ un_remote_control_input.bit_data.enable = 1;
+ }
+ else
+ {
+ // 都离线,清空使能
+ un_remote_control_input.bit_data.enable = 0;
+ }
+
+ publishMessage(&un_remote_control_input, 1); // 优先级为1,这里只传递数据指针
+}
+
+
+/**
+ * @brief 遥控器应用模块初始化函数
+ * @details
+ * 初始化遥控器应用模块:
+ * 1. 初始化定时器
+ * 2. 订阅定时器信号
+ * 3. 订阅遥控器数据信号
+ */
+void rcAppInit(void)
+{
+ // 初始化定时器
+ timerInit(&rc_timer);
+
+ // 订阅定时器信号,每500ms调用一次检测函数
+ subscribe(&rc_timer, rcNodeCheck);
+
+ // 订阅统一遥控器输入处理函数(替代原两个独立处理函数)
+ subscribe(&remote_control_16ch_output, rcInputHandler);
+ subscribe(&un_remote_control_input_can, rcInputHandler);
+
+ // 启动定时器,500ms周期
+ timerStart(&rc_timer, 500, 1);
+}
diff --git a/boards/e3_176_ref/app_demo/eth-xip/sf/app/app_rc.h b/boards/e3_176_ref/app_demo/eth-xip/sf/app/app_rc.h
new file mode 100644
index 0000000..dc8cbf9
--- /dev/null
+++ b/boards/e3_176_ref/app_demo/eth-xip/sf/app/app_rc.h
@@ -0,0 +1,88 @@
+/**
+ * @file app_rc.h
+ * @brief 遥控器应用模块头文件
+ * @description 定义遥控器数据处理相关的数据结构和函数接口
+ */
+
+#ifndef APP_RC_H
+#define APP_RC_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "interface.h"
+
+/**
+ * @brief 遥控器节点状态枚举
+ */
+typedef enum
+{
+ RC_NODE_OFFLINE = 0, /**< 遥控器节点离线 */
+ RC_NODE_ONLINE = 1 /**< 遥控器节点在线 */
+} RcNodeState;
+
+/**
+ * @brief 遥控器应用模块状态
+ */
+typedef struct
+{
+ uint16_t rc_16ch_last_seq; // 16通道遥控器上次序列号
+ uint16_t rc_16ch_current_seq; // 16通道遥控器当前序列号
+ uint16_t rc_traditional_last_seq; // 传统遥控器上次序列号
+ uint16_t rc_traditional_current_seq; // 传统遥控器当前序列号
+ RcNodeState rc_16ch_state; // 16通道遥控器节点状态
+ RcNodeState rc_traditional_state; // 传统遥控器节点状态
+ uint8_t rc_16ch_enable; // 16通道遥控器使能状态
+ uint8_t rc_traditional_enable; // 传统遥控器使能状态
+} RcAppState;
+
+#define RC_CH_MIN_VALUE 1050 // 遥控通道最小值
+#define RC_CH_MAX_VALUE 1950 // 遥控通道最大值
+#define RC_CH_MID_VALUE 1500 // 遥控通道中值
+#define RC_DEADZONE 30 // 遥控通道死区
+
+/**
+ * @brief 检测遥控器节点状态
+ * @param current_seq 当前帧序列号
+ * @param last_seq 上次帧序列号(传入指针,函数会更新)
+ * @param enable 使能状态(1=使能,0=未使能)
+ * @return RcNodeState 节点状态(RC_NODE_ONLINE/RC_NODE_OFFLINE)
+ * @details
+ * 通用遥控器节点状态检测函数:
+ * - 检查使能信号是否有效
+ * - 比较当前序列号和上次序列号是否更新
+ * - 更新 last_seq 指针指向的值
+ * @note
+ * - 节点在线条件:使能信号有效且序列号正常更新
+ */
+RcNodeState rcCheckNodeState(uint16_t current_seq, uint16_t *last_seq, uint8_t enable);
+
+/**
+ * @brief 遥控器应用模块初始化函数
+ * @details
+ * 初始化遥控器应用模块:
+ * 1. 初始化定时器
+ * 2. 订阅定时器信号
+ * 3. 订阅遥控器数据信号
+ * @note
+ * - 此函数应在系统启动时调用一次
+ */
+void rcAppInit(void);
+
+/**
+ * @brief 遥控器输入处理函数(统一处理)
+ * @param signal_id 信号ID(用于判断是哪个遥控器数据更新)
+ * @details
+ * 统一处理遥控器输入数据更新:
+ * - 通过信号地址判断是哪个遥控器
+ * - 更新对应的序列号
+ */
+void rcInputHandler(void *signal_id);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // APP_RC_H
diff --git a/boards/e3_176_ref/app_demo/eth-xip/sf/interface.c b/boards/e3_176_ref/app_demo/eth-xip/sf/interface.c
index 6ff4f7f..84f56cd 100644
--- a/boards/e3_176_ref/app_demo/eth-xip/sf/interface.c
+++ b/boards/e3_176_ref/app_demo/eth-xip/sf/interface.c
@@ -28,7 +28,8 @@ UnInfCanKGFOutput un_inf_can_kgf_output2 ;
UnHBridgeOutput un_h_bridge_output ;//H桥输出
UnWheelSpeedOutput un_wheel_wpeed_output ;//轮速输出
-UnRemoteControlInput un_remote_control_input ;//遥控器输入
+UnRemoteControlInput un_remote_control_input ;//遥控器模块输出
+UnRemoteControlInput un_remote_control_input_can ;//遥控器can输入
UnHBridgeOutput un_h_bridge_output ;//H桥输出
UnHBridgeOutput un_h_bridge_output1 ;//H桥输出
@@ -51,6 +52,8 @@ UnManualComputerInput un_manual_computer_input ;//自主计算机
UnRequestFrame un_request_frame ;//请求帧
UnComputerOutput un_computer_output ;//输出给自主计算机
+
+RemoteControl16ChUnion remote_control_16ch_output ;//16通道遥控器输出
//输出给上位机
UnVehicleInfoOutput un_vehicle_Info_output ;// 车辆信息,输出给上位机
diff --git a/boards/e3_176_ref/app_demo/eth-xip/sf/interface.h b/boards/e3_176_ref/app_demo/eth-xip/sf/interface.h
index d9e18a0..53bb399 100644
--- a/boards/e3_176_ref/app_demo/eth-xip/sf/interface.h
+++ b/boards/e3_176_ref/app_demo/eth-xip/sf/interface.h
@@ -685,7 +685,40 @@ typedef union _UnComputerOutput
} UnComputerOutput;
+/* 16通道遥控器数据结构体 - CMD_ID 0x0F */
+#pragma pack(push, 1)
+typedef struct {
+ uint16_t STX; // 帧起始标志,固定为0x6655(低字节在前,实际存储为0x55 0x66)
+ uint8_t CTRL; // 控制位:bit0-need_ack(是否需要ack) bit1-ack_pack(是否为ack包) bit2-7-预留
+ uint16_t Data_len; // 数据域字节长度(低字节在前),此处固定为32(16个通道×2字节)
+ uint16_t SEQ; // 帧序列(0~65535),低字节在前
+ uint8_t CMD_ID; // 命令ID,此处固定为0x0F
+ // 以下为DATA域(对应偏移8开始,长度=Data_len=32)
+ int16_t CH1; // 通道1数据(默认范围1050~1950)
+ int16_t CH2; // 通道2数据(默认范围1050~1950)
+ int16_t CH3; // 通道3数据(默认范围1050~1950)
+ int16_t CH4; // 通道4数据(默认范围1050~1950)
+ int16_t CH5; // 通道5数据(默认范围1050~1950)
+ int16_t CH6; // 通道6数据(默认范围1050~1950)
+ int16_t CH7; // 通道7数据(默认范围1050~1950)
+ int16_t CH8; // 通道8数据(默认范围1050~1950)
+ int16_t CH9; // 通道9数据(默认范围1050~1950)
+ int16_t CH10; // 通道10数据(默认范围1050~1950)
+ int16_t CH11; // 通道11数据(默认范围1050~1950)
+ int16_t CH12; // 通道12数据(默认范围1050~1950)
+ int16_t CH13; // 通道13数据(默认范围1050~1950)
+ int16_t CH14; // 通道14数据(默认范围1050~1950)
+ int16_t CH15; // 通道15数据(默认范围1050~1950)
+ int16_t CH16; // 通道16数据(默认范围1050~1950)
+ uint16_t CRC16; // 整个数据包的CRC16校验(低字节在前)
+} RemoteControl16ChFrame;
+#pragma pack(pop)
+/* 16通道遥控器数据完整通信帧联合体 - CMD_ID 0x0F */
+typedef union {
+ RemoteControl16ChFrame frame; // 按结构体访问各字段
+ uint8_t data[41]; // 按字节数组访问(总长度:2+1+2+2+1+32+2 = 41字节)
+} RemoteControl16ChUnion;
// 车辆信息,输出给上位机
typedef struct _StrVehicleInfoOutput
@@ -950,7 +983,7 @@ extern UnGatherOutput un_gather_output;//采集模块输出
//串口
extern UnRemoteControlInput un_remote_control_input; //遥控器输入
-
+extern UnRemoteControlInput un_remote_control_input_can ;//遥控器CAN输入
//IO口
extern UnSwSample un_sw_sample;
@@ -959,6 +992,8 @@ extern UnRequestFrame un_request_frame; //请求帧
extern UnComputerOutput un_computer_output; //输出给自主计算机
+extern RemoteControl16ChUnion remote_control_16ch_output ;//16通道遥控器输出
+
//输出给上位机
extern UnVehicleInfoOutput un_vehicle_Info_output; // 车辆信息,输出给上位机
extern UnMotorStatusOutput un_motor_status_output; // 电机状态信息,输出给上位机
diff --git a/boards/e3_176_ref/app_demo/eth-xip/sf/interface_can.c b/boards/e3_176_ref/app_demo/eth-xip/sf/interface_can.c
index 0fd39b5..c67ea64 100644
--- a/boards/e3_176_ref/app_demo/eth-xip/sf/interface_can.c
+++ b/boards/e3_176_ref/app_demo/eth-xip/sf/interface_can.c
@@ -685,10 +685,10 @@ void flexcan_Receive_callback_7(flexcan_handle_t *handle,
can_fault_info.bit_data.remote_count ++;
for(i = 0; i < (buf->length); i++)
{
- un_remote_control_input.arr[i] = buf->dataBuffer[i];
+ un_remote_control_input_can.arr[i] = buf->dataBuffer[i];
}
//�����ź�
- publishMessage(&un_remote_control_input, 1);
+ publishMessage(&un_remote_control_input_can, 1);
// printf("ori_remote_stop: %d\n", un_remote_control_input.bit_data.switch_b);
}
diff --git a/boards/e3_176_ref/app_demo/eth-xip/sf/interface_ethernet.c b/boards/e3_176_ref/app_demo/eth-xip/sf/interface_ethernet.c
index 76df6e1..235aee2 100644
--- a/boards/e3_176_ref/app_demo/eth-xip/sf/interface_ethernet.c
+++ b/boards/e3_176_ref/app_demo/eth-xip/sf/interface_ethernet.c
@@ -273,6 +273,19 @@ void udp_Callback_1(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_ad
// printf("Autorecive len:%d\n",len);
// udp_sendto(upcb, p, addr, port);
}
+ else if( (buf[0] == 0x55) && (buf[1] == 0x66) && (buf[7] == 0x42))
+ {
+ // ݳǷ
+ if(p->len <= 42)
+ {
+ // ֱӸƵȫ
+ memcpy(&remote_control_16ch_output.data[0], buf, p->len);
+
+ // ֪ͨϢָȫݵָ
+ publishMessage(&remote_control_16ch_output, 1); // ȼΪ1ָֻ
+
+ }
+ }
else
{
}