STM32 Nucleo-L上HAL_Delay失效求助:寄存器R2/R3冲突及替代方案
STM32 Nucleo-L汇编中HAL_Delay异常问题与解决方案
问题背景
我们在计算机科学课程中使用STM32 Nucleo-L控制器编写汇编代码,我受老师委托测试HAL_Delay指令(老师此前使用该指令遇到问题)。测试发现:
- 当寄存器R2或/和R3被用于其他用途时,
HAL_Delay无法正常工作 - 自定义的
wait_ms指令完全正常 - 将代码中
wait_ms替换为HAL_Delay后,代码可正常编译烧录,但按键按下后无任何反应
想咨询:
- 是否应直接改用
wait_ms? - 有没有解决
HAL_Delay问题的方案? HAL_Delay子程序在代码中的具体位置?
测试代码
.syntax unified .equ L152,1 .include "../Core/src/regs.s" .global mainasm mainasm: main: bl startup ldr R1,=GPIOA ldr R2,=GPIOC gruenwechsel: //Wechsel von Rot auf Grün ldr R0,[R2,ODR] //Ampel auf rot setzen mov R0,#0b1 strb R0,[R2,ODR] mov R0,#500 bl wait_ms //500ms Warten ldr R0,[R2,ODR] mov R0,#0b101 //Rote und Grüne LED geichzeitig an strb R0,[R2,ODR] mov R0,#500 //500ms Warten bl wait_ms b Gruen //Ampel auf Grün setzen Gruen: //Grüner Loop ldr R0,[R2,ODR] mov R0,#0b10000 //Ampel auf Grün strb R0,[R2,ODR] ldr R0,[R1,IDR] tst R0,Bit10 //Schauen ob PA10 gedrueckt ist bne rotwechsel //Falls ja, in rotwechsel springen b Gruen rotwechsel: ldr R0,[R2,ODR] mov R0,#0b00100 //Grüne und Gelbe LED Gleichzeitig an strb R0,[R2,ODR] mov R0,#1000 //Warte 1 Sekunde bl wait_ms ldr R0,[R2,ODR] mov R0,#0b00001 //Rote LED an strb R0,[R2,ODR] b Rot Rot: //Roter Loop ldr R0,[R2,ODR] mov R0,#0b000001 //LED Rot an strb R0,[R2,ODR] ldr R0,[R1,IDR] tst R0,Bit10 //Schauen ob PA10 gedrückt ist, falls ja, in Grünwechsel springen bne gruenwechsel b Rot .end
解决方案与说明
1. 是否改用wait_ms?
如果wait_ms能满足课程中的延时需求(精度、功能均达标),直接改用是最高效的选择——它在你的代码环境中工作稳定,无需额外调试成本。
2. HAL_Delay问题的修复方案
HAL_Delay依赖STM32 HAL库的SysTick定时器,且遵循ARM Cortex-M的调用约定:R0-R3属于调用者保存寄存器,子程序可直接修改这些寄存器而无需恢复。你的问题大概率是因为HAL_Delay的实现依赖了R2/R3的值,而你在调用前修改了这两个寄存器,导致HAL_Delay运行异常。
修复步骤:
- 手动保存/恢复寄存器:调用
HAL_Delay前将R2、R3压入栈,调用完成后弹出恢复:// 替换原有bl HAL_Delay的代码段 push {r2, r3} mov r0, #500 bl HAL_Delay pop {r2, r3} - 检查SysTick初始化:
HAL_Delay需要SysTick定时器正常运行提供延时基准,确认你的startup子程序已正确初始化SysTick,或调用了HAL_Init完成HAL库的初始化流程。
3. HAL_Delay的位置
HAL_Delay是STM32 HAL库的标准函数:
- 源码层面:位于HAL库对应型号的
stm32lxx_hal.c文件中(例如stm32l1xx_hal.c或stm32l4xx_hal.c,取决于你的Nucleo-L具体型号) - 编译后:存在于HAL库的静态库文件(如
libstm32lxx_hal.a)中,也可在IDE中通过搜索符号HAL_Delay定位其具体位置。
内容的提问来源于stack exchange,提问作者Alex Biedermann
相关产品推荐
相关产品推荐

