Files
433_STM32/docs/代码与设计文档一致性审查及LED控制逻辑异常分析报告_v1.0.md

31 KiB
Raw Blame History

代码与设计文档一致性审查及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 UART1433模块通信

参数 设计文档要求 当前实际配置 状态 备注
引脚 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 UART3485通信

参数 设计文档要求 当前实际配置 状态 备注
引脚 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 SPI2W5500模块

参数 设计文档要求 当前实际配置 状态 备注
引脚 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中断优先级设置为1UART3中断优先级设置为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_TXLED_RX两个指示灯的实际亮灭状态与程序预期相反:

  • 代码意图点亮LED时LED反而熄灭
  • 代码意图熄灭LED时LED反而点亮

2.1.2 当前LED控制代码分析

代码位置: Core/Src/gpio.c 第94-112行

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行

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_SETGPIO_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控制函数:

    原始代码:

    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);
    }
    

    修改后代码:

    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行:

    HAL_GPIO_WritePin(GPIOB, M1_Pin|LED_RX_Pin|LED_TX_Pin, GPIO_PIN_SET);
    

    修改后代码:

    HAL_GPIO_WritePin(GPIOB, M1_Pin|LED_RX_Pin|LED_TX_Pin, GPIO_PIN_RESET);
    
  4. 保存文件并编译项目

修改说明:

  • 交换了GPIO_PIN_SETGPIO_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行的代码

    HAL_GPIO_WritePin(GPIOB, M1_Pin|LED_RX_Pin|LED_TX_Pin, GPIO_PIN_RESET);
    

    或者:

    HAL_GPIO_WritePin(GPIOB, M1_Pin|LED_RX_Pin|LED_TX_Pin, GPIO_PIN_SET);
    

    根据CubeMX配置初始状态应该与配置一致。

  2. 检查LED控制函数:

    打开Core/Src/gpio.c确认LED控制函数

    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);
    }
    

    如果硬件设计为高电平有效,需要修改这些函数:

    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的驱动方式

    /**
     * @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的配置
  • UART1433模块通信的配置
  • SPI2W5500模块的配置
  • 时钟配置

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. 记录测试结果:

    • 记录测试结果和发现的问题
    • 跟踪问题的解决进度
    • 确保所有问题都得到解决

附录ACubeMX配置修改指南

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控制函数高电平有效

/**
 * @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控制函数低电平有效

/**
 * @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);
}

文档结束