You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Proteus中STM32F103 GPIOA触发BUS_FAULT故障排查求助

STM32F103 Proteus仿真总线错误(BUS_FAULT)排查方案

我已经确认开启了GPIOA的时钟,但Proteus里的STM32F103仿真还是跑不起来,日志反复弹出这个报错:

"Access to register of unclocked peripheral at 0x40010800 cause BUS_FAULT [U1_CM3CORE]"

以下是我的汇编代码:

.cpu cortex-m3
.fpu softvfp
.thumb

.equ RCC_BASE, (0X40021000)
.equ RCC_APB2ENR, (RCC_BASE + 0x18)
.equ RCC_APB2ENR_IOAEN, 0x00000004
.equ GPIOA_BASE, (0x40010800)
.equ GPIOA_CRL, (GPIOA_BASE +(0x00))
.equ GPIOA1_CRL_MASK, (0b11 << 4)
.equ GPIOA1_CRL_SET_PUSH_PULL_OUTPUT, (0b00 << 4)   
.equ GPIOA_BSRR, (GPIOA_BASE +  0x10)

.global main
main:
    LDR R0, =RCC_APB2ENR
    LDR R1, [R0]
    LDR R2, =RCC_APB2ENR_IOAEN
    ORR R1, R1, R2
    STR R1, [R0]  
    NOP 
    NOP
    NOP
    NOP
    
    LDR R0, =GPIOA_CRL
    LDR R1, [R0]
    LDR R2, =GPIOA1_CRL_MASK
    MVN R2, R2              
    AND R1, R1, R2
    ORR R1, R1, GPIOA1_CRL_SET_PUSH_PULL_OUTPUT
    STR R1, [R0]
    
loop:
    LDR R0, =GPIOA_BSRR
    MOV R1, #(1 << 1)
    STR R1, [R0]
    BL delay
    
    LDR R0, =GPIOA_BSRR
    MOV R1, #(1 << (1 + 16))
    STR R1, [R0]
    BL delay
    b loop
    
delay:
    MOV R2, #50000         
delay_loop:
    SUBS R2, R2, #1        
    BNE delay_loop         
    BX LR                  

问题根源与解决步骤

1. GPIO引脚配置的位掩码和模式错误

STM32F1的GPIO CRL寄存器中,每个引脚对应4位(CNF[1:0] + MODE[1:0]),你的代码里只设置了2位的掩码和模式,导致配置不完整:

  • GPIOA1_CRL_MASK 只覆盖了MODE位(低2位),没清除CNF位(高2位),残留的旧配置会导致外设状态异常
  • GPIOA1_CRL_SET_PUSH_PULL_OUTPUT 设为0b00 <<4是输入模式,不是推挽输出,后续操作输出寄存器会触发错误

修正代码:

.equ GPIOA1_CRL_MASK, (0b1111 << 4)  // 覆盖PA1对应的全部4位
.equ GPIOA1_CRL_SET_PUSH_PULL_OUTPUT, (0b0011 << 4)  // 推挽输出(CNF=00)+ 50MHz速率(MODE=11)

2. 优化时钟使能代码(可选)

原代码用LDR加载立即数可以简化为直接用立即数操作,减少指令周期:

// 替换原时钟使能代码段
LDR R0, =RCC_APB2ENR
LDR R1, [R0]
ORR R1, R1, #RCC_APB2ENR_IOAEN  // 直接用立即数,无需LDR加载
STR R1, [R0]

另外,加的4个NOP完全没必要,硬件上时钟使能是立即生效的,仿真中也不需要额外等待。

3. Proteus仿真环境检查

  • 确认选用的STM32模型是STM32F103C8T6(或对应型号),部分冷门模型的寄存器仿真逻辑有bug
  • 打开Proteus的系统配置,确保勾选了「Peripheral Clock Simulation」选项,否则仿真不会识别时钟使能操作
  • 清空仿真缓存,重新生成hex文件并加载,有时候旧缓存会导致配置不生效

修改后的完整代码

.cpu cortex-m3
.fpu softvfp
.thumb

.equ RCC_BASE, (0X40021000)
.equ RCC_APB2ENR, (RCC_BASE + 0x18)
.equ RCC_APB2ENR_IOAEN, 0x00000004
.equ GPIOA_BASE, (0x40010800)
.equ GPIOA_CRL, (GPIOA_BASE + 0x00)
.equ GPIOA1_CRL_MASK, (0b1111 << 4)
.equ GPIOA1_CRL_SET_PUSH_PULL_OUTPUT, (0b0011 << 4)
.equ GPIOA_BSRR, (GPIOA_BASE + 0x10)

.global main
main:
    // 使能GPIOA时钟
    LDR R0, =RCC_APB2ENR
    LDR R1, [R0]
    ORR R1, R1, #RCC_APB2ENR_IOAEN
    STR R1, [R0]  

    // 配置PA1为推挽输出
    LDR R0, =GPIOA_CRL
    LDR R1, [R0]
    LDR R2, =GPIOA1_CRL_MASK
    MVN R2, R2              
    AND R1, R1, R2
    ORR R1, R1, GPIOA1_CRL_SET_PUSH_PULL_OUTPUT
    STR R1, [R0]
    
loop:
    // PA1置高
    LDR R0, =GPIOA_BSRR
    MOV R1, #(1 << 1)
    STR R1, [R0]
    BL delay
    
    // PA1置低
    LDR R0, =GPIOA_BSRR
    MOV R1, #(1 << (1 + 16))
    STR R1, [R0]
    BL delay
    b loop
    
delay:
    MOV R2, #50000         
delay_loop:
    SUBS R2, R2, #1        
    BNE delay_loop         
    BX LR                  

内容的提问来源于stack exchange,提问作者Long Phan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 12:31:01