这段程序是模仿马潮老师书上写的,但是应用的过程中发现当读的时候会多读一个字节,请高手指点一下,看问题在那儿?
/********************************************************************************************************** * I2C(TWI) **********************************************************************************************************/ // MT: Master Transmit MR: Master Receive // TWI Operation Macros (Work in MT/MR Mode)define1 #define I2C_Start() (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)) #define I2C_Stop() (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN)) #define I2C_Wait() {while(!(TWCR&(1<<TWINT)));} #define I2C_TestAck() (TWSR&0xf8) #define I2C_SetAck() (TWCR|=(1<<TWEA)) #define I2C_SetNoAck() (TWCR&=~(1<<TWEA)) #define Twi_RR() (TWCR=(1<<TWINT)|(1<<TWEN)) //need to Re-Receive #define Twi_SR() (TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWEA)) //Success Received #define I2C_WriteChar(x) {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);}
// TWI Operation Macros (Work in MT/MR Mode) define2 #define i2cSendStart() (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)) #define i2cSendStop() (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN)) #define i2cWaitForComplete() {while(!(TWCR&(1<<TWINT)));}
#define i2cReceiveByte(x) if (x) Twi_SR(); else Twi_RR() #define i2cSendByte(x) {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);} #define i2cGetStatus() inb(TWDR) #define i2cGetReceivedByte() inb(TWSR)
void IICErrStop(void) { I2C_Stop(); DlyUs(100); }
U8 WriteByteIIC( U8 SlaveAddr, U8 RegAddr, U8 *Data, U8 Number) { I2C_Start(); I2C_Wait(); if(I2C_TestAck() != START) { IICErrStop(); return 1; } I2C_WriteChar(SlaveAddr); // 写I2C从器件地址 I2C_Wait(); if(I2C_TestAck() != MT_SLA_ACK) { IICErrStop(); return 2; } I2C_WriteChar(RegAddr); I2C_Wait(); if(I2C_TestAck() != MT_DATA_ACK) { IICErrStop(); return 3; } while(Number--) { I2C_WriteChar(*Data); I2C_Wait(); Data++; if(I2C_TestAck() != MT_DATA_ACK) { IICErrStop(); return 5; } } I2C_Stop(); DlyUs(100); return 0; }
U8 ReadByteIIC( U8 SlaveAddr, U8 RegAddr, U8* Ptr, U8 Number) { I2C_Start(); I2C_Wait(); if(I2C_TestAck() != START) { IICErrStop(); return 1; }
I2C_WriteChar(SlaveAddr + WRITE); // 写I2C从器件地址 I2C_Wait(); if(I2C_TestAck() != MT_SLA_ACK) { IICErrStop(); return 2; } I2C_WriteChar(RegAddr); // The high bit of the address I2C_Wait(); if(I2C_TestAck() != MT_DATA_ACK) { IICErrStop(); return 3; } I2C_Start(); I2C_Wait(); if(I2C_TestAck() != RE_START) { IICErrStop(); return 1; } I2C_WriteChar(SlaveAddr + READ); // Read mode I2C_Wait(); if(I2C_TestAck() != MR_SLA_ACK) { IICErrStop(); return 5; } Twi_SR(); while(Number--) { I2C_Wait(); *Ptr = TWDR; Ptr++; if(Number == 0) { I2C_SetNoAck(); } else { I2C_SetAck(); } } I2C_Wait(); I2C_Stop(); DlyUs(100); return 0; } |