ATMEGA32的TWI接口写的一个读写PCF8563的程序,不会产生TWINT中断?
马老师,这是我用ATMEGA32的TWI接口写的一个读写PCF8563的程序,本来昨天是可以正确收到从机状态码0x18的,但是今天为什么我发了从机地址后,TWCC值会被修改,并且不会产生TWINT中断呢?//I2c definition
#define I2cError 0x01
#define I2cStart() TWCR = ( 1<<TWINT ) | ( 1<<TWSTA ) | ( 1<<TWEN ) //send start condition
#define I2cStop() TWCR = ( 1<<TWINT ) | ( 1<<TWEN ) | ( 1<<TWSTO ) //trasmit stop condition
#define ClearTWINT() TWCR =( 1<<TWINT ) | ( 1<<TWEN )//clear TWINT in TWCR to start transmit
#define WaitTWINT() while( !( TWCR & ( 1<<TWINT ) ) )
#define CheckI2cStatus() ( TWSR & 0XF8 )
//define I2c status word
#define START 0x08
#define MT_SLA_ACK 0x18
#define MT_SLA_NACK 0x20
#define MT_DATA_ACK 0x28
#define MT_DATA_NACK 0x30
#define MR_SLA_ACK 0X40
#define MR_DATA_ACK 0X50
/************************************************************************/
//Rtc functions list
//MCU Write to I2c slaver
//Mcu Transmit As Master
unsigned charWriteRtc( unsigned char SlaAddr, unsigned char RegAddr, unsigned char *SlaData, unsigned char Length )
{
unsigned char i;
I2cStart();
WaitTWINT(); //wait for TWINT set , caused by start signal
if( CheckI2cStatus() != START )
{
FlagError |= I2cError;
I2cStop();
return( FlagError );
}
TWDR = SlaAddr; //TWDR must be written when TWINT set
ClearTWINT();
WaitTWINT(); //wait forTWINT come, that indicates transmit ok
if( CheckI2cStatus() != MT_SLA_ACK )
{
FlagError |= I2cError;
I2cStop();
return( FlagError );
}
TWDR = RegAddr;
ClearTWINT();
WaitTWINT();
if( CheckI2cStatus() != MT_DATA_ACK )
{
FlagError |= I2cError;
I2cStop();
return( FlagError );
}
for( i = 0; i < Length;)
{
static unsigned char WriteErrorCount;
TWDR = *( SlaData+i );
ClearTWINT();
WaitTWINT();
if( CheckI2cStatus() != MT_DATA_ACK )
{
if( WriteErrorCount++ >20 )
{
I2cStop();
break;
}
FlagError |= I2cError;
continue;
}
i++;
}
I2cStop();
FlagError &= ( I2cError ^ 0xff );
return( FlagError );
}
//MCU Read fromI2c slaver
//Mcu Receive As Master
unsigned char ReadRtc( void )
{
unsigned char Minute, Hour, Day, Week, Month, Year;
I2cStart();
WaitTWINT();
if( CheckI2cStatus() != START )
{
FlagError |= I2cError;
I2cStop();
return( FlagError );
}
TWDR = ReadPcf8563; //send slave address
ClearTWINT();
WaitTWINT();
if( CheckI2cStatus() != MR_SLA_ACK )
{
FlagError |= I2cError;
I2cStop();
return( FlagError );
}
TWDR = SecondAddr; //send register of device
ClearTWINT();
WaitTWINT();
if( CheckI2cStatus() != MR_DATA_ACK )
{
FlagError |= I2cError;
I2cStop();
return( FlagError );
}
I2cStop();
TWDR = ReadPcf8563;
ClearTWINT();
WaitTWINT();
if( CheckI2cStatus() != MR_SLA_ACK )
{
FlagError |= I2cError;
I2cStop();
return( FlagError );
}
DisBuff2 = TWDR; //read second
ClearTWINT();
WaitTWINT();
if( CheckI2cStatus() != MR_DATA_ACK )
{
FlagError |= I2cError;
I2cStop();
return( FlagError );
}
Minute = TWDR; //read Minute
ClearTWINT();
WaitTWINT();
if( CheckI2cStatus() != MR_DATA_ACK )
{
FlagError |= I2cError;
I2cStop();
return( FlagError );
}
DisBuff2 = AnodeSeg[( Minute&0x0f )]; //low byte of Minute
DisBuff2 = AnodeSeg[( Minute>>4 )]; //high byte of Minute
Hour = TWDR; //read Hour
ClearTWINT();
WaitTWINT();
if( CheckI2cStatus() != MR_DATA_ACK )
{
FlagError |= I2cError;
I2cStop();
return( FlagError );
}
DisBuff2 = AnodeSeg; //low byte of beijing hour
DisBuff2 = AnodeSeg[( Hour>>4 )]; //high byte of beijing hour
Day = TWDR; //read Day
ClearTWINT();
WaitTWINT();
if( CheckI2cStatus() != MR_DATA_ACK )
{
FlagError |= I2cError;
I2cStop();
return( FlagError );
}
DisBuff1 = AnodeSeg[( Day>>4 )]; //high byte of day
DisBuff1 = AnodeSeg[( Day&0x0f )]; //low byte of day
Week = TWDR; //read week
ClearTWINT();
WaitTWINT();
if( CheckI2cStatus() != MR_DATA_ACK )
{
FlagError |= I2cError;
I2cStop();
return( FlagError );
}
DisBuff1 = AnodeSeg[( ( 1>>Week )^0xff )]; //week
Month = TWDR; //read Month
ClearTWINT();
WaitTWINT();
if( CheckI2cStatus() != MR_DATA_ACK )
{
FlagError |= I2cError;
I2cStop();
return( FlagError );
}
DisBuff1 = AnodeSeg[( Month>>4 )]; //high byte of month
DisBuff1 = AnodeSeg[( Month&0x0f )]; //low byte of month
Year = TWDR; //read Year
ClearTWINT();
WaitTWINT();
if( CheckI2cStatus() != MR_DATA_ACK )
{
FlagError |= I2cError;
I2cStop();
return( FlagError );
}
DisBuff1 = AnodeSeg[( Year>>4 )]; //high byte of year
DisBuff1 = AnodeSeg[( Year&0x0f)]; //low byte of year
I2cStop();
FlagError &= ( I2cError ^ 0xff );
return( FlagError );
} 给自己顶一个,琢磨了几天了,没瞧出什么来,还请各位大虾指点下 问题已经解决
页:
[1]