Zahada v C
Pavel Hudeček
edizon na seznam.cz
Čtvrtek Prosinec 11 01:15:42 CET 2014
Dobrý den všem,
mějme následující kus kódu, běžící ve dříve zmíněném bastlu s ATmega8 a
displejem:
si7020_measure(&H, &T);
dispXY(0, 0);
dispInk(GLCD_CL_BLACK);
dispUInt(i2cAck);
dispX=100;
dispCas("cas: ", sec);
dispX=180;
if (TRI2_out==0) {
. dispTextF("2vyp ");
. dispUInt(secPer/60); dispChr('/'); dispUInt(PER_vyp/60); dispChr(32);
} else {
. dispTextF("2zap ");
. dispUInt(secPer/60); dispChr('/'); dispUInt(PER_zap/60); dispChr(32);
}
dispX=16;
dispInk(GLCD_CL_BLUE);
dispTextF("RH x10 ");
dispUInt(H); dispChr(32); dispChr(32);
dispPt(H-300, y1);
dispPt(H-300, y2);
dispInk(GLCD_CL_WHITE);
dispXY(0, y2+1);
dispLine(240, 0);
dispInk(GLCD_CL_GREEN);
dispXY(0, y2+2);
dispLine(240, 0);
dispXY(16, 8);
dispInk(GLCD_CL_RED);
dispTextF("T x100 ");
dispUInt(T); dispChr(32); dispChr(32);
dispPt((T-2100)/2, y1);
dispPt((T-2100)/2, y2);
Který je uvnitř while(1). Všechny proměnné jsou signed int. Je tam ještě
čekání 1 s, mazání konce předchozích grafů a jejich zacyklení. Volané funkce
zde:
void dispUInt(unsigned long x) { // ----------------------------------------
------------
. unsigned char n;
. unsigned long L=1000000000, M;
. if (x==0) {dispChr('0'); return;}
. for (L=1000000000; L>0; L/=10) if (x>=L) break;
. for (M=x; L>0; L/=10) {
. n=M/L;
. if (L==1000 || L==1000000 || L==1000000000) dispMezera=2;
. dispChr(n+'0');
. M-=n*L;
. }
}
// mereni RH a T: vysledek ulozen do *H a *T. RH v % x10, T ve st.C x100.
Pri OK je i2cAck=0.
void si7020_measure(signed int *H, signed int *T) { // ---------------------
------------
. unsigned char a, b;
. signed long L;
. i2cAck=0;
. i2cByteWS(SI7_adr+I2C_wr);
. i2cByteW(0xf5);
. if (i2cAck>0) return;
. a=0;
. do {
. i2cStop();
. SI7020_wait(2);
. i2cAck=0;
. i2cByteWS(SI7_adr+I2C_rd);
. a++;
. } while (i2cAck>0 && a<200);
. if (i2cAck>0) return;
. a=i2cByteR(0);
. b=i2cByteRS(1);
. L=((unsigned long)a<<8)+b;
. L*=1250;
. L=(L>>16)-60;
. *H=(signed int)L;
. i2cByteWS(SI7_adr+I2C_wr);
. i2cByteW(0xe0);
. i2cStop();
. i2cByteWS(SI7_adr+I2C_rd);
. a=i2cByteR(0);
. b=i2cByteRS(1);
. L=(unsigned long)(a<<8)+b;
. L*=17572;
. L=(L>>16)-4685;
. *T=(signed int)L;
}
Problém je následující: Všechno funguje jak má, nahoře jsou zobrazeny txt
údaje, dole pod sebou rychlý a pomalý graf, ... ale: Někdy se stane, že se
hodnota RH x10 jaksi zasekne: Prostě tam je stále třeba 343, jako zrovna
teď. graf ovšem vesele jezdí, jako by nic, takže hodnota H se zjevně stále
mění. Ostatní hodnoty se taky normálně mění a to na grafech i zobrazovaná
čísla.
Když zařízení resetnu, všechno funguje OK, ale RH x10 zas po nějakém čase
vytuhne. Ale ne úplně. Někdy na čas "obživne" a mění s spolu s grafem.
WTF?
Děkuji,
PH
------------- další část ---------------
HTML příloha byla odstraněna...
URL: <http://list.hw.cz/pipermail/hw-list/attachments/20141211/96341b8c/attachment.html>
Další informace o konferenci Hw-list