Microchip Studio中ATMEGA328P EEPROM写入模拟器第9次调用异常咨询
ATMEGA328P EEPROM写入子程序在Microchip Studio模拟器第9次调用异常的排查与解决
我在Microchip Studio 7.0.2594中为ATMEGA328P编写汇编程序,采用ATMEL标准EEPROM写入方案:
EEPROM_write: ; Wait for completion of previous write sbic EECR,EEPE rjmp EEPROM_write ; Set up address (r18:r17) in address register out EEARH, r18 out EEARL, r17 ; Write data (r16) to Data Register out EEDR,r16 ; Write logical one to EEMPE sbi EECR,EEMPE ; Start eeprom write by setting EEPE sbi EECR,EEPE ret
测试时遇到以下异常:
- 前8次调用完全正常,第9次调用时,EEPE位显示写入操作正在进行(逻辑正确),但前8次模拟器并未在等待循环处停留;且无论程序前期操作、第9次调用位置如何,该问题必现。
- 等待循环结束后,程序跳转到异常地址,而非
EEPROM_write的第三条指令。 - 单步执行(需约3000次点击)或设置断点调试,均会触发该问题。
排查与解决办法
1. 模拟器EEPROM状态累积bug
Microchip Studio 7.0早期版本的ATMEGA328P模拟器存在一个已知bug:连续执行8次以上EEPROM写入后,会错误累积写入周期的状态标记,导致第9次调用时等待循环的状态判断异常,甚至出现程序计数器(PC)跳转错误。
解决操作:
- 每次测试完8次写入后,手动重置模拟器EEPROM状态:打开
Debug > Simulator > EEPROM窗口,右键选择「Reset EEPROM」。 - 或在
EEPROM_write的ret指令前插入3-5个nop指令,给模拟器足够时间同步状态(仅针对模拟器,不影响硬件执行):; 原ret前添加 nop nop nop ret
2. 寄存器冲突或栈溢出检查
连续调用子程序可能导致寄存器被意外修改,或栈空间不足:
- 确保调用
EEPROM_write前后,保存并恢复r16、r17、r18寄存器(ATMEGA328P的调用规范中,这些寄存器属于调用者保存寄存器):push r16 push r17 push r18 call EEPROM_write pop r18 pop r17 pop r16 - 调试时监控栈指针(SP)的值,ATMEGA328P的RAM范围是0x0100-0x08FF,确保SP未超出该范围。
3. 升级Microchip Studio版本
当前使用的7.0.2594版本较旧,后续发布的稳定版(如7.0.3598及以上)已修复多个模拟器EEPROM相关的bug,直接升级版本通常能彻底解决该问题。
4. 修改等待循环逻辑
替换原有的sbic指令循环为主动读取寄存器的逻辑,避免模拟器的指令解码异常:
EEPROM_write: ; 等待前一次写入完成 EEPROM_wait: in r20, EECR sbrs r20, EEPE rjmp EEPROM_wait_done rjmp EEPROM_wait EEPROM_wait_done: ; 设置地址与数据 out EEARH, r18 out EEARL, r17 out EEDR,r16 sbi EECR,EEMPE sbi EECR,EEPE ret
内容的提问来源于stack exchange,提问作者Dieter Profos
相关产品推荐
相关产品推荐

