откопал старый свой исходник
но тут функции под другие устройства заточены, но все макросы можно использовать.
Код
#define WaitTWI() while (!(TWCR & (1<<TWINT)))
#define TWIStatus() (TWSR & 0xF8)
#define twiSTART 0x08
#define twiRSTART 0x10
#define twiSLA_W_ACK 0x18
#define twiSLA_W_NAK 0x20
#define twiSLA_R_ACK 0x40
#define twiDATA_W_ACK 0x28
#define twiDATA_R_ACK 0x50
#define twiDATA_R_NAK 0x58
#define twiSET_START() TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWSTO)|(1<<TWEN)
#define twiSET_RSTART() TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN)
#define twiSET_STOP() TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN)
#define twiSEND_DATA(DatByte) TWDR=DatByte; TWCR = (1<<TWINT)|(1<<TWEN)
#define twiREQUEST_DATA() TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWEA)
#define twiREQUEST_DATA_NA() TWCR=(1<<TWINT)|(1<<TWEN)
BYTE twiWriteByte(BYTE SlaveAddr, BYTE Reg, BYTE Data);
BYTE twiWriteWord(BYTE SlaveAddr, BYTE Reg, WORD Data);
WORD twiReadByte(BYTE SlaveAddr, BYTE Reg);
WORD twiReadByte1(BYTE SlaveAddr);
DWORD twiReadWord1(BYTE SlaveAddr);
DWORD twiReadWord(BYTE SlaveAddr, BYTE Reg);
BYTE twiWriteByte1(BYTE SlaveAddr, BYTE Data);
BYTE twiWriteCfg(BYTE SlaveAddr, BYTE Reg, BYTE Len, const BYTE __flash* Data);
#define twiWriteAddr(SlaveAddr,FailLabel) {\
BYTE Ack;\
twiSET_START();\
WaitTWI();\
Ack=TWIStatus();\
if ( !((Ack==twiSTART) || (Ack==twiRSTART)) ) goto FailLabel;\
twiSEND_DATA(SlaveAddr);\
Ack=twiSLA_W_ACK;\
if ((SlaveAddr) & 1) Ack=twiSLA_R_ACK;\
WaitTWI();\
if (TWIStatus()!=Ack) goto FailLabel;\
}\
#define twiWriteData(Data,FailLabel) {\
twiSEND_DATA(Data);\
WaitTWI();\
if (TWIStatus()!=twiDATA_W_ACK) goto FailLabel;\
}\
#define twiReadDataNa(Res,FailLabel) {\
BYTE Ack;\
twiREQUEST_DATA_NA();\
WaitTWI();\
Ack=TWIStatus();\
Res=TWDR;\
if (Ack!=twiDATA_R_NAK) goto FailLabel;\
}
#define twiReadData(Res,FailLabel) {\
BYTE Ack;\
twiREQUEST_DATA();\
WaitTWI();\
Ack=TWIStatus();\
Res=TWDR;\
if (Ack!=twiDATA_R_ACK) goto FailLabel;\
}
WORD twiReadByte(BYTE SlaveAddr, BYTE Reg)
{
BYTE Res;
twiWriteAddr(SlaveAddr,Fail);
twiWriteData(Reg,Fail);
twiWriteAddr(SlaveAddr|1,Fail);
twiReadDataNa(Res,Fail);
twiSET_STOP();
return Res;
Fail:
twiSET_STOP();
return 0xFFFF;
}
WORD twiReadByte1(BYTE SlaveAddr)
{
BYTE Res;
twiWriteAddr(SlaveAddr|1,Fail);
twiReadData(Res,Fail);
twiSET_STOP();
return Res;
Fail:
twiSET_STOP();
return 0xFFFF;
}
DWORD twiReadWord1(BYTE SlaveAddr)
{
BYTE Res1,Res2;
twiWriteAddr(SlaveAddr|1,Fail);
twiReadData(Res1,Fail);
twiReadData(Res2,Fail);
twiSET_STOP();
return (WORD)(Res2 | (Res1<<8));
Fail:
twiSET_STOP();
return 0xFFFFFFFF;
}
BYTE twiWriteByte1(BYTE SlaveAddr, BYTE Data)
{
twiWriteAddr(SlaveAddr,Fail);
twiWriteData(Data,Fail);
twiSET_STOP();
return 1;
Fail:
twiSET_STOP();
return 0;
}
DWORD twiReadWord(BYTE SlaveAddr, BYTE Reg)
{
BYTE Res1,Res2;
twiWriteAddr(SlaveAddr,Fail);
twiWriteData(Reg,Fail);
twiWriteAddr(SlaveAddr|1,Fail);
twiReadData(Res1,Fail);
twiReadDataNa(Res2,Fail);
twiSET_STOP();
return (WORD)(Res1 | (Res2<<8));
Fail:
twiSET_STOP();
return 0xFFFFFFFF;
}
BYTE twiWriteByte(BYTE SlaveAddr, BYTE Reg, BYTE Data)
{
twiWriteAddr(SlaveAddr,Fail);
twiWriteData(Reg,Fail);
twiWriteData(Data,Fail);
twiSET_STOP();
return 1;
Fail:
twiSET_STOP();
return 0;
}
BYTE twiWriteWord(BYTE SlaveAddr, BYTE Reg, WORD Data)
{
twiWriteAddr(SlaveAddr,Fail);
twiWriteData(Reg,Fail);
twiWriteData(Data,Fail);
twiWriteData((BYTE)(Data>>8),Fail);
twiSET_STOP();
return 1;
Fail:
twiSET_STOP();
return 0;
}
BYTE twiWriteCfg(BYTE SlaveAddr, BYTE Reg, BYTE Len, const BYTE __flash* Data)
{
twiWriteAddr(SlaveAddr,Fail);
twiWriteData(Reg,Fail);
do {
twiWriteData(*Data++,Fail);
} while(--Len);
twiSET_STOP();
return 1;
Fail:
twiSET_STOP();
return 0;
}