Fórum témák
» Több friss téma |
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
Sziasztok!
Ha megszakításvektorban akarok műveletet végezni valamilyen változóval akkor annak minden esetben globális változónak kell lenni? Továbbá az ISR-t mindig a main előtt kell deklarálni mint a függvényeket? Köszi!
Akkor már inkább ez, de igaz hogy így nincsen csak 1 végtelen ciklus))
vagy méginkább:
A változó legyen globális és volatile.
Az ISR lehet a main után is.
Az ISR lehet a program legvégén is, azt soha nem kell külön deklarálni. Azonban ügyelj arra hogy minden engedélyezendő interrupt le legyen kezelve!
Lokális változókat is nyugodtan használhatsz az interruptodban, akkor a stack-en végzi a műveleteket, de az interrupt befejezése után azokat nem fogod elérni. Például a ciklusváltozókat nem muszáj globálissá tenni... Ügyelj arra, hogy az olyan globális változókat amelyeket az interrupton kívül a "fő programszál" vagy más interrupt is használ, a volatile makrót is tedd eléjük a deklarálásnál!
Ha jót akarsz magadnak, akkor nem csak, hogy globális változónak kell lennie a klasszikus C értelemben. Hanem ráadásul volatile előtagot is kell használni. Ez mondja meg az AVR fordítónak, hogy azt a változót interruptból is lehet változtatni, így minden művelet előtt beolvassa, nem pedig csak egy másolatot tart a regiszterben.
Vedd ezt az esetet: Van egy uint8_t típusú szam nevű változód mondjuk. Ha egy ponton a programban ehhez pl hozzáadsz 100-at, majd azt kiteszed a PORTA-ra, akkor ez így zajlik le kb: Beolvassa azt a változót az SRAM-ból az egyik szabad regiszterbe, elvégzi az összeadást a regiszterben, majd a regisztert teszi ki a PORTA-ra, legvégén pedig a regisztert visszaírja SRAM-ba. Azért dolgozik a regiszterből, mert az piszok gyors. Nos ha az előző példánál egy interrupt pont akkor jön be, miután magának bemásolta a regiszterbe, és az interruptnál eggyel növelnéd az értéket pl. Akkor amikor a regiszterből a rendes programmenet visszaírja az SRAM-ba a regisztert, az fölülírja azt a változtatást, amit csinált az interrupt. Így a helyes x+101 helyett x+100 lesz az SRAMban a legvégén. A volatile változó használata esetén minden műveletet SRAM-ból végez, ami így lassabb lesz. Részleteket lás az app noteokban és adatlapokban. Tehát így használd az előző példa változóját:
Természetesen a függvényeken kívül deklarálva, és ami ezt használni akarja, annak bigyessz oda egy extern deklarációt. Így globális lesz. Ami a második kérdésed illeti, az arról árulkodik, hogy kicsit járatlan vagy C-ben, hiszen a függvényeket bárhol definiálhatod, hogyha a prototípusát a hívása előtt elhelyezed, konvenció szerint erre van ugye a header file. Ami az interrupt függvényt illeti, az is bárhol lehet, feltéve, hogy include-oltad az interrupt.h -t előtte.
A volatile nemcsak a regiszterben-tartás problémáját oldja meg, hanem a több bájtos változók használata előtt letiltja, majd a végén újra engedélyezi(persze ha előtte engedélyezve volt) az interruptokat. Ez egy 16-32 bites változónál rendesen eszi a flashmemóriát, így csak módjával!
Ha jól emlékszem, a megszakításból csak a volatile változókat lehet elérni és használni, a többit nem. Mondjuk ebben nem vagyok biztos, majd kipróbálom...
Koszonom a plusz infot. Ezt reflexbol nem mertem leirni, mert nem voltam total biztos benne.
Rosszul tudod.
A volatile nem tart regiszterben semmit es nem tiltja a megszakitasokat, ha nagyobb a valtozo, mint amit egy lepesben kezelni tudni(es mas esetben sem, erre a programozonak kell figyelnie). Mindossze a forditonak jelzi, hogy nem szabad optimalizalni a valtozo hasznalatat. A flash hasznalatan sokat nem valtoztat.
Sziasztok!
Egy gyors kérdésem lenne, a jártasabbak biztos tudják. Mi a különbség az ATmega8 és az ATmega8A között? Megnéztem az adatlapjukat, de nem vettem észre különbséget, árban viszont a sima 8-as egy kicsit olcsóbb. A bennük lévő memória mérete is megegyezik, pedig arra gyanakodtam, hogy abban különböznek. üdv, Kiwy
Mas benne a mag(ujabb), 2.7-5.5V-ig megy, mig a regi csak 4.5-5.5V-ig ment. Lenyegeben osszevontak a mega8 es mega8L tipusokat. Programozas szempontjabol tudtommal nincsen kulonbseg. Meg az errata is ugyan az.
Na, az jó, erre voltam a leginkább kíváncsi Köszönöm szépen a segítségeteket!
Az összes A-val végződő típus gyakorlatilag teljesen kompatibilis az előző változatokkal. Ha jól rémlik, akkor a gyártásnál alkalmazott csíkszélességet csökkentették, ami ugye elméletben olcsóbb gyártást jelent (természetesen azonos selejt ráta esetén).
Igen, csereszabatosak.
2 lényegi eltérés van: - kisebb áramfelvétel, jobb sleep/idle áramfelvételek - Vref, reset kis eltérés a szórás/billenési értékben Az esetek 99,9%ában csereszabatos a régi 8L/8 és a 8A chip. A régi sorozat kifut, és sok helyen már csak az A sorozat beszerezhető.
Én is így oldanám meg, de a kérdés a végtelen ciklusra volt specifikálva
Sziasztok! Lenne még egy észrevételem ami számomra megmagyarázhatatlan:Amikor a konfigurációnál beállítottam az órajelet(1000000 hz-t)hogy jól működjön az időzítés és 115Khz-et ISP frekvenciának ,hogy az órajel 1/4-énél kisebb legyen (1000000/4=250Khz>115Kh)
Ennek ellenére jött a szokásos hibaüzenet ,hogy kapcsoljam be a CKDIV8-at ,hogy aZ ISP freki és az órajel egálba legyenek.Na ,de egálba volt nem de ? Nos hát mit volt mit tenni bekapcsoltam a fuse-t és így már működött.És mikor elkészítettem a Topi által kifejlesztett jelzőlámpát(mivel még csak kezdő vagyok )az időzítés a Led-ek között hibátlanul ment.Pedig én arra számítottam,hogy a CKDIV8 miatt nyolcszor olyan gyorsan fog menni? Magyarázatot kérek. Előre is köszönöm!
Mégegyszer köszönöm a részletes válaszokat!
A CKDIV8 8-adára LASSÍTJA az órajelet. Ha a FUSE biteknél 8MHz van beállítva(belső órajel) és 1000000Hz az F_CPU-n akkor minden korrekt. A "túl gyors" AVR órajel miatt soha nem hibázhat a programozás, csak ha lassabb mint az ISP freki 4-szerese. Azaz, a CKDIV8 bekapcsolásával inkább növeled a hiba valószínűségét. Persze egy Topi féle programozó tudja a 250kHz-et(még többet is), de az már más kérdés hogy minden ciklus után egy hosszú várakozás jön a szoftveres USB miatt, ezért is olyan lassú.
Tanács: Topi féle programozó mellett a CKDIV8 legyen kikapcsolva, és használd 430kHz-en.
Hellosztok!
PCF8563-at kezelnék Bascom-AVR alatt, de nem tudom, hogyan álljak neki... Mi ennek az ICnek a címe? Hogy kell beállítani az időt? Hogy kell kiolvasni azt? Segítségeteket előre is köszönöm: Hurka
ÓraiC Bascom-AVR alatt: PCF8583, PCF8563, RS5C372A/B....
A I2C-s PCF8563-as IC a Bascom/Samples alatt a clock.bas állományban van leírva. A PCF8563 és a PCF8583 nem kompatibilis!
Sziasztok!
Egy kis C-s segítséget szeretnék kérni. Utánépítettem egy autós fedélzeti komputer projectet. Ez egy cseh project, a Praktiká Elektronika 2010/06 számában található. Több problémám is volt vele. Főképp az, hogy a mellékelt forráskódot a fordítóm túl nagyra fordította, nem fért bele a készülék agyába, egy ATMega8-ba. Ezért "kicsit átszabtam" a forráskódot, kitöröltem belőle néhány funkciót, amire nincs szükségem. Így már befért a Mega8-ba, és egy funkciót kivéve jól működik. Ez a nem műküdő dolog pedig az ECU élőadatainak lekérdezése. Odáig eljut, hogy kapcsolódik az ECU-hoz, szinkronizáció is sikeres. Ezután "Get data...", ezen is túljut, de innen már nem írja ki a vett adatokat. Csak egy "0" van az alsó sor 20. karakterén. Az autómmal minden rendben, laptoppal kiolvasható, a protokoll is stimmel, hardveresen is jónak tűnik. A kérésem: megnéznétek a forráskódot, hogy miért ír nullát a vett adatok helyett ? Lehet, hogy én babráltam el valamit, amikor variáltam a kóddal. Esetleg volna ötletetek, mivel próbáljam lefordítani, hogy az eredeti forrás is kellően kicsi HEX-et eredményezzen ? Kipróbáltam az összes optimalizálási lehetőséget a fordítómban, de így is jóval nagyobb HEX készült, mint a Mega8 memóriája. Hozzáteszem, én nem értek a C-hez, a "nyírbálást" is csak a logika, és az assembly-s tudásom alapján csináltam. Mellékelem az ide vonatkozó, eredeti fájlokat. Bocs, ha kicsit hosszúra sikerült a kérés! Üdv.: Laci.
Hello!
Bár látom hogy TavIR kolléga már megválaszolta a gyakorlati oldalról, én inkább a kérdésedre válaszolnék és adnék pár jótanácsot. Ha egy új IC van a láthatáron, a nulladik lépés mindig az adatlap. Nem kell perfekt angol, de a programozáshoz egy minimális tudás nem árt. Gyorsszótárak is léteznek már. Én is így tanultam meg AVR-ezni: kezdetben nehéz volt, de már tudom hogy mi hol van és ez elég. Szóval: a HE fórumot azért szeretem mert ha kapható náluk a cucc akkor belinkeli. A hozzászólásodnál is ez történt, két kattintás, és már töltöttem is le az adatlapot! A tartalomjegyzék is sokat segít, az eszköz címe 5 másodpercen belül meglett, itt: "I2C-bus protocol" - "Addressing" Akkor a kérdésedre a bűvös válasz: Olvasás: A3h (10100011); Írás: A2h (10100010) Csak egy negyed oldalt kell lefelé lapozni és ott van a regiszterek írási/olvasási mechanizmusa. Bascom alatt viszonylag könnyű, mert az I2C műveletek be vannak építve. AVR Studio és C nyelv mellett sem nehezebb, mert Bascom-mintára megírtam egy jó rövid I2C-könyvtárat, igaz, csak hardvereset. Akkor egy kis általánosítás: Ez az eszköz olyan, aminek regiszterei vannak és az eszköz használata lényegében ezeknek a regisztereknek az írásából-olvasásából áll. Pont mint egy AVR, csak itt kommunikáció van és lényegesen lassabb, de a cél szempontjából nem lényeges. A regiszterek sorszámozva vannak, érdemes a rendes nevükkel definiálni őket, így mindig tudod mit írsz. Könnyen lehet írni egy réteget a kommunikáció fölé, ahol Te már csak a regisztereket írod/olvasod, akár egyetlen műveletben. Így kell ezt csinálni, mert a sok i2cstart/write/read/stop között könnyen el lehet veszni! Az interrupt is a regiszterekkel vezérelhető, de ha használni is akarod(pl. AVR-ébresztő funkció) akkor hardverrel is támogatnod kell: valamelyik INT lábra bekötni, interruptot leprogramozni. Nem könnyű amit leírtam, nem tagadom hogy az MCP23009-es áramkörrel is alaposan meggyűlt a bajom mire szóra bírtam. De a sok tanulság az ami végül oda vezet hogy meg tudd érteni a működését és a jövőben más eszköznek is bátrabban nekiállsz és nem az lesz a legelső kérdésed hogy "mi az eszköz címe".
Nem te vagy az elso ezzel a problemaval. Sokat segitene, ha a kommenteket atforditanad magyarra. (Es esetleg a cseh roviditest/toredekszot/stb tartalmazo valtozok melle kommentelned a jelenteset).
Szia !
Hogy érted, hogy nem én vagyok az első ezzel a problémával ? A cseh tudásom nulla. A Google fordítóján már átküldtem, de sok kifejezést nem ismer, a többit is elég értelmetlenre fordítja. Ezért gondoltam, hogy egy profi C-s a kódból is elég sok mindent kihámoz... Arra kéne rájönni, a szerző mivel fordított, hogy normális méretű HEX-et kapott... Köszönöm a reagálást ! Üdv.: Laci.
A Fuse biteknél hol lehet beállítani az órajelet?
Köszönöm a jó tanácsokat! Én azt a programozót használom amit tőled rendeltem(ha nem tévedek)mert a Topi féle programozót csak KITT-ként lehetett beszerezni én meg nem vagyok valami jó forrasztó,a gépet meg azért nem akartam tönkre vágni ...
Ja és egyébként hol lehet beállítani az órajelet a Fuse biteknél? Köszönöm!
Nem írtad milyen programban, így feltételezem, hogy Avrstudio 4-ben.
Ezek most az eredeti fileok voltak, vagy az amibe már te belebütyköltél?
Azt tudod esetleg, hogy pontosan melyik sorban zajlik az a funkció, ami hibásan történik meg? Ezek az infók mind sokat segítenének annak, aki megnézné a kódot neked. |
Bejelentkezés
Hirdetés |