Fórum témák

» Több friss téma
Fórum » AVR - Miértek hogyanok
WinAVR / GCC alapszabályok:
1. Ha ISR-ben használsz globális változót, az legyen "volatile"
2. Soha ne érjen véget a main() függvény
3. UART/USART hibák 99,9% a rossz órajel miatt van
4. Kerüld el a -O0 optimalizációs beállítást minden áron
5. Ha nem jó a _delay időzítése, akkor túllépted a 65ms-et, vagy rossz az optimalizációs beállítás
6. Ha a PORTC-n nem működik valami, kapcsold ki a JTAG-et
Bővebben: AVR-libc FAQ
Lapozás: OK   626 / 626
(#) Droot válasza vzoole hozzászólására (») Pé, 20:31 /
 
Tökéletesen működik!

Hogy lehet megcsinálni, hogy ne csak egész számokat tudjon kezelni?
(#) killbill válasza Droot hozzászólására (») Pé, 20:37 /
 
Azert kell neggyel osztani, mert az also ket bit nem a homerseklethez tartozik, a kovetkezo ket bit pedig a tizedes resz, azaz a 0.5 es 0.25 fokok bitjei. A sprintf-ben nem egyszeru a ket tizedes kiiras, mert ha azt kapod az IC-bol, hogy 3, akkor az 0.75 fok. Egy nem tul elegans megoldas, ha pl. megszorzod 25-tel a kapott eredmenyt, es azt iratod ki ket reszletben. Csak ott is szivas van a tort resz elojelevel:

  1. #define ABS(x) ((x<0)?-(x):(x))
  2.  
  3. void func(void)
  4. {
  5. int  kt, it;
  6.  
  7.  CS_LOW();
  8.  kt = spi_read(0) << 8;
  9.  kt |= spi_read(0);
  10.  it = spi_read(0) << 8;
  11.  it |= spi_read(0);
  12.  CS_HIGH();
  13.  
  14.  kt >>= 2// also ket bit nem kell, az elojel megmarad
  15.  kt *= 25;
  16.  printf("%d.%d", kt / 100, ABS(kt%100));
  17. }

Ha ugyanezt lebegopontosan oldod meg, akkor valamivel egyszerubb a kiiratas, de valojaban sokkal tobb kodba kerul a lebegopontos aritmetika hozzalinkelese miatt:

  1. double temp;
  2.  CS_LOW();
  3.  kt = .....
  4.  CS_HIGH();
  5.  kt >>= 2// also ket bit nem kell, az elojel megmarad
  6.  temp = 0.25 * kt;
  7.  printf("%6.2fC", temp);
(#) Droot válasza killbill hozzászólására (») Pé, 20:39 /
 
Köszönöm a gyors válaszokat neked is és Zolinak is! A legvégén nem lesz szükségem a tizedesek kiírására, de szeretném megérteni, ezért jól jött hogy leírtad.
(#) vzoole válasza Droot hozzászólására (») Pé, 20:40 /
 
Én nem terhelném le az AVR-t tört változókkal.
Külön kezelném a tört értékeket egész számként.
Persze ez függ a felhasználási területtől is.
  1. //hőelem tizedes
  2. tizedes_ertek = ( (data_H>>2) & 0x3 ) * 25;
A hozzászólás módosítva: Pé, 20:44
(#) killbill válasza vzoole hozzászólására (») Pé, 23:50 /
 
Jogos, csak akkor a negativ szamok eseteben maskepp kell dolgozni. Ha csak siman eldobod az also ket bitet a szambol, amikor az egeszeket kepzed, akkor a negagiv ertekeknel kulon oda kell figyelni, mert a -1, -2 es -3 ertekek -0.25, -0.5, -0.75 foknak felel meg. Ha csak siman eldobod az also ket bitet, akkor az egesz resz -1 lenne, pedig annak nullanak kellene lennie. Ezen felul a tizedeseket sem kepezheted ugy, hogy az also ket bitet szorzod 25-tel, mert negativ homersekletnel az sem lesz jo. Ennel egyszerubb, ha negativ homerseklet eseten, kiirsz egy minusz jelet, es a szamot negalod, es utana pont ugy kezeled, mint a pozitiv homersekleteket.
A hozzászólás módosítva: Pé, 23:54
(#) killbill válasza killbill hozzászólására (») Szo, 0:13 /
 
Nem is jo a kodreszlet, amit irtam, mert -0.25 es -0.75 fok kozott hibas erteket ir, mivel ezekben az esetekben az egesz resz nulla, igy nem fogja kiirni a minusz jelet... A floatos megoldas jo, csak az irtozatos pazarlas.
(#) vzoole válasza killbill hozzászólására (») Szo, 1:07 /
 
Ez a része tényleg beugratós, észre se vettem.

Még egy olyan megoldást tudnék elképzelni, hogy a hőelem adatán az alsó két bitet lemaszkoljuk, és így használjuk fel előjeles egész számként. Csak minden számítási műveletnél figyelembe kell venni, hogy az aktuális hőmérséklet 16 szoros értékével dolgozunk.

Egyedül a megjelenítésnél kell egy pár művelet, ahol külön kezelnénk az előjelet, az egész értéket és a tizedest. Talán még mindig kevésbé lenne erőforrás igényes mint egy lebegőpontos szám.

Persze, terminálon átküldve nem lenne jó, de az szerintem nem is végtermék megoldás. Ha PC-n kell megjeleníteni, akkor oda is átmehet egészként és majd az ottani program konvertálja át magának tizedesre.
A hozzászólás módosítva: Szo, 1:08
(#) killbill válasza vzoole hozzászólására (») Szo, 11:02 /
 
Maszkolas helyett inkabb elshiftelem ket bittel jobbra. Akkor is elojeles egesz szam marad, de minden bit hasznos lesz benne, nem kell kulon foglalkozni azzal, hogy az also ket bit mindig nulla. Tort szam marad igy is, hiszen az also ket bit 0.75 fokot "ér", de ettol meg szamolni konnyen lehet vele. Es ahogy mondod, a kiirasnal kell csak vacakolni a szetszedessel. A 25-os szorzast is csak a kiirasra javasoltam, egyeb muveletekre a 14 bites erteket jobbra igazitva a legcelszerubb hasznalni. Terminalra ASCII-t kuldesz, ez adja magat. De hat az a kiiratas, maga.
(#) vzoole válasza killbill hozzászólására (») Szo, 14:22 /
 
Tehát ha előjeles számot shift-elek az előjel marad a helyén?
(#) killbill válasza vzoole hozzászólására (») Szo, 14:29 /
 
Igen. 0x8000 >> 1 = 0xc000. Ha elojeles szamot shiftelsz jobbra, akkor a legfelso bit megmarad, es az eggyel alacsonyabb helyierteku bitre is a legfelso bit masolodik be. Assembly-ben ez altalaban az ASR, Arithmetic Shift Right. Balra shiftelesnel az also bitbe nulla megy mindig.
A hozzászólás módosítva: Szo, 14:30
Következő: »»   626 / 626
Bejelentkezés

Belépés

Hirdetés
Frissek
2014. Okt, 20. Hé
10:10:52
Jelenleg 422 fő olvassa az oldalt
Online tagok:
Lapoda.hu     XDT.hu     HEStore.hu