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