Egy ismert probléma megoldását szeretném kérni tőletek.
Adott egy DS1621 hőmérőm és mindig kb. 2 fokkal többet mutat, mint a valódi. Utána olvastam és több elméletet kipróbáltam már, de nincs eredmény, ezért döntöttem a teljes kód beszúrása mellett. Az I2C fgv-ekről annyit, hogy az összes állapothoz tartozó TWSR érték megfelelő, csak most a próba alatt ezt nem szedtem ki. A TempUpdate a főprogramból kerül meghívásra x időnként. Az alap jelenleg az, hogy Done bit ell, ha OK, mehet a 1shot és a Start konverzió, majd várok egy kicsit, újra Done bit ellenőrzés és érték kiolvasás. DE ez nem kalács. Előre is köszi a segítséget és bocsi a c miatt, de nem hinném, hogy ez gondot okozna nektek.
Kód: Egész kijelölése
#define I2C_START TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN)
#define I2C_EN TWCR = (1<<TWINT)|(1<<TWEN)
#define I2C_STOP TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN)
#define I2C_ACK_EN TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA)
#define I2C_ACK while (!(TWCR & (1<<TWINT)))
int I2Ccommand,I2Caddress,I2Cdata,I2CClockStatus,I2Chibajel,bflag;
int i,TH,TL;
int TempUpdate()
{
I2CBusy(144,0xAC); // busy flag ellenőrzés
if(bflag == 128) // konverzió kész, kezdődhet a mérés
{ // vagy a hőmérséklet értékek kiolvasása
// PORTC = 1; // vizuális ellenőrzés
I2C1shot(144,0xAC,1); // 1shot
I2Cstart(144,0xEE); // Start Convert
I2CBusy(144,0xAC);
if(!(bflag == 128)) // itt még nincs kész a konverzió (ez csak
// PORTC = 0; // próbának szúrtam be: rendben
// működik az I2CBusy függvényem)
// vizuális ellenőrzés
_delay_ms(1000); // várok ezerrel, a konvetálás
// befejezéséhez (teszt üzemmód)
I2CBusy(144,0xAC); // busy flag ellenőrzés
if(bflag == 128) // itt már kész a konverzió
{
// PORTC = 2; // vizuális ellenőrzés
_delay_ms(100); // kis delay, hogy lássam is
I2CTempRead(144,0xAA); // hőmérséklet értékek kiolvasása
}
// PORTC = 0; // vizuális ellenőrzés
}
else
;
itoa(TH, LcdText+17,10); // kijelzés
if(TL == 128)
TL = 5;
itoa(TL, LcdText+20,10);
memcpy(LcdText+19,".",1);
memcpy(LcdText+22,"C",1);
LcdText[21] = 223;
}
int I2Cstart(int I2Caddress, int I2Ccommand)
{
I2C_START;
while (!(TWCR & (1<<TWINT))) // START
;
TWDR = I2Caddress; // SLA + W
I2C_EN;
while (!(TWCR & (1<<TWINT)))
;
TWDR = I2Ccommand; // Command
I2C_EN;
while (!(TWCR & (1<<TWINT)))
;
I2C_STOP; // STOP
}
int I2C1shot(int I2Caddress, int I2Ccommand, int I2Cdata)
{
I2C_START;
while (!(TWCR & (1<<TWINT)))
;
TWDR = I2Caddress; // Slave address + 0
I2C_EN; // SLA+W
while (!(TWCR & (1<<TWINT)))
;
TWDR = I2Ccommand; // Access Config
I2C_EN;
while (!(TWCR & (1<<TWINT)))
;
TWDR = I2Cdata; // 1 shot
I2C_EN;
while (!(TWCR & (1<<TWINT)))
;
I2C_STOP;
}
int I2CTempRead(int I2Caddress, int I2Ccommand)
{
I2C_START;
while (!(TWCR & (1<<TWINT)))
;
TWDR = I2Caddress; // Slave address + 0
I2C_ACK_EN; // SLA+W
while (!(TWCR & (1<<TWINT)))
;
TWDR = I2Ccommand;
I2C_ACK_EN; // ACKEN
while (!(TWCR & (1<<TWINT)))
;
I2C_START; // REPEATED START
while (!(TWCR & (1<<TWINT)))
;
TWDR = I2Caddress + 1; //SLA + R
I2C_EN;
while (!(TWCR & (1<<TWINT)))
;
I2C_ACK_EN;
while (!(TWCR & (1<<TWINT)))
;
TH = TWDR;
I2C_EN;
while (!(TWCR & (1<<TWINT)))
;
TL = TWDR;
I2C_STOP;
if((TH & 128) == 128)
{
memcpy(LcdText+16,"-",1);
TH = TH - 1;
TH = TH^255;
}
else
memcpy(LcdText+16,"+",1);
}
int I2CBusy(int I2Caddress, int I2Ccommand)
{
I2C_START;
while (!(TWCR & (1<<TWINT)))
;
TWDR = I2Caddress; // Slave address + 0
I2C_EN; // SLA+W
while (!(TWCR & (1<<TWINT)))
;
TWDR = I2Ccommand; // configuration register
I2C_EN;
while (!(TWCR & (1<<TWINT)))
;
I2C_START; // REPEATED START
while (!(TWCR & (1<<TWINT)))
;
TWDR = I2Caddress + 1; // SLA+R
I2C_EN;
while (!(TWCR & (1<<TWINT)))
;
I2C_EN;
while (!(TWCR & (1<<TWINT)))
;
bflag = TWDR&128;
I2C_STOP;
}