# N32_test_mcu **Repository Path**: xuchi123/n32_test_mcu ## Basic Information - **Project Name**: N32_test_mcu - **Description**: N32G455 香橙派底盘主控板固件工程 - **Primary Language**: C++ - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-16 - **Last Updated**: 2026-08-16 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # N32_test_mcu — 香橙派底盘主控板固件 基于国民技术 **N32G455CEQ7**(ARM Cortex-M4F, 144MHz)的底盘主控板固件工程,负责电机驱动、LORA 遥控、编码器采集、CAN 总线桥接及与香橙派单板计算机的串口通信。 --- ## 工程概览 ``` N32_test_mcu/ ├── Core/ 底层驱动层(时钟、GPIO、UART、CAN、定时器、ADC、中断) ├── user/ 应用层(电机控制、LORA 遥控、编码器、CAN 解析、香橙派通信、IAP) ├── Drivers/ 国民技术 N32G45x 标准外设库 + CMSIS DSP ├── MDK-ARM/ Keil MDK 工程文件 └── README.md ``` **开发环境:** Keil MDK V5.36 + ARM Compiler 5 (ARMCC) **目标芯片:** N32G455CEQ7 (Cortex-M4F, 144MHz, FPU/DSP) **系统时钟:** HSE 8MHz → PLL ×18 = **144MHz** SYSCLK → AHB=144M, APB2=72M, APB1=36M --- ## 架构设计 ### 三层头文件体系 工程采用三层 include 架构以消除循环依赖: 1. **base.h** — 基础层,聚合标准 C 库(`stdio.h`, `stdlib.h`, `stdint.h`, `math.h` 等)、N32G45x HAL 层(`n32g45x.h`, `n32g45x_conf.h`)和 ARM CMSIS DSP(`arm_math.h`)。所有模块只 include `base.h`,不直接引用底层头文件。 2. **各独立头文件**(`sys.h`, `gpio.h`, `uart.h`, `can.h`, `tim.h` 等)— 仅 include `base.h`,声明本模块的 API。 3. **main.h** — 汇总层,include 所有头文件,作为 `main.c` 的唯一入口。 ### 定时器驱动架构 系统采用定时器中断驱动的周期性任务调度: | 定时器 | 周期 | 用途 | |--------|------|------| | TIM6 | 1ms | 系统核心节拍 → 电机控制 (5ms)、香橙派通信 (8ms)、控制源超时计数 | | TIM5 | 1s | LED 心跳指示、周期性状态任务 | | TIM1 | 100μs | ADC 触发源(CC2 触发规则组,CC4 触发注入组) | 主循环(`main()` 超循环)轮询调用 `uart_parser_run()` 和 `lora_con_run()`。 ### 中断优先级方案 所有中断使用抢占优先级 0,子优先级分配如下: | 子优先级 | 外设 | |----------|------| | 0 | UART 中断、COMP 比较器 | | 1 | CAN 接收中断 | | 2 | DMA 通道 | | 3 | TIM1 / TIM5 / TIM6 | --- ## Core — 底层驱动层 ### sys — 系统初始化 `sys.c` / `sys.h` 负责全局初始化,`sys_init()` 按顺序调用:时钟配置 → NVIC 配置 → GPIO → UART → CAN → 定时器 → LORA。 **时钟树配置:** - HSE 8MHz → PLL ×18 = 144MHz SYSCLK - AHB = 144MHz, APB2 = 72MHz, APB1 = 36MHz - Flash 等待周期:4 个 wait state(适配 144MHz) - 使能所有外设时钟:GPIO A~F, DMA1/2, USART1/4/5/6/7, CAN1/2, TIM1/5/6, CRC, OPAMP, COMP ### gpio — 引脚配置 `gpio.c` / `gpio.h` 统一管理所有外设的 GPIO 初始化,并提供通用的 set / read / toggle 工具函数。 **关键引脚分配:** | 信号 | 引脚 | 说明 | |------|------|------| | LED1 | PB8 | 心跳指示灯 | | LED2 | PA15 | 心跳指示灯 | | RS485_DE | PE12 | RS485 收发方向控制 | | LORA MD0 | PE10 | LORA 模块模式选择 | | LORA MD1 | PE11 | LORA 模块模式选择 | | CAN1 TX/RX | PD9 / PD8 | 重映射引脚 | | CAN2 TX/RX | PB13 / PB12 | 默认引脚 | | UART1 TX/RX | PA9 / PA10 | 调试串口 | | UART4 TX/RX | PB2 / PE7 | LORA 通信 | | UART5 TX/RX | PE8 / PE9 | 传感器 | | UART6 TX/RX | PB0 / PB1 | RS485 总线 | | UART7 TX/RX | PC4 / PC5 | 香橙派通信 | **便捷宏:** `LED1(x)`, `LED2(x)`, `RS485_DE(x)`, `MD0(x)`, `MD1(x)` ### uart — 串口驱动 `uart.c` / `uart.h` 实现 5 路 UART 的完整驱动,支持轮询发送、DMA 发送、以及基于 IDLE 行中断 + DMA + 乒乓双缓冲的接收方案。 **串口配置总览:** | 串口 | 波特率 | 用途 | TX DMA | RX DMA | |------|--------|------|--------|--------| | USART1 | 1,500,000 | 调试 / printf 重定向 | DMA1_CH4 | DMA1_CH5 | | UART4 | 115,200 | LORA 遥控 | DMA2_CH5 | DMA2_CH3 | | UART5 | 115,200 | 传感器 | DMA1_CH1 | DMA1_CH8 | | UART6 | 115,200 | RS485 总线 | DMA2_CH2 | DMA2_CH1 | | UART7 | 1,000,000 | 香橙派通信 | DMA2_CH7 | DMA2_CH6 | **接收机制:** 每路串口分配 300 字节 × 2 的乒乓缓冲区(`RX_BUF_SIZE=300`),通过 IDLE 中断触发 DMA 缓冲区切换,主循环通过 `uart_get_flag()` / `uart_get_data()` 读取数据。 **printf 重定向:** `fputc()` 将 printf 输出重定向到 USART1,带 0xFF 超时防止死锁。 **RS485 支持:** UART6 发送时自动拉高 RS485_DE,发送完成中断自动拉低。 ### can — CAN 总线驱动 `can.c` / `can.h` 实现双 CAN 总线(CAN1 + CAN2)的初始化、发送、接收和滤波器配置。 **配置参数:** - 默认波特率:125Kbps(APB1=36MHz, 预分频=72, 4 时间量子位) - 工作模式:Normal, ABOM 自动离线管理, NART 禁止自动重传, TXFP FIFO 优先发送 - 时序:RSJW=1tq, TBS1=2tq, TBS2=1tq - 滤波器:默认全接收(32 位掩码模式),支持 16 位 ID 列表模式 **波特率预设(基于 36MHz APB1):** 1M(÷9), 500K(÷18), 250K(÷36), 125K(÷72) **数据结构:** `CanRx_t` 接收结构体包含 `{ id, len, data[8], flag }`。 ### tim — 定时器 `tim.c` / `tim.h` 初始化 TIM1/TIM5/TIM6 三个定时器,作为系统时间基准和 ADC 触发源。TIM1 配置为 100μs 周期(144MHz APB2 时钟,Prescaler=143, Period=99),用于 ADC 规则组和注入组的硬件触发。 ### adc — ADC 采样 `adc.c` / `adc.h` 实现双转换组 ADC 驱动: - **规则组:** 4 通道(CH1/CH2/CH5/CH6),DMA 循环模式,TIM1_CC2 触发,连续扫描,每通道 16 次采样取和 - **注入组:** 4 通道,TIM1_CC4 触发,转换完成中断读取 - **温度传感器:** 使用工厂校准 NVR 参数(VTS @ 0x1FFFF520, AVG_SLOPE=0.004)计算芯片温度 ### n32g45x_it — 中断向量表 `n32g45x_it.c` / `n32g45x_it.h` 实现 Cortex-M4 异常处理向量表。关键的定时器中断服务函数: - `TIM6_IRQHandler()` → 调用 `main_1ms()` → 电机控制 (5ms) + 香橙派通信 (8ms) - `TIM5_IRQHandler()` → 调用 `main_1s()` → LED 心跳 --- ## user — 应用层 ### motor_zhongling — 中菱轮毂电机驱动 `motor_zhongling.c` / `motor_zhongling.h` 通过 CAN 总线控制两台中菱轮毂电机(左轮 CAN ID 0x211,右轮 0x212),并接收速度反馈(0x311 / 0x312)。 **核心功能:** - **`motor_speed_run()`**(5ms 周期):读取 CAN 反馈速度,交替发送左右轮速度指令,含安全超时检测 - **`lora_con_run()`**:解析 LORA 摇杆数据,施加死区补偿(Y轴 ±20, X轴 ±25),转换为线速度 v 和角速度 omega - **`diff_calc(v, omega)`**:差速运动学计算,轮距 B=0.45m,轮径 D=0.254m **差速公式:** ``` vL = v - (B/2) × ω vR = v + (B/2) × ω RPM = v_wheel × 60 / (π × D) ``` **安全机制:** 当 LORA 和香橙派均超时(>1 秒无有效指令),自动停止电机。LORA 遥控优先级高于香橙派。 ### orange — 香橙派通信桥 `orange.c` / `orange.h` 是 MCU 与香橙派之间的协议转换器,通过 UART7(1Mbps)通信,承担三项职责: 1. **CAN 桥接:** 将 CAN1/CAN2 接收的数据帧打包(帧头 + CAN ID + CRC)转发给香橙派;接收香橙派的 CAN 帧并分发到 CAN1/CAN2 2. **遥测上报:** 周期性构建遥测帧(`0x55 0xAB` 帧头 + 总长度 + `Mcu_to_Orangepi` 结构体 + 累加和 CRC + `0xBB` 帧尾),包含 LORA 遥控数据和轮速信息 3. **指令解析:** 解析香橙派下发的速度指令(`Orangepi_to_Mcu` 结构体:`{v×100, omega×100}`,共 9 字节,小端序),调用 `diff_calc()` 驱动电机 **通信协议帧格式(MCU → 香橙派):** ``` [0x55][0xAB][长度][LORA数据 + 轮速数据][CRC累加和低8位][0xBB] ``` **通信协议帧格式(香橙派 → MCU):** ``` [0x55][0xAB][0x09][v_lo][v_hi][omega_lo][omega_hi][CRC][0xBB] 共9字节 ``` ### LORA — 无线遥控 `LORA.c` / `LORA.h` 驱动 LORA 无线模块(通过 UART4 通信),支持配置模式(9600 baud, MD0=0/MD1=0)和透传模式(115200 baud, MD0=1/MD1=0)。 **数据帧结构(`LORA_Data_t`,1 字节对齐):** ``` [0xAA][len][x1][y1][x2][y2][btn1][btn2][encoder_lo][encoder_hi][checksum][0xBB] ``` **初始化流程:** 切换到配置模式 → 发送 51 字节参数数组(频率、功率、信道等) → 切换到透传模式。 接收数据时进行帧头(0xAA)和 CRC 校验,解析双摇杆轴值、按钮状态和编码器值,并可转发到香橙派(帧头改为 0xCC 通过 UART7)。 ### uart_parser — 串口数据分发 `uart_parser.c` / `uart_parser.h` 在主循环中轮询 4 路串口的接收标志,按端口分发数据: | 串口 | 处理函数 | 目标模块 | |------|----------|----------| | UART1 | `uart1_rx_parser()` | 调试回显(数据环回) | | UART4 | `uart4_rx_parser()` | LORA 数据接收 → `lora_set_data()` | | UART6 | `uart6_rx_parser()` | RS485(预留) | | UART7 | `uart7_rx_parser()` | 香橙派通信:0x55+0xAB 帧头 → `orange_parse_cmd()`(速度指令),其他 → `orange_get_data()`(CAN 桥接) | ### can_parser — CAN 数据解析 `can_parser.c` / `can_parser.h` 轮询 CAN1 和 CAN2 的接收标志,提取数据后转发给香橙派桥接模块(`orange_set_can1_data()` / `orange_set_can2_data()`)。 ### encoder — 编码器数据封装 `encoder.c` / `encoder.h` 将磁编码器的角度和温度数据打包为 6 字节协议帧(帧头 0xAA + 2 字节角度 + 2 字节温度 + XOR 校验),支持通过 UART1 (RS485)、UART2 或 CAN 总线发送。 ### adc_parser — ADC 数据处理 `adc_parser.c` / `adc_parser.h` 处理磁编码器的 4 路 ADC 原始数据(X1/Y1/X2/Y2),计算差分信号(aa=X1-X2, bb=Y1-Y2),经自适应低通滤波后通过 CMSIS-DSP 的 `arm_atan2_f32` 计算角度,并计算转速,结果传递给 encoder 模块。 ### mc_math — 电机控制数学库 `mc_math.c` / `mc_math.h` 提供 FOC(磁场定向控制)所需的数学运算,全程使用 Q1.15 定点数: - **Clarke 变换 / 逆 Clarke 变换:** uvw ↔ αβ 坐标系 - **Park 变换 / 逆 Park 变换:** αβ ↔ qd 坐标系 - **SVPWM:** 空间矢量脉宽调制(含中点偏移) - **三角函数:** 5120 点正弦查找表,四象限映射 - **PI 控制器:** 带积分累加 - **低通滤波器:** 一阶 IIR - **均值滤波器:** 窗口大小 100 ### IAP — 在线应用编程 `IAP.c` / `IAP.h` 实现 IAP 引导加载程序: **Flash 布局:** ``` 0x08000000 ─── IAP 引导区 (16KB, 8页) 0x08004000 ─── APP 应用区 (48KB, 24页) 0x08010000 ─── Flash 末尾 ``` **核心功能:** Flash 擦除/写入/读取、硬件 CRC32 校验、跳转到 APP、通过 RS485 中断标志进入固件更新模式、启动计数器管理(Flash Page 7)。 ### FIR — 数字滤波器 `FIR.c` / `FIR.h` 基于 CMSIS-DSP 的 33 阶浮点 FIR 低通滤波器(`arm_fir_f32`),用于 ADC 信号后处理。 ### delay — 延时工具 `delay.c` / `delay.h` 基于 SysTick 定时器实现精确的微秒和毫秒阻塞延时,提供 `delay_us(n)` 和 `delay_ms(n)` 便捷宏。 ### opamp — 运算放大器 `opamp.c` / `opamp.h` 配置两路硬件 OPAMP(OPAMP1: VP=PA1/VM=PA3, OPAMP2: VP=PA7/VM=PA2)为外部运放模式,用于电机电流采样。 ### comp — 比较器 `comp.c` / `comp.h` 配置三路硬件比较器(COMP1/COMP2/COMP5),以 DAC1/PA4 为反相参考电压,输出连接 TIM1 刹车输入(BKIN),实现电机过流保护。滤波参数:采样窗口 31,阈值 18。 ### log — 日志框架 `log.c` / `log.h` 提供编译期日志级别过滤(`LOG_NONE` / `ERROR` / `WARNING` / `INFO` / `DEBUG`),通过宏控制是否在编译中包含 `printf()` 调用,以及 `uint16_t` 数组格式化输出。 --- ## 模块间数据流 ``` ┌──────────────┐ │ LORA 遥控器 │ └──────┬───────┘ │ UART4 ▼ ┌──────────┐ ┌───────────────┐ ┌───────────┐ │ 磁编码器 │──ADC──▶ │ adc_parser │──angle──▶ │ encoder │ │ (X1Y1X2Y2)│ └───────────────┘ └─────┬─────┘ └──────────┘ │ UART1/CAN ▼ ┌──────────┐ UART7 ┌───────────────┐ CAN1/2 ┌────────────┐ │ 香橙派 │◀─────────▶│ orange │◀──────────▶│ CAN 总线 │ │ │ └───────┬───────┘ └─────┬──────┘ └──────────┘ │ │ v, omega 速度反馈 ▼ ▼ ┌───────────────────────┐ ┌──────────────────┐ │ motor_zhongling │◀───│ LORA 摇杆数据 │ │ (差速运动学 + 安全) │ └──────────────────┘ └───────────┬───────────┘ │ CAN (0x211/0x212) ▼ ┌───────────────────────┐ │ 中菱轮毂电机 ×2 │ │ (左轮 0x211/0x311) │ │ (右轮 0x212/0x312) │ └───────────────────────┘ ``` --- ## 安全与控制权机制 系统实现双控制源(LORA 遥控 / 香橙派指令)的安全管理: - **超时保护:** `g_lora_ctrl_ms` 和 `g_orangepi_ctrl_ms` 计数器在 1ms 中断中递增,超过 1000ms 无有效指令则判定超时,自动停止电机 - **优先级仲裁:** LORA 活跃时(`g_lora_ctrl_ms < 1000`),忽略香橙派的速度指令,避免冲突 - **CAN 安全:** CAN 报文采用 NART(禁止自动重传),避免总线拥塞 --- ## 编译与烧录 本工程使用 **Keil MDK V5.36** + **ARM Compiler 5 (ARMCC)** 编译。通过 USB 下载器(如 J-Link / DAP-Link)连接目标板烧录。 工程文件位于 `MDK-ARM/N32G455CEQ7.uvprojx`。