最近在调试时钟芯片 PCF8563 与 ATMEGA128的IIC通讯。 使用的是模拟IIC. 附上 几个程序 并告知我的问题所在,希望有高手可以指点迷津: void Start() { SET_SDA; SET_SCL; __asm__ volatile("nop"); __asm__ volatile("nop"); CLR_SDA; __asm__ volatile("nop"); __asm__ volatile("nop"); CLR_SCL; } void Stop() { CLR_SDA; SET_SCL; __asm__ volatile("nop"); __asm__ volatile("nop"); SET_SDA; __asm__ volatile("nop"); __asm__ volatile("nop"); CLR_SCL; } void WaitACK() { UCHAR errtime=20; UCHAR tp=0; // SDA_IN; DDRD=DDRD&0xfd; PORTD=PORTD|0x02; ///0:禁止上拉;1:使能上拉 PIND=PIND&0xfd; SET_SCL; // __asm__ volatile("nop"); __asm__ volatile("nop"); tp=PIND; while(tp&0x02) { if(errtime) errtime--; else Stop(); __asm__ volatile("nop"); tp=PIND; } CLR_SCL; }
void writebyte(UCHAR wdata) { UCHAR i;
SDA_OUT;
for(i=0;i<8;i++) { if(wdata&0x80) SET_SDA; else CLR_SDA; SET_SCL; __asm__ volatile("nop"); __asm__ volatile("nop"); CLR_SCL; // __asm__ volatile("nop"); // __asm__ volatile("nop"); wdata<<=1; } WaitACK(); //I2C器件或通讯出错,将会退出I2C通讯 }
void writeData(UCHAR address,UCHAR mdata) { cli(); Start(); writebyte(0xa2); //*写命令 writebyte(address); //*写地址 writebyte(mdata); //*写数据 Stop(); }
这是几个子函数。时序方面我都对过了,不应该有什么错误。现在的问题 就是 WaitACK()函数里面的循环 while(tp&0x02) { if(errtime) errtime--; else Stop(); __asm__ volatile("nop"); tp=PIND; }始终也跳不出来。 我这个函数是在写完一个字节给从机之后,检测从机是否返回一个低电平信号的。按照IIC协议上说,如果返回的是个低电平,则说明写成功;否则,则说明写失败。 我现在 无法跳出循环,就说明检测到的这个信号,始终为高电平。这是我一直困惑的。 想请同时 熟悉AVR的 朋友给看看,我的寄存器使用是否有错误,但是感觉上好像也应该就是这样的。谢谢大家~~~~~ |