TWI的START函数死循环了
最近在做IIC通信: ATmega16,WINAVR;通过串口调试发现程序刚进START函数就死那里了
void Start(void)
{
TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while(!(TWCR&(1<<TWINT))); //死在此处
}
在第一句当中,将TWCR的TWINT位置1就是清零,为什么会死在第2句的WHILE语句中呢?
请高手指教,谢谢! while(!(TWCR & BIT(TWINT)));
的意思是,如果TWINT位为0就一直循环……第一句写1清零 TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN); 那么当然会导致While一直在那个地方循环啦。 谢谢 Gorgon Meducer
“TWINT 置1清零”这句话我没理解好!
在网上下载了几个 TWI 的例子,有的START语句就是上面那样写的,现在我就不理解了。 ?????
有的是 TWINT 置1 后延时一段时间,如下:
unsigned char wait;
TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);//开始
wait=32;
while(wait--); TWINT是TWI状态机中断标志位,每当完成一个状态功能,它都会被置位。
你这句话的意思是要发送一个START信号,正常情况下,如果成功发送了一个START信号以后,系统会自动将TWINT位置1。
所以,我仔细回头看了一下TWI的Datasheet,我觉得你这部分代码应该是没有问题的。我建议你想办法监视一下TWSR中的状态码,这样容易帮助分析问题出在什么地方。
void Start(void)
{
TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while(!(TWCR&(1<<TWINT))); //死在此处
} START信号这么写没有问题,我曾这么测试过;就是应该加上一些判断状态的信号,但是如何写我还没时间去测试。
个人认为这种判断是很必要的,作为一个实时系统,很难接受如果一旦TWI通信有问题而死在一个循环点的。
不知道傻孩子有没有这方面的使用经验 to 【9楼】 Alvinwang
我一般直接使用中断模式来驱动状态机,不会采用这种顺序查询模式…… 明白,我用TWI驱动液晶也希望用中断模式,调试中……
也看过ARM上IIC读写EEPROM(友善之臂的例程)的例子,中断中要做很多处理,包括一些状态的判断和数据的发送等等。
但是这种方式,总觉得跟传统说法“中断中不做过多的处理”背道而驰,不知这应该如何处理? to 【11楼】 Alvinwang
传统说的“中断中不做过多的处理”并不是说中断里面不能有过多的代码,而是说
中断不能占用太多的处理器时间,或者说不能一次做过多的事情,而状态机是一种根据
状态执行不同子处理的方法,代码虽多,但是每次执行中断处理程序的时间却并不长,
而且TWI协议本身是一个状态机驱动的通讯协议,对中断处理时间并不非常敏感(在通
讯速度不敏感的前提下),因此采用中断模式的TWI是没有问题的。 多谢傻孩子的提示,会在调试中继续体会。
晚上准备去书店看看你的《深入浅出AVR单片机》~ to 【13楼】 Alvinwang
关于TWI,我在书中有非常详细的介绍,以我理解的方式阐释了时钟同步和仲裁;
也给了详细的利用中断模式建立状态机的讲解。^_^希望多听听您的意见。目前论坛
还没有读者就这个问题给出过回馈——对于TWI的章节,其实也是我的得意之作之一……
页:
[1]