987 lines
31 KiB
Markdown
987 lines
31 KiB
Markdown
|
|
# 代码与设计文档一致性审查及LED控制逻辑异常分析报告
|
|||
|
|
|
|||
|
|
## 文档信息
|
|||
|
|
- **版本**: v1.0
|
|||
|
|
- **日期**: 2026-03-25
|
|||
|
|
- **项目**: E32-433TBH-SC
|
|||
|
|
- **MCU**: STM32F103C8T6
|
|||
|
|
- **审查人**: 嵌入式系统架构师
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 一、 代码与设计文档一致性审查报告
|
|||
|
|
|
|||
|
|
### 1.1 审查概述
|
|||
|
|
|
|||
|
|
本次审查基于以下文件进行:
|
|||
|
|
- **设计文档**: `docs/STM32硬件配置对比分析报告_v1.0.md`
|
|||
|
|
- **CubeMX配置**: `project.ioc`
|
|||
|
|
- **生成的HAL代码**: `Core/Src/gpio.c`, `Core/Src/usart.c`, `Core/Src/spi.c`
|
|||
|
|
- **引脚宏定义**: `Core/Inc/main.h`
|
|||
|
|
|
|||
|
|
审查范围包括:GPIO配置、UART配置、SPI配置、时钟配置、中断配置等。
|
|||
|
|
|
|||
|
|
### 1.2 GPIO配置对比
|
|||
|
|
|
|||
|
|
#### 1.2.1 LED指示灯配置
|
|||
|
|
|
|||
|
|
| 信号 | 设计文档要求 | 当前实际配置 | 状态 | 备注 |
|
|||
|
|
|------|-------------|-------------|------|------|
|
|||
|
|
| LED_TX | PB9, GPIO_Output, GPIO_PIN_SET | PB9, GPIO_Output, GPIO_PIN_SET | ✅ 符合 | 初始状态为SET(高电平) |
|
|||
|
|
| LED_RX | PB3, GPIO_Output, GPIO_PIN_SET | PB3, GPIO_Output, GPIO_PIN_SET | ✅ 符合 | 初始状态为SET(高电平) |
|
|||
|
|
|
|||
|
|
**代码位置**:
|
|||
|
|
- `Core/Inc/main.h`: 第84-85行
|
|||
|
|
- `Core/Src/gpio.c`: 第57行(初始状态设置)
|
|||
|
|
|
|||
|
|
#### 1.2.2 433模块控制引脚配置
|
|||
|
|
|
|||
|
|
| 信号 | 设计文档要求 | 当前实际配置 | 状态 | 备注 |
|
|||
|
|
|------|-------------|-------------|------|------|
|
|||
|
|
| M0 | PA7, GPIO_Output, GPIO_PIN_SET | PA7, GPIO_Output, GPIO_PIN_SET | ✅ 符合 | 初始状态为SET(高电平) |
|
|||
|
|
| M1 | PB0, GPIO_Output, GPIO_PIN_SET | PB0, GPIO_Output, GPIO_PIN_SET | ✅ 符合 | 初始状态为SET(高电平) |
|
|||
|
|
| AUX | PB1, GPIO_Input, GPIO_PULLUP | PB1, GPIO_Input, GPIO_PULLUP | ✅ 符合 | 上拉输入 |
|
|||
|
|
| RESET | PB2, GPIO_Output, GPIO_PIN_SET | PB2, GPIO_Output, GPIO_PIN_RESET | ⚠️ 差异 | 初始状态不一致 |
|
|||
|
|
|
|||
|
|
**差异分析**:
|
|||
|
|
- 设计文档要求RESET初始状态为`GPIO_PIN_SET`(高电平)
|
|||
|
|
- 当前代码中RESET初始状态为`GPIO_PIN_RESET`(低电平)
|
|||
|
|
- **影响**: RESET引脚初始状态为低电平,可能导致433模块在启动时处于复位状态
|
|||
|
|
- **建议**: 根据硬件设计确认RESET引脚的初始状态要求
|
|||
|
|
|
|||
|
|
**代码位置**:
|
|||
|
|
- `Core/Inc/main.h`: 第60-67行
|
|||
|
|
- `Core/Src/gpio.c`: 第60行(RESET初始状态设置)
|
|||
|
|
|
|||
|
|
#### 1.2.3 W5500模块配置
|
|||
|
|
|
|||
|
|
| 信号 | 设计文档要求 | 当前实际配置 | 状态 | 备注 |
|
|||
|
|
|------|-------------|-------------|------|------|
|
|||
|
|
| W5500_RESET | PA8, GPIO_Output, GPIO_PIN_SET | PA8, GPIO_Output, GPIO_PIN_RESET | ⚠️ 差异 | 初始状态不一致 |
|
|||
|
|
| W5500_CS | PB12, GPIO_Output | PB12, SPI2_NSS | ⚠️ 差异 | 配置方式不同 |
|
|||
|
|
| W5500_SCLK | PB13, SPI2_SCK | PB13, SPI2_SCK | ✅ 符合 | - |
|
|||
|
|
| W5500_MISO | PB14, SPI2_MISO | PB14, SPI2_MISO | ✅ 符合 | - |
|
|||
|
|
| W5500_MOSI | PB15, SPI2_MOSI | PB15, SPI2_MOSI | ✅ 符合 | - |
|
|||
|
|
|
|||
|
|
**差异分析**:
|
|||
|
|
|
|||
|
|
1. **W5500_RESET初始状态**:
|
|||
|
|
- 设计文档要求初始状态为`GPIO_PIN_SET`(高电平)
|
|||
|
|
- 当前代码中初始状态为`GPIO_PIN_RESET`(低电平)
|
|||
|
|
- **影响**: W5500模块在启动时可能处于复位状态
|
|||
|
|
- **建议**: 根据硬件设计确认RESET引脚的初始状态要求
|
|||
|
|
|
|||
|
|
2. **W5500_CS配置方式**:
|
|||
|
|
- 设计文档要求配置为`GPIO_Output`(软件控制片选)
|
|||
|
|
- 当前代码中配置为`SPI2_NSS`(硬件NSS)
|
|||
|
|
- **影响**:
|
|||
|
|
- 硬件NSS模式下,片选信号由SPI硬件自动控制
|
|||
|
|
- 软件控制模式下,片选信号需要手动控制
|
|||
|
|
- 两种模式的控制方式不同,需要根据W5500驱动的要求选择
|
|||
|
|
- **建议**:
|
|||
|
|
- 如果W5500驱动使用软件控制片选,需要修改CubeMX配置
|
|||
|
|
- 在CubeMX中将PB12配置为`GPIO_Output`,而不是`SPI2_NSS`
|
|||
|
|
- 在SPI配置中设置`NSS = SPI_NSS_SOFT`
|
|||
|
|
|
|||
|
|
**代码位置**:
|
|||
|
|
- `Core/Inc/main.h`: 第68-71行
|
|||
|
|
- `Core/Src/gpio.c`: 第63行(W5500_RESET初始状态设置)
|
|||
|
|
- `Core/Src/spi.c`: 第46行(SPI NSS配置)
|
|||
|
|
- `project.ioc`: 第114行(PB12配置为SPI2_NSS)
|
|||
|
|
|
|||
|
|
#### 1.2.4 继电器控制配置
|
|||
|
|
|
|||
|
|
| 信号 | 设计文档要求 | 当前实际配置 | 状态 | 备注 |
|
|||
|
|
|------|-------------|-------------|------|------|
|
|||
|
|
| RL_Control | PA15, GPIO_Output, GPIO_PIN_RESET | PA15, GPIO_Output, GPIO_PIN_RESET | ✅ 符合 | 初始状态为RESET(低电平) |
|
|||
|
|
|
|||
|
|
**代码位置**:
|
|||
|
|
- `Core/Inc/main.h`: 第72-73行
|
|||
|
|
- `Core/Src/gpio.c`: 第63行(RL_Control初始状态设置)
|
|||
|
|
|
|||
|
|
#### 1.2.5 开关信号输入配置
|
|||
|
|
|
|||
|
|
| 信号 | 设计文档要求 | 当前实际配置 | 状态 | 备注 |
|
|||
|
|
|------|-------------|-------------|------|------|
|
|||
|
|
| MCU_DI1 | PB4, GPIO_Input | PB4, GPIO_Input | ✅ 符合 | 无上拉/下拉 |
|
|||
|
|
| MCU_DI2 | PB5, GPIO_Input | PB5, GPIO_Input | ✅ 符合 | 无上拉/下拉 |
|
|||
|
|
| MCU_DI3 | PB6, GPIO_Input | PB6, GPIO_Input | ✅ 符合 | 无上拉/下拉 |
|
|||
|
|
| MCU_DI4 | PB7, GPIO_Input | PB7, GPIO_Input | ✅ 符合 | 无上拉/下拉 |
|
|||
|
|
|
|||
|
|
**代码位置**:
|
|||
|
|
- `Core/Inc/main.h`: 第76-83行
|
|||
|
|
- `Core/Src/gpio.c`: 第86-89行(开关输入初始化)
|
|||
|
|
|
|||
|
|
### 1.3 UART配置对比
|
|||
|
|
|
|||
|
|
#### 1.3.1 UART1(433模块通信)
|
|||
|
|
|
|||
|
|
| 参数 | 设计文档要求 | 当前实际配置 | 状态 | 备注 |
|
|||
|
|
|------|-------------|-------------|------|------|
|
|||
|
|
| 引脚 | PA9/PA10 | PA9/PA10 | ✅ 符合 | - |
|
|||
|
|
| 波特率 | 9600 | 9600 | ✅ 符合 | - |
|
|||
|
|
| 数据位 | 8 | 8 | ✅ 符合 | - |
|
|||
|
|
| 停止位 | 1 | 1 | ✅ 符合 | - |
|
|||
|
|
| 校验位 | None | None | ✅ 符合 | - |
|
|||
|
|
| 中断优先级 | 0 | 0 | ✅ 符合 | 最高优先级 |
|
|||
|
|
|
|||
|
|
**代码位置**:
|
|||
|
|
- `Core/Src/usart.c`: 第34-60行(UART1初始化)
|
|||
|
|
- `Core/Src/usart.c`: 第148-149行(UART1中断优先级)
|
|||
|
|
- `project.ioc`: 第65行(UART1中断配置)
|
|||
|
|
|
|||
|
|
#### 1.3.2 UART2(调试串口)
|
|||
|
|
|
|||
|
|
| 参数 | 设计文档要求 | 当前实际配置 | 状态 | 备注 |
|
|||
|
|
|------|-------------|-------------|------|------|
|
|||
|
|
| 引脚 | PA2/PA3 | PA2/PA3 | ✅ 符合 | - |
|
|||
|
|
| 波特率 | 115200 | 115200 | ✅ 符合 | - |
|
|||
|
|
| 数据位 | 8 | 8 | ✅ 符合 | - |
|
|||
|
|
| 停止位 | 1 | 1 | ✅ 符合 | - |
|
|||
|
|
| 校验位 | None | None | ✅ 符合 | - |
|
|||
|
|
| 中断优先级 | 1 | 0 | ⚠️ 差异 | 优先级不一致 |
|
|||
|
|
|
|||
|
|
**差异分析**:
|
|||
|
|
- 设计文档要求UART2中断优先级为1
|
|||
|
|
- 当前代码中UART2中断优先级为0
|
|||
|
|
- **影响**: UART2中断优先级与UART1相同,可能导致中断优先级冲突
|
|||
|
|
- **建议**: 将UART2中断优先级修改为1,与设计文档保持一致
|
|||
|
|
|
|||
|
|
**代码位置**:
|
|||
|
|
- `Core/Src/usart.c`: 第63-89行(UART2初始化)
|
|||
|
|
- `Core/Src/usart.c`: 第178-179行(UART2中断优先级)
|
|||
|
|
- `project.ioc`: 第66行(UART2中断配置)
|
|||
|
|
|
|||
|
|
#### 1.3.3 UART3(485通信)
|
|||
|
|
|
|||
|
|
| 参数 | 设计文档要求 | 当前实际配置 | 状态 | 备注 |
|
|||
|
|
|------|-------------|-------------|------|------|
|
|||
|
|
| 引脚 | PB10/PB11 | PB10/PB11 | ✅ 符合 | - |
|
|||
|
|
| 波特率 | 9600 | 115200 | ⚠️ 差异 | 波特率不一致 |
|
|||
|
|
| 数据位 | 8 | 8 | ✅ 符合 | - |
|
|||
|
|
| 停止位 | 1 | 1 | ✅ 符合 | - |
|
|||
|
|
| 校验位 | None | None | ✅ 符合 | - |
|
|||
|
|
| 中断优先级 | 2 | 0 | ⚠️ 差异 | 优先级不一致 |
|
|||
|
|
|
|||
|
|
**差异分析**:
|
|||
|
|
|
|||
|
|
1. **波特率差异**:
|
|||
|
|
- 设计文档要求波特率为9600
|
|||
|
|
- 当前代码中波特率为115200
|
|||
|
|
- **影响**: 485通信可能无法正常工作,因为波特率不匹配
|
|||
|
|
- **建议**: 根据实际485设备的要求确认波特率,并修改CubeMX配置
|
|||
|
|
|
|||
|
|
2. **中断优先级差异**:
|
|||
|
|
- 设计文档要求UART3中断优先级为2
|
|||
|
|
- 当前代码中UART3中断优先级为0
|
|||
|
|
- **影响**: UART3中断优先级与UART1、UART2相同,可能导致中断优先级冲突
|
|||
|
|
- **建议**: 将UART3中断优先级修改为2,与设计文档保持一致
|
|||
|
|
|
|||
|
|
**代码位置**:
|
|||
|
|
- `Core/Src/usart.c`: 第92-118行(UART3初始化)
|
|||
|
|
- `Core/Src/usart.c`: 第208-209行(UART3中断优先级)
|
|||
|
|
- `project.ioc`: 第67行(UART3中断配置)
|
|||
|
|
|
|||
|
|
### 1.4 SPI配置对比
|
|||
|
|
|
|||
|
|
#### 1.4.1 SPI2(W5500模块)
|
|||
|
|
|
|||
|
|
| 参数 | 设计文档要求 | 当前实际配置 | 状态 | 备注 |
|
|||
|
|
|------|-------------|-------------|------|------|
|
|||
|
|
| 引脚 | PB13/PB14/PB15/PB12 | PB13/PB14/PB15/PB12 | ✅ 符合 | - |
|
|||
|
|
| 模式 | Master | Master | ✅ 符合 | - |
|
|||
|
|
| 数据大小 | 8 Bits | 8 Bits | ✅ 符合 | - |
|
|||
|
|
| 时钟极性 | Low | Low | ✅ 符合 | - |
|
|||
|
|
| 时钟相位 | 1 Edge | 1 Edge | ✅ 符合 | - |
|
|||
|
|
| 波特率 | 18 MHz | 18 MHz | ✅ 符合 | - |
|
|||
|
|
| NSS | Soft | Soft | ✅ 符合 | - |
|
|||
|
|
|
|||
|
|
**代码位置**:
|
|||
|
|
- `Core/Src/spi.c`: 第30-60行(SPI2初始化)
|
|||
|
|
- `project.ioc`: 第225-230行(SPI2配置)
|
|||
|
|
|
|||
|
|
### 1.5 时钟配置对比
|
|||
|
|
|
|||
|
|
| 参数 | 设计文档要求 | 当前实际配置 | 状态 | 备注 |
|
|||
|
|
|------|-------------|-------------|------|------|
|
|||
|
|
| 系统时钟 | 72 MHz | 72 MHz | ✅ 符合 | - |
|
|||
|
|
| AHB时钟 | 72 MHz | 72 MHz | ✅ 符合 | - |
|
|||
|
|
| APB1时钟 | 36 MHz | 36 MHz | ✅ 符合 | - |
|
|||
|
|
| APB2时钟 | 72 MHz | 72 MHz | ✅ 符合 | - |
|
|||
|
|
|
|||
|
|
**代码位置**:
|
|||
|
|
- `project.ioc`: 第203-224行(时钟配置)
|
|||
|
|
|
|||
|
|
### 1.6 中断配置对比
|
|||
|
|
|
|||
|
|
| 中断 | 设计文档要求 | 当前实际配置 | 状态 | 备注 |
|
|||
|
|
|------|-------------|-------------|------|------|
|
|||
|
|
| USART1_IRQn | 0 | 0 | ✅ 符合 | 最高优先级 |
|
|||
|
|
| USART2_IRQn | 1 | 0 | ⚠️ 差异 | 优先级不一致 |
|
|||
|
|
| USART3_IRQn | 2 | 0 | ⚠️ 差异 | 优先级不一致 |
|
|||
|
|
| SysTick_IRQn | 15 | 15 | ✅ 符合 | 最低优先级 |
|
|||
|
|
|
|||
|
|
**差异分析**:
|
|||
|
|
- UART2和UART3的中断优先级与设计文档不一致
|
|||
|
|
- **影响**: 可能导致中断优先级冲突,影响系统稳定性
|
|||
|
|
- **建议**: 修改CubeMX配置,将UART2中断优先级设置为1,UART3中断优先级设置为2
|
|||
|
|
|
|||
|
|
**代码位置**:
|
|||
|
|
- `project.ioc`: 第65-67行(中断配置)
|
|||
|
|
|
|||
|
|
### 1.7 配置差异总结
|
|||
|
|
|
|||
|
|
| 序号 | 配置项 | 设计文档要求 | 当前配置 | 差异类型 | 影响程度 | 建议操作 |
|
|||
|
|
|------|--------|-------------|----------|----------|----------|----------|
|
|||
|
|
| 1 | RESET初始状态 | GPIO_PIN_SET | GPIO_PIN_RESET | 初始状态 | 中 | 确认硬件设计后修改 |
|
|||
|
|
| 2 | W5500_RESET初始状态 | GPIO_PIN_SET | GPIO_PIN_RESET | 初始状态 | 中 | 确认硬件设计后修改 |
|
|||
|
|
| 3 | W5500_CS配置 | GPIO_Output | SPI2_NSS | 配置方式 | 高 | 修改CubeMX配置 |
|
|||
|
|
| 4 | UART2中断优先级 | 1 | 0 | 中断优先级 | 中 | 修改CubeMX配置 |
|
|||
|
|
| 5 | UART3波特率 | 9600 | 115200 | 波特率 | 高 | 修改CubeMX配置 |
|
|||
|
|
| 6 | UART3中断优先级 | 2 | 0 | 中断优先级 | 中 | 修改CubeMX配置 |
|
|||
|
|
|
|||
|
|
### 1.8 修改建议
|
|||
|
|
|
|||
|
|
#### 1.8.1 高优先级修改(必须修改)
|
|||
|
|
|
|||
|
|
1. **修改W5500_CS配置**:
|
|||
|
|
- 在CubeMX中,将PB12从`SPI2_NSS`改为`GPIO_Output`
|
|||
|
|
- 在SPI2配置中,确保`NSS = SPI_NSS_SOFT`
|
|||
|
|
- 重新生成代码
|
|||
|
|
|
|||
|
|
2. **修改UART3波特率**:
|
|||
|
|
- 在CubeMX中,将UART3波特率从115200改为9600
|
|||
|
|
- 重新生成代码
|
|||
|
|
|
|||
|
|
#### 1.8.2 中优先级修改(建议修改)
|
|||
|
|
|
|||
|
|
1. **修改UART2中断优先级**:
|
|||
|
|
- 在CubeMX中,将UART2中断优先级从0改为1
|
|||
|
|
- 重新生成代码
|
|||
|
|
|
|||
|
|
2. **修改UART3中断优先级**:
|
|||
|
|
- 在CubeMX中,将UART3中断优先级从0改为2
|
|||
|
|
- 重新生成代码
|
|||
|
|
|
|||
|
|
#### 1.8.3 需要确认的修改
|
|||
|
|
|
|||
|
|
1. **RESET初始状态**:
|
|||
|
|
- 确认硬件设计中RESET引脚的初始状态要求
|
|||
|
|
- 如果需要高电平初始状态,修改CubeMX配置
|
|||
|
|
- 重新生成代码
|
|||
|
|
|
|||
|
|
2. **W5500_RESET初始状态**:
|
|||
|
|
- 确认硬件设计中W5500_RESET引脚的初始状态要求
|
|||
|
|
- 如果需要高电平初始状态,修改CubeMX配置
|
|||
|
|
- 重新生成代码
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 二、 LED_TX/RX亮灭状态异常分析与解决方案
|
|||
|
|
|
|||
|
|
### 2.1 原因分析
|
|||
|
|
|
|||
|
|
#### 2.1.1 问题描述
|
|||
|
|
|
|||
|
|
在新硬件板卡上,`LED_TX`和`LED_RX`两个指示灯的实际亮灭状态与程序预期相反:
|
|||
|
|
- 代码意图点亮LED时,LED反而熄灭
|
|||
|
|
- 代码意图熄灭LED时,LED反而点亮
|
|||
|
|
|
|||
|
|
#### 2.1.2 当前LED控制代码分析
|
|||
|
|
|
|||
|
|
**代码位置**: `Core/Src/gpio.c` 第94-112行
|
|||
|
|
|
|||
|
|
```c
|
|||
|
|
void gpio_led_tx_on(void)
|
|||
|
|
{
|
|||
|
|
HAL_GPIO_WritePin(LED_TX_GPIO_Port, LED_TX_Pin, GPIO_PIN_RESET);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void gpio_led_tx_off(void)
|
|||
|
|
{
|
|||
|
|
HAL_GPIO_WritePin(LED_TX_GPIO_Port, LED_TX_Pin, GPIO_PIN_SET);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void gpio_led_rx_on(void)
|
|||
|
|
{
|
|||
|
|
HAL_GPIO_WritePin(LED_RX_GPIO_Port, LED_RX_Pin, GPIO_PIN_RESET);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void gpio_led_rx_off(void)
|
|||
|
|
{
|
|||
|
|
HAL_GPIO_WritePin(LED_RX_GPIO_Port, LED_RX_Pin, GPIO_PIN_SET);
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**代码逻辑分析**:
|
|||
|
|
- `gpio_led_tx_on()` / `gpio_led_rx_on()`: 使用`GPIO_PIN_RESET`(低电平)点亮LED
|
|||
|
|
- `gpio_led_tx_off()` / `gpio_led_rx_off()`: 使用`GPIO_PIN_SET`(高电平)熄灭LED
|
|||
|
|
|
|||
|
|
#### 2.1.3 GPIO初始状态分析
|
|||
|
|
|
|||
|
|
**代码位置**: `Core/Src/gpio.c` 第57行
|
|||
|
|
|
|||
|
|
```c
|
|||
|
|
HAL_GPIO_WritePin(GPIOB, M1_Pin|LED_RX_Pin|LED_TX_Pin, GPIO_PIN_SET);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**初始状态分析**:
|
|||
|
|
- LED_TX和LED_RX的初始状态为`GPIO_PIN_SET`(高电平)
|
|||
|
|
- 根据当前控制逻辑,初始状态为高电平意味着LED熄灭
|
|||
|
|
|
|||
|
|
#### 2.1.4 硬件电路分析
|
|||
|
|
|
|||
|
|
**常见LED驱动电路类型**:
|
|||
|
|
|
|||
|
|
1. **高电平有效电路**(Active High):
|
|||
|
|
```
|
|||
|
|
VCC → 限流电阻 → LED → GPIO引脚
|
|||
|
|
```
|
|||
|
|
- GPIO输出高电平时,LED点亮
|
|||
|
|
- GPIO输出低电平时,LED熄灭
|
|||
|
|
|
|||
|
|
2. **低电平有效电路**(Active Low):
|
|||
|
|
```
|
|||
|
|
VCC → 限流电阻 → LED → GPIO引脚
|
|||
|
|
```
|
|||
|
|
- GPIO输出低电平时,LED点亮
|
|||
|
|
- GPIO输出高电平时,LED熄灭
|
|||
|
|
|
|||
|
|
**当前代码逻辑分析**:
|
|||
|
|
- 代码使用`GPIO_PIN_RESET`(低电平)点亮LED
|
|||
|
|
- 代码使用`GPIO_PIN_SET`(高电平)熄灭LED
|
|||
|
|
- 这种逻辑对应**低电平有效电路**
|
|||
|
|
|
|||
|
|
#### 2.1.5 问题原因判断
|
|||
|
|
|
|||
|
|
根据以上分析,LED亮灭状态异常的可能原因:
|
|||
|
|
|
|||
|
|
1. **硬件电路设计为高电平有效,但代码按低电平有效编写**:
|
|||
|
|
- 硬件电路:高电平点亮LED
|
|||
|
|
- 代码逻辑:低电平点亮LED
|
|||
|
|
- 结果:代码意图点亮时输出低电平,但硬件需要高电平才能点亮,导致LED熄灭
|
|||
|
|
|
|||
|
|
2. **硬件电路设计为低电平有效,但代码按高电平有效编写**:
|
|||
|
|
- 硬件电路:低电平点亮LED
|
|||
|
|
- 代码逻辑:高电平点亮LED
|
|||
|
|
- 结果:代码意图点亮时输出高电平,但硬件需要低电平才能点亮,导致LED熄灭
|
|||
|
|
|
|||
|
|
**根据当前代码分析**:
|
|||
|
|
- 代码使用`GPIO_PIN_RESET`(低电平)点亮LED
|
|||
|
|
- 这种逻辑对应**低电平有效电路**
|
|||
|
|
- 如果硬件实际为**高电平有效电路**,就会出现LED亮灭状态相反的问题
|
|||
|
|
|
|||
|
|
**结论**: 最可能的原因是**硬件电路设计为高电平有效,但代码按低电平有效编写**。
|
|||
|
|
|
|||
|
|
### 2.2 解决策略判断与理由
|
|||
|
|
|
|||
|
|
#### 2.2.1 解决方案对比
|
|||
|
|
|
|||
|
|
| 解决方案 | 修改位置 | 修改内容 | 优点 | 缺点 | 适用场景 |
|
|||
|
|
|---------|---------|---------|------|------|----------|
|
|||
|
|
| 方案1:仅修改应用层代码 | `gpio.c` | 交换`GPIO_PIN_SET`和`GPIO_PIN_RESET` | 简单快速,不影响CubeMX配置 | 代码逻辑与硬件设计不一致 | 紧急修复、临时方案 |
|
|||
|
|
| 方案2:修改CubeMX配置 | `project.ioc` | 修改GPIO初始状态 | 代码逻辑与硬件设计一致,符合最佳实践 | 需要重新生成代码,可能影响其他代码 | 正式方案、长期维护 |
|
|||
|
|
|
|||
|
|
#### 2.2.2 推荐方案:方案2(修改CubeMX配置)
|
|||
|
|
|
|||
|
|
**理由**:
|
|||
|
|
|
|||
|
|
1. **代码逻辑与硬件设计一致**:
|
|||
|
|
- 修改CubeMX配置后,代码逻辑与硬件设计保持一致
|
|||
|
|
- 符合嵌入式开发的最佳实践
|
|||
|
|
- 便于后续维护和理解
|
|||
|
|
|
|||
|
|
2. **符合STM32CubeMX设计理念**:
|
|||
|
|
- STM32CubeMX的设计理念是通过图形化配置生成代码
|
|||
|
|
- 修改CubeMX配置可以确保生成的代码与配置一致
|
|||
|
|
- 避免手动修改生成的代码
|
|||
|
|
|
|||
|
|
3. **便于团队协作**:
|
|||
|
|
- CubeMX配置文件(`.ioc`)可以作为项目配置的单一真实来源
|
|||
|
|
- 团队成员可以通过查看`.ioc`文件了解硬件配置
|
|||
|
|
- 避免因手动修改代码导致的配置不一致
|
|||
|
|
|
|||
|
|
4. **便于硬件变更**:
|
|||
|
|
- 如果硬件设计变更,只需修改CubeMX配置
|
|||
|
|
- 重新生成代码即可,无需手动修改多处代码
|
|||
|
|
- 提高开发效率
|
|||
|
|
|
|||
|
|
5. **避免代码混淆**:
|
|||
|
|
- 如果仅修改应用层代码,代码逻辑与硬件设计不一致
|
|||
|
|
- 后续维护人员可能难以理解代码逻辑
|
|||
|
|
- 容易引入新的bug
|
|||
|
|
|
|||
|
|
#### 2.2.3 不推荐方案1的原因
|
|||
|
|
|
|||
|
|
虽然方案1(仅修改应用层代码)可以快速解决问题,但不推荐作为长期方案,原因如下:
|
|||
|
|
|
|||
|
|
1. **代码逻辑与硬件设计不一致**:
|
|||
|
|
- 代码使用`GPIO_PIN_SET`点亮LED,但硬件需要低电平才能点亮
|
|||
|
|
- 这种不一致会导致代码难以理解和维护
|
|||
|
|
|
|||
|
|
2. **不符合STM32CubeMX设计理念**:
|
|||
|
|
- STM32CubeMX生成的代码应该与配置保持一致
|
|||
|
|
- 手动修改生成的代码违背了这一设计理念
|
|||
|
|
|
|||
|
|
3. **容易引入新的bug**:
|
|||
|
|
- 后续维护人员可能不理解代码逻辑
|
|||
|
|
- 在修改代码时可能引入新的bug
|
|||
|
|
|
|||
|
|
4. **不利于团队协作**:
|
|||
|
|
- 团队成员需要同时查看CubeMX配置和代码才能理解系统
|
|||
|
|
- 增加了沟通成本
|
|||
|
|
|
|||
|
|
### 2.3 具体修改步骤
|
|||
|
|
|
|||
|
|
#### 2.3.1 示例1:通过仅修改应用程序代码来修正逻辑
|
|||
|
|
|
|||
|
|
**适用场景**: 紧急修复、临时方案、无法修改CubeMX配置的情况
|
|||
|
|
|
|||
|
|
**修改步骤**:
|
|||
|
|
|
|||
|
|
1. **打开文件**: `Core/Src/gpio.c`
|
|||
|
|
|
|||
|
|
2. **修改LED控制函数**:
|
|||
|
|
|
|||
|
|
**原始代码**:
|
|||
|
|
```c
|
|||
|
|
void gpio_led_tx_on(void)
|
|||
|
|
{
|
|||
|
|
HAL_GPIO_WritePin(LED_TX_GPIO_Port, LED_TX_Pin, GPIO_PIN_RESET);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void gpio_led_tx_off(void)
|
|||
|
|
{
|
|||
|
|
HAL_GPIO_WritePin(LED_TX_GPIO_Port, LED_TX_Pin, GPIO_PIN_SET);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void gpio_led_rx_on(void)
|
|||
|
|
{
|
|||
|
|
HAL_GPIO_WritePin(LED_RX_GPIO_Port, LED_RX_Pin, GPIO_PIN_RESET);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void gpio_led_rx_off(void)
|
|||
|
|
{
|
|||
|
|
HAL_GPIO_WritePin(LED_RX_GPIO_Port, LED_RX_Pin, GPIO_PIN_SET);
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**修改后代码**:
|
|||
|
|
```c
|
|||
|
|
void gpio_led_tx_on(void)
|
|||
|
|
{
|
|||
|
|
HAL_GPIO_WritePin(LED_TX_GPIO_Port, LED_TX_Pin, GPIO_PIN_SET);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void gpio_led_tx_off(void)
|
|||
|
|
{
|
|||
|
|
HAL_GPIO_WritePin(LED_TX_GPIO_Port, LED_TX_Pin, GPIO_PIN_RESET);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void gpio_led_rx_on(void)
|
|||
|
|
{
|
|||
|
|
HAL_GPIO_WritePin(LED_RX_GPIO_Port, LED_RX_Pin, GPIO_PIN_SET);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void gpio_led_rx_off(void)
|
|||
|
|
{
|
|||
|
|
HAL_GPIO_WritePin(LED_RX_GPIO_Port, LED_RX_Pin, GPIO_PIN_RESET);
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
3. **修改GPIO初始状态**:
|
|||
|
|
|
|||
|
|
**原始代码**(第57行):
|
|||
|
|
```c
|
|||
|
|
HAL_GPIO_WritePin(GPIOB, M1_Pin|LED_RX_Pin|LED_TX_Pin, GPIO_PIN_SET);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**修改后代码**:
|
|||
|
|
```c
|
|||
|
|
HAL_GPIO_WritePin(GPIOB, M1_Pin|LED_RX_Pin|LED_TX_Pin, GPIO_PIN_RESET);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
4. **保存文件并编译项目**
|
|||
|
|
|
|||
|
|
**修改说明**:
|
|||
|
|
- 交换了`GPIO_PIN_SET`和`GPIO_PIN_RESET`
|
|||
|
|
- `gpio_led_tx_on()` / `gpio_led_rx_on()` 现在使用`GPIO_PIN_SET`(高电平)点亮LED
|
|||
|
|
- `gpio_led_tx_off()` / `gpio_led_rx_off()` 现在使用`GPIO_PIN_RESET`(低电平)熄灭LED
|
|||
|
|
- GPIO初始状态改为`GPIO_PIN_RESET`(低电平),确保LED初始状态为点亮
|
|||
|
|
|
|||
|
|
**注意事项**:
|
|||
|
|
- 这种修改方式仅适用于紧急修复或临时方案
|
|||
|
|
- 如果硬件设计为低电平有效,这种修改会导致LED亮灭状态再次相反
|
|||
|
|
- 建议在确认硬件设计后,使用方案2进行正式修改
|
|||
|
|
|
|||
|
|
#### 2.3.2 示例2:通过调整CubeMX GPIO配置并结合代码修改来修正逻辑
|
|||
|
|
|
|||
|
|
**适用场景**: 正式方案、长期维护、符合最佳实践
|
|||
|
|
|
|||
|
|
**修改步骤**:
|
|||
|
|
|
|||
|
|
##### 步骤1:修改CubeMX配置
|
|||
|
|
|
|||
|
|
1. **打开CubeMX项目**: 双击`project.ioc`文件
|
|||
|
|
|
|||
|
|
2. **修改LED_TX引脚配置**:
|
|||
|
|
- 在Pinout & Configuration视图中,找到PB9引脚(LED_TX)
|
|||
|
|
- 点击PB9引脚,在右侧配置面板中找到"GPIO"配置
|
|||
|
|
- 找到"GPIO output level"选项
|
|||
|
|
- 将"GPIO output level"从"High"改为"Low"
|
|||
|
|
- 或者,如果当前为"Low",则改为"High"(根据硬件设计确定)
|
|||
|
|
|
|||
|
|
3. **修改LED_RX引脚配置**:
|
|||
|
|
- 在Pinout & Configuration视图中,找到PB3引脚(LED_RX)
|
|||
|
|
- 点击PB3引脚,在右侧配置面板中找到"GPIO"配置
|
|||
|
|
- 找到"GPIO output level"选项
|
|||
|
|
- 将"GPIO output level"从"High"改为"Low"
|
|||
|
|
- 或者,如果当前为"Low",则改为"High"(根据硬件设计确定)
|
|||
|
|
|
|||
|
|
4. **保存CubeMX配置**: 点击"File" → "Save Project"或按Ctrl+S
|
|||
|
|
|
|||
|
|
5. **生成代码**: 点击"GENERATE CODE"按钮
|
|||
|
|
|
|||
|
|
##### 步骤2:确认生成的代码
|
|||
|
|
|
|||
|
|
1. **检查GPIO初始状态**:
|
|||
|
|
|
|||
|
|
打开`Core/Src/gpio.c`,确认第57行的代码:
|
|||
|
|
|
|||
|
|
```c
|
|||
|
|
HAL_GPIO_WritePin(GPIOB, M1_Pin|LED_RX_Pin|LED_TX_Pin, GPIO_PIN_RESET);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
或者:
|
|||
|
|
|
|||
|
|
```c
|
|||
|
|
HAL_GPIO_WritePin(GPIOB, M1_Pin|LED_RX_Pin|LED_TX_Pin, GPIO_PIN_SET);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
根据CubeMX配置,初始状态应该与配置一致。
|
|||
|
|
|
|||
|
|
2. **检查LED控制函数**:
|
|||
|
|
|
|||
|
|
打开`Core/Src/gpio.c`,确认LED控制函数:
|
|||
|
|
|
|||
|
|
```c
|
|||
|
|
void gpio_led_tx_on(void)
|
|||
|
|
{
|
|||
|
|
HAL_GPIO_WritePin(LED_TX_GPIO_Port, LED_TX_Pin, GPIO_PIN_RESET);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void gpio_led_tx_off(void)
|
|||
|
|
{
|
|||
|
|
HAL_GPIO_WritePin(LED_TX_GPIO_Port, LED_TX_Pin, GPIO_PIN_SET);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void gpio_led_rx_on(void)
|
|||
|
|
{
|
|||
|
|
HAL_GPIO_WritePin(LED_RX_GPIO_Port, LED_RX_Pin, GPIO_PIN_RESET);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void gpio_led_rx_off(void)
|
|||
|
|
{
|
|||
|
|
HAL_GPIO_WritePin(LED_RX_GPIO_Port, LED_RX_Pin, GPIO_PIN_SET);
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
如果硬件设计为高电平有效,需要修改这些函数:
|
|||
|
|
|
|||
|
|
```c
|
|||
|
|
void gpio_led_tx_on(void)
|
|||
|
|
{
|
|||
|
|
HAL_GPIO_WritePin(LED_TX_GPIO_Port, LED_TX_Pin, GPIO_PIN_SET);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void gpio_led_tx_off(void)
|
|||
|
|
{
|
|||
|
|
HAL_GPIO_WritePin(LED_TX_GPIO_Port, LED_TX_Pin, GPIO_PIN_RESET);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void gpio_led_rx_on(void)
|
|||
|
|
{
|
|||
|
|
HAL_GPIO_WritePin(LED_RX_GPIO_Port, LED_RX_Pin, GPIO_PIN_SET);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void gpio_led_rx_off(void)
|
|||
|
|
{
|
|||
|
|
HAL_GPIO_WritePin(LED_RX_GPIO_Port, LED_RX_Pin, GPIO_PIN_RESET);
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
##### 步骤3:编译和测试
|
|||
|
|
|
|||
|
|
1. **编译项目**: 在IDE中编译项目,确保没有编译错误
|
|||
|
|
|
|||
|
|
2. **下载程序**: 将程序下载到目标硬件
|
|||
|
|
|
|||
|
|
3. **测试LED功能**:
|
|||
|
|
- 测试LED_TX是否正常点亮和熄灭
|
|||
|
|
- 测试LED_RX是否正常点亮和熄灭
|
|||
|
|
- 确认LED亮灭状态与代码逻辑一致
|
|||
|
|
|
|||
|
|
##### 步骤4:文档更新
|
|||
|
|
|
|||
|
|
1. **更新硬件设计文档**: 在硬件设计文档中明确说明LED的驱动方式(高电平有效或低电平有效)
|
|||
|
|
|
|||
|
|
2. **更新代码注释**: 在LED控制函数中添加注释,说明LED的驱动方式
|
|||
|
|
|
|||
|
|
```c
|
|||
|
|
/**
|
|||
|
|
* @brief 点亮LED_TX
|
|||
|
|
* @note LED_TX为高电平有效(Active High)
|
|||
|
|
* @retval None
|
|||
|
|
*/
|
|||
|
|
void gpio_led_tx_on(void)
|
|||
|
|
{
|
|||
|
|
HAL_GPIO_WritePin(LED_TX_GPIO_Port, LED_TX_Pin, GPIO_PIN_SET);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 熄灭LED_TX
|
|||
|
|
* @note LED_TX为高电平有效(Active High)
|
|||
|
|
* @retval None
|
|||
|
|
*/
|
|||
|
|
void gpio_led_tx_off(void)
|
|||
|
|
{
|
|||
|
|
HAL_GPIO_WritePin(LED_TX_GPIO_Port, LED_TX_Pin, GPIO_PIN_RESET);
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**修改说明**:
|
|||
|
|
- 通过修改CubeMX配置,确保GPIO初始状态与硬件设计一致
|
|||
|
|
- 通过修改LED控制函数,确保代码逻辑与硬件设计一致
|
|||
|
|
- 添加代码注释,便于后续维护和理解
|
|||
|
|
|
|||
|
|
**注意事项**:
|
|||
|
|
- 在修改CubeMX配置前,需要确认硬件设计中LED的驱动方式(高电平有效或低电平有效)
|
|||
|
|
- 如果不确定硬件设计,可以先使用万用表测量LED驱动电路
|
|||
|
|
- 修改CubeMX配置后,需要重新生成代码,注意不要覆盖用户代码
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 三、 总结与建议
|
|||
|
|
|
|||
|
|
### 3.1 代码与设计文档一致性审查总结
|
|||
|
|
|
|||
|
|
#### 3.1.1 符合设计文档的配置
|
|||
|
|
|
|||
|
|
以下配置完全符合设计文档要求:
|
|||
|
|
- LED_TX和LED_RX的引脚配置和初始状态
|
|||
|
|
- 433模块控制引脚(M0、M1、AUX)的配置
|
|||
|
|
- 继电器控制引脚(RL_Control)的配置
|
|||
|
|
- 开关信号输入引脚(MCU_DI1~MCU_DI4)的配置
|
|||
|
|
- UART1(433模块通信)的配置
|
|||
|
|
- SPI2(W5500模块)的配置
|
|||
|
|
- 时钟配置
|
|||
|
|
|
|||
|
|
#### 3.1.2 需要修改的配置
|
|||
|
|
|
|||
|
|
以下配置与设计文档不一致,需要修改:
|
|||
|
|
|
|||
|
|
1. **高优先级修改(必须修改)**:
|
|||
|
|
- W5500_CS配置:从`SPI2_NSS`改为`GPIO_Output`
|
|||
|
|
- UART3波特率:从115200改为9600
|
|||
|
|
|
|||
|
|
2. **中优先级修改(建议修改)**:
|
|||
|
|
- UART2中断优先级:从0改为1
|
|||
|
|
- UART3中断优先级:从0改为2
|
|||
|
|
|
|||
|
|
3. **需要确认的修改**:
|
|||
|
|
- RESET初始状态:确认硬件设计后决定是否修改
|
|||
|
|
- W5500_RESET初始状态:确认硬件设计后决定是否修改
|
|||
|
|
|
|||
|
|
### 3.2 LED控制逻辑异常总结
|
|||
|
|
|
|||
|
|
#### 3.2.1 问题原因
|
|||
|
|
|
|||
|
|
LED亮灭状态异常的最可能原因是:
|
|||
|
|
- **硬件电路设计为高电平有效,但代码按低电平有效编写**
|
|||
|
|
- 代码使用`GPIO_PIN_RESET`(低电平)点亮LED
|
|||
|
|
- 但硬件需要高电平才能点亮LED
|
|||
|
|
- 导致代码意图点亮时,LED反而熄灭
|
|||
|
|
|
|||
|
|
#### 3.2.2 推荐解决方案
|
|||
|
|
|
|||
|
|
**推荐方案**: 修改CubeMX配置并结合代码修改
|
|||
|
|
|
|||
|
|
**理由**:
|
|||
|
|
- 代码逻辑与硬件设计一致
|
|||
|
|
- 符合STM32CubeMX设计理念
|
|||
|
|
- 便于团队协作和后续维护
|
|||
|
|
- 避免代码混淆和引入新的bug
|
|||
|
|
|
|||
|
|
#### 3.2.3 修改步骤
|
|||
|
|
|
|||
|
|
1. **修改CubeMX配置**:
|
|||
|
|
- 修改LED_TX和LED_RX的GPIO初始状态
|
|||
|
|
- 重新生成代码
|
|||
|
|
|
|||
|
|
2. **修改LED控制函数**:
|
|||
|
|
- 根据硬件设计修改LED控制函数
|
|||
|
|
- 确保代码逻辑与硬件设计一致
|
|||
|
|
|
|||
|
|
3. **编译和测试**:
|
|||
|
|
- 编译项目
|
|||
|
|
- 下载程序到目标硬件
|
|||
|
|
- 测试LED功能
|
|||
|
|
|
|||
|
|
4. **文档更新**:
|
|||
|
|
- 更新硬件设计文档
|
|||
|
|
- 更新代码注释
|
|||
|
|
|
|||
|
|
### 3.3 后续工作建议
|
|||
|
|
|
|||
|
|
#### 3.3.1 立即执行的工作
|
|||
|
|
|
|||
|
|
1. **修改W5500_CS配置**:
|
|||
|
|
- 在CubeMX中将PB12从`SPI2_NSS`改为`GPIO_Output`
|
|||
|
|
- 在SPI2配置中确保`NSS = SPI_NSS_SOFT`
|
|||
|
|
- 重新生成代码
|
|||
|
|
|
|||
|
|
2. **修改UART3波特率**:
|
|||
|
|
- 在CubeMX中将UART3波特率从115200改为9600
|
|||
|
|
- 重新生成代码
|
|||
|
|
|
|||
|
|
3. **解决LED控制逻辑异常**:
|
|||
|
|
- 确认硬件设计中LED的驱动方式
|
|||
|
|
- 修改CubeMX配置和LED控制函数
|
|||
|
|
- 测试LED功能
|
|||
|
|
|
|||
|
|
#### 3.3.2 短期执行的工作
|
|||
|
|
|
|||
|
|
1. **修改UART中断优先级**:
|
|||
|
|
- 在CubeMX中将UART2中断优先级从0改为1
|
|||
|
|
- 在CubeMX中将UART3中断优先级从0改为2
|
|||
|
|
- 重新生成代码
|
|||
|
|
|
|||
|
|
2. **确认RESET初始状态**:
|
|||
|
|
- 确认硬件设计中RESET引脚的初始状态要求
|
|||
|
|
- 根据确认结果修改CubeMX配置
|
|||
|
|
- 重新生成代码
|
|||
|
|
|
|||
|
|
3. **确认W5500_RESET初始状态**:
|
|||
|
|
- 确认硬件设计中W5500_RESET引脚的初始状态要求
|
|||
|
|
- 根据确认结果修改CubeMX配置
|
|||
|
|
- 重新生成代码
|
|||
|
|
|
|||
|
|
#### 3.3.3 长期执行的工作
|
|||
|
|
|
|||
|
|
1. **完善硬件设计文档**:
|
|||
|
|
- 在硬件设计文档中明确说明每个引脚的驱动方式(高电平有效或低电平有效)
|
|||
|
|
- 在硬件设计文档中明确说明每个引脚的初始状态要求
|
|||
|
|
- 在硬件设计文档中明确说明每个外设的配置参数
|
|||
|
|
|
|||
|
|
2. **完善代码注释**:
|
|||
|
|
- 在关键函数中添加详细的注释
|
|||
|
|
- 说明函数的功能、参数、返回值、注意事项
|
|||
|
|
- 说明硬件相关的配置和驱动方式
|
|||
|
|
|
|||
|
|
3. **建立代码审查机制**:
|
|||
|
|
- 在代码提交前进行代码审查
|
|||
|
|
- 确保代码与设计文档一致
|
|||
|
|
- 确保代码符合最佳实践
|
|||
|
|
|
|||
|
|
4. **建立测试机制**:
|
|||
|
|
- 为每个功能模块编写测试用例
|
|||
|
|
- 在代码修改后进行回归测试
|
|||
|
|
- 确保修改不会引入新的bug
|
|||
|
|
|
|||
|
|
### 3.4 最佳实践建议
|
|||
|
|
|
|||
|
|
#### 3.4.1 硬件设计阶段
|
|||
|
|
|
|||
|
|
1. **明确引脚驱动方式**:
|
|||
|
|
- 在硬件设计文档中明确说明每个GPIO引脚的驱动方式(高电平有效或低电平有效)
|
|||
|
|
- 在原理图中标注LED的驱动方式
|
|||
|
|
- 在PCB设计中标注LED的驱动方式
|
|||
|
|
|
|||
|
|
2. **统一驱动方式**:
|
|||
|
|
- 尽量统一所有LED的驱动方式(全部高电平有效或全部低电平有效)
|
|||
|
|
- 避免混合使用不同的驱动方式
|
|||
|
|
- 便于代码编写和维护
|
|||
|
|
|
|||
|
|
3. **考虑初始状态**:
|
|||
|
|
- 在硬件设计时考虑GPIO引脚的初始状态
|
|||
|
|
- 确保初始状态不会导致意外的硬件行为
|
|||
|
|
- 在硬件设计文档中明确说明初始状态要求
|
|||
|
|
|
|||
|
|
#### 3.4.2 软件开发阶段
|
|||
|
|
|
|||
|
|
1. **使用CubeMX配置**:
|
|||
|
|
- 尽量使用CubeMX进行硬件配置
|
|||
|
|
- 避免手动修改生成的代码
|
|||
|
|
- 确保代码与配置一致
|
|||
|
|
|
|||
|
|
2. **使用宏定义**:
|
|||
|
|
- 使用宏定义抽象硬件层
|
|||
|
|
- 避免在应用层直接使用硬件相关代码
|
|||
|
|
- 提高代码可移植性
|
|||
|
|
|
|||
|
|
3. **添加代码注释**:
|
|||
|
|
- 在关键函数中添加详细的注释
|
|||
|
|
- 说明函数的功能、参数、返回值、注意事项
|
|||
|
|
- 说明硬件相关的配置和驱动方式
|
|||
|
|
|
|||
|
|
4. **进行代码审查**:
|
|||
|
|
- 在代码提交前进行代码审查
|
|||
|
|
- 确保代码与设计文档一致
|
|||
|
|
- 确保代码符合最佳实践
|
|||
|
|
|
|||
|
|
#### 3.4.3 测试阶段
|
|||
|
|
|
|||
|
|
1. **编写测试用例**:
|
|||
|
|
- 为每个功能模块编写测试用例
|
|||
|
|
- 覆盖正常情况和边界情况
|
|||
|
|
- 确保测试用例的完整性
|
|||
|
|
|
|||
|
|
2. **进行回归测试**:
|
|||
|
|
- 在代码修改后进行回归测试
|
|||
|
|
- 确保修改不会引入新的bug
|
|||
|
|
- 确保系统稳定性
|
|||
|
|
|
|||
|
|
3. **记录测试结果**:
|
|||
|
|
- 记录测试结果和发现的问题
|
|||
|
|
- 跟踪问题的解决进度
|
|||
|
|
- 确保所有问题都得到解决
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 附录A:CubeMX配置修改指南
|
|||
|
|
|
|||
|
|
### A.1 修改W5500_CS配置
|
|||
|
|
|
|||
|
|
1. 打开`project.ioc`文件
|
|||
|
|
2. 在Pinout & Configuration视图中,找到PB12引脚
|
|||
|
|
3. 点击PB12引脚,在右侧配置面板中找到"GPIO"配置
|
|||
|
|
4. 将PB12从`SPI2_NSS`改为`GPIO_Output`
|
|||
|
|
5. 在SPI2配置中,确保`NSS = SPI_NSS_SOFT`
|
|||
|
|
6. 保存CubeMX配置
|
|||
|
|
7. 生成代码
|
|||
|
|
|
|||
|
|
### A.2 修改UART3波特率
|
|||
|
|
|
|||
|
|
1. 打开`project.ioc`文件
|
|||
|
|
2. 在Pinout & Configuration视图中,找到USART3
|
|||
|
|
3. 点击USART3,在右侧配置面板中找到"Parameter Settings"
|
|||
|
|
4. 将"Baud Rate"从115200改为9600
|
|||
|
|
5. 保存CubeMX配置
|
|||
|
|
6. 生成代码
|
|||
|
|
|
|||
|
|
### A.3 修改UART中断优先级
|
|||
|
|
|
|||
|
|
1. 打开`project.ioc`文件
|
|||
|
|
2. 在Pinout & Configuration视图中,找到"NVIC Settings"
|
|||
|
|
3. 找到USART2,将"Priority"从0改为1
|
|||
|
|
4. 找到USART3,将"Priority"从0改为2
|
|||
|
|
5. 保存CubeMX配置
|
|||
|
|
6. 生成代码
|
|||
|
|
|
|||
|
|
### A.4 修改LED初始状态
|
|||
|
|
|
|||
|
|
1. 打开`project.ioc`文件
|
|||
|
|
2. 在Pinout & Configuration视图中,找到PB9引脚(LED_TX)
|
|||
|
|
3. 点击PB9引脚,在右侧配置面板中找到"GPIO"配置
|
|||
|
|
4. 找到"GPIO output level"选项
|
|||
|
|
5. 根据硬件设计,将"GPIO output level"设置为"High"或"Low"
|
|||
|
|
6. 对PB3引脚(LED_RX)重复上述步骤
|
|||
|
|
7. 保存CubeMX配置
|
|||
|
|
8. 生成代码
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 附录B:代码修改示例
|
|||
|
|
|
|||
|
|
### B.1 修改LED控制函数(高电平有效)
|
|||
|
|
|
|||
|
|
```c
|
|||
|
|
/**
|
|||
|
|
* @brief 点亮LED_TX
|
|||
|
|
* @note LED_TX为高电平有效(Active High)
|
|||
|
|
* @retval None
|
|||
|
|
*/
|
|||
|
|
void gpio_led_tx_on(void)
|
|||
|
|
{
|
|||
|
|
HAL_GPIO_WritePin(LED_TX_GPIO_Port, LED_TX_Pin, GPIO_PIN_SET);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 熄灭LED_TX
|
|||
|
|
* @note LED_TX为高电平有效(Active High)
|
|||
|
|
* @retval None
|
|||
|
|
*/
|
|||
|
|
void gpio_led_tx_off(void)
|
|||
|
|
{
|
|||
|
|
HAL_GPIO_WritePin(LED_TX_GPIO_Port, LED_TX_Pin, GPIO_PIN_RESET);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 点亮LED_RX
|
|||
|
|
* @note LED_RX为高电平有效(Active High)
|
|||
|
|
* @retval None
|
|||
|
|
*/
|
|||
|
|
void gpio_led_rx_on(void)
|
|||
|
|
{
|
|||
|
|
HAL_GPIO_WritePin(LED_RX_GPIO_Port, LED_RX_Pin, GPIO_PIN_SET);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 熄灭LED_RX
|
|||
|
|
* @note LED_RX为高电平有效(Active High)
|
|||
|
|
* @retval None
|
|||
|
|
*/
|
|||
|
|
void gpio_led_rx_off(void)
|
|||
|
|
{
|
|||
|
|
HAL_GPIO_WritePin(LED_RX_GPIO_Port, LED_RX_Pin, GPIO_PIN_RESET);
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### B.2 修改LED控制函数(低电平有效)
|
|||
|
|
|
|||
|
|
```c
|
|||
|
|
/**
|
|||
|
|
* @brief 点亮LED_TX
|
|||
|
|
* @note LED_TX为低电平有效(Active Low)
|
|||
|
|
* @retval None
|
|||
|
|
*/
|
|||
|
|
void gpio_led_tx_on(void)
|
|||
|
|
{
|
|||
|
|
HAL_GPIO_WritePin(LED_TX_GPIO_Port, LED_TX_Pin, GPIO_PIN_RESET);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 熄灭LED_TX
|
|||
|
|
* @note LED_TX为低电平有效(Active Low)
|
|||
|
|
* @retval None
|
|||
|
|
*/
|
|||
|
|
void gpio_led_tx_off(void)
|
|||
|
|
{
|
|||
|
|
HAL_GPIO_WritePin(LED_TX_GPIO_Port, LED_TX_Pin, GPIO_PIN_SET);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 点亮LED_RX
|
|||
|
|
* @note LED_RX为低电平有效(Active Low)
|
|||
|
|
* @retval None
|
|||
|
|
*/
|
|||
|
|
void gpio_led_rx_on(void)
|
|||
|
|
{
|
|||
|
|
HAL_GPIO_WritePin(LED_RX_GPIO_Port, LED_RX_Pin, GPIO_PIN_RESET);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 熄灭LED_RX
|
|||
|
|
* @note LED_RX为低电平有效(Active Low)
|
|||
|
|
* @retval None
|
|||
|
|
*/
|
|||
|
|
void gpio_led_rx_off(void)
|
|||
|
|
{
|
|||
|
|
HAL_GPIO_WritePin(LED_RX_GPIO_Port, LED_RX_Pin, GPIO_PIN_SET);
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
**文档结束**
|