C AVR:main()/ISR干扰
我在C语言的ATmega168(从)上使用I2C(使用avr gcc编译),但这可能是关于中断的一般问题 在我的C程序中,我有一个类型为C AVR:main()/ISR干扰,c,interrupt,avr,i2c,C,Interrupt,Avr,I2c,我在C语言的ATmega168(从)上使用I2C(使用avr gcc编译),但这可能是关于中断的一般问题 在我的C程序中,我有一个类型为uint8\u t i2c\u buffer[32]的全局变量,用于存储一些传感器和配置数据。每当总线主设备读取或写入从设备时,I2C-ISR也会访问该阵列。 在硬件中驱动通信时,通过中断触发到ram(我的I2C缓冲变量)的传输 我知道,由于ISR和我的主例程之间的竞争条件,不小心从ISR和主例程访问变量可能会导致数据损坏,但我不确定如何正确处理。 我被告知在m
uint8\u t i2c\u buffer[32]
的全局变量,用于存储一些传感器和配置数据。每当总线主设备读取或写入从设备时,I2C-ISR也会访问该阵列。
在硬件中驱动通信时,通过中断触发到ram(我的I2C缓冲变量)的传输
我知道,由于ISR和我的主例程之间的竞争条件,不小心从ISR和主例程访问变量可能会导致数据损坏,但我不确定如何正确处理。
我被告知在main访问相关变量时禁用中断。
这将保护变量不被破坏,但另一方面这不会导致数据丢失吗?
如果主机在中断被禁用的情况下尝试发送数据怎么办
我猜,由于I2C接口仍处于启用状态,传入字节至少会写入TWDR。对吗?
如果是:是否有办法在主例程访问完变量后立即触发ISR
并且:如果一个实例(ISR或main)只读取而不写入缓冲区的特定部分,此问题是否会持续存在?通常,您需要在主进程(主程序)中创建一个关键部分。当主程序访问共享变量时,需要禁用中断 您有现成的标准解决方案:
#include <util/atomic.h>
/* ....*/
ATOMIC_BLOCK(ATOMIC_FORCEON)
{
/* potentially non atomic opeartions */
}
#包括
/* ....*/
原子力块(原子力)
{
/*潜在非原子操作*/
}
非常感谢!如果主设备在中断被禁用的情况下进行传输,I2C-ISR是否会在原子_块完成后触发?如果设置了TW中断标志(TWINT),并且启用了TW中断,则立即执行ISR。设置TWINT和启用全局中断时是否相同?这就是想法。只有原子块是受保护的没错!最后一个问题:当使用ATOMIC_块
时,这实际上会在运行时禁用中断(就像cli();
那样),还是会在编译时以任何不同的方式使块“原子化”。如果我在for循环中访问变量,我会在每次迭代中“ATOMIC_BLOCK
”还是包装整个循环?尽量将禁用ISR的时间缩短为possible@SimSon: “如果全局中断状态在进入ATOMIC_块之前不确定,则应使用参数ATOMIC_RESTORESTATE而不是ATOMIC_FORCEON执行。原子_块通过操纵SREG寄存器的全局中断状态(I)位进行操作。”