在嵌入式系统中,特殊功能寄存器(SFR)的值在中断服务程序(ISR)发生前被修改时,可能会因非原子操作或时序冲突导致意外结果。以下是系统化的解决方案:
当主程序修改SFR且可能被ISR访问时,需通过以下方法保证操作的不可中断性:
EA=0)。EA=1)。 EA = 0; // 禁用全局中断
SFR_REG = new_value; // 安全修改SFR
EA = 1; // 启用全局中断P0^1),直接使用位操作指令(如SETB/CLR)。bit-band)。 SETB SFR_BIT ; 原子操作,无需禁用中断shadow_SFR)。代码示例:
uint8_t shadow_SFR; // SFR的缓存副本
void main() {
shadow_SFR = new_value; // 先修改副本
if (!in_isr) { // 确认不在ISR中
SFR_REG = shadow_SFR; // 安全写入SFR
}
}
void ISR() {
uint8_t safe_val = shadow_SFR; // ISR使用副本值
}SFR_UPDATE_FLAG)。代码示例:
volatile bool update_flag = false;
void main() {
SFR_REG = new_value;
update_flag = true; // 通知ISR值已更新
}
void ISR() {
if (update_flag) {
// 安全使用SFR_REG
update_flag = false; // 清除标志
}
}TR0=1)避免禁用中断。CLR EA/SETB EA包裹。__disable_irq()和__enable_irq()内核函数。cli()和sei()控制全局中断。
核心准则:
任何可能被ISR访问的共享SFR资源,其修改操作必须通过原子化或同步机制保护,确保主程序与ISR的视图一致性。
通过上述方法,可从根本上避免因SFR异步修改导致的寄存器损坏、信号毛刺或逻辑错误。
举报
更多回帖