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
Szia!
Az AVR Studio ingyenes, lehet benne assemblyben programozni, proci és égető nélkül is tud szimulációt futtatni. (Persze vannak korlátai, mert azt nem tudod megadni neki, hogy az ADC bemeneten 3 Volt van, a referencia feszültségre 4V-ot kötöttél, ő pedig mondja meg mit mérne.) Én csak assemblyben programoztam, kellemesen lehet makrózni és úgy már szinte magas szintű programhoz hasonlóan kódolhatsz.
Az AVR Studio-val milyen égetőt használsz?
Ezzel égettem: AVRISP-mkII kompatibilis programozó. Azt nem tudom, hogy az eredeti mkII-vel is kell úgy trükközni a driverekkel, mint ennél vagy az pöc-röff megy?
A hozzászólás módosítva: Jan 31, 2017
Természetesen programozhatsz C-ben is (kivéve a legkisebb uC-ket). Kezdőként szerintem szerencsésebb irány mint az assembly, mivel jóval hamarabb lesz sikerélményed. Használhatsz egyébként C-n belül (és az Arduino-s C++-on belül is) assembly betéteket, ha úgy érzed bizonyos részeket úgy jobban el tudsz készíteni.
Léteznek még (fizetős) fordítók, amikkel lehet Basic-ben és Pascal-ban is programozni, de ha már az Arduinos C++ ment, akkor a C-vel is boldogulni fogsz.
Üdv!
Az Atmel Studio 7 szimulátorát próbálgattam és egyből egy problémába ütköztem.
A kódban 3db megszakítást raktam. A leggyakrabban a 2.-dik aktiválódik. Már ennél jelentkezik egy hiba. Pontosabban a megszakítást párszor léptetem (Continue), akkor az OCR1A értéke módosul. 0x383f-ről 0x003f-re, azaz ledobja a high byte(OCR1AH) értékét. Ez szimulációs hiba, vagy én hagyok ki valamit, ami "rögzítené" az OCR1AH-t?
Próbáld ki ezzel a beállítással:
Debug -> Options -> Tools -> Tool Settings -> Mask Interrupts while stepping -> False
Köszönöm a válaszaitokat!
Az AVR Studioban van C fordító esetleg? Ha nincs, ti melyik fordítót használjátok hozzá (mármint C programozáshoz)? Gondolom a legkisebb mikrokontrollereket a kisméretű flashmemória miatt célszerűbb assemblyben programozni.
Helló Kovidivi!
Mégegyszer köszönet a gombrutin kódért. A napokban alkalmaztam is. Elég nehéz volt rájönnöm a működésére, mert eddig nem ismertem a bitműveletek használati módját, azok operátorait. Módosítottam pár dolgot: 1.) 4 gombot figyel 2.) kivettem a NOT bitoperátort a 'PIND' elől, így már a lenyomáskor értelmezi a rutin a lenyomást, nem csak felengedéskor 3.) 5s-ként fut le Lenne pár kérdésem ![]() 1.) Hol figyeli a rutin a lenyomási és felengedési időtartamot (40ms és 30ms)? Ezen szeretnék változtatni. 2.) Miért csak 10s-ként fut a rutin? Gondolom nem probléma, ha nálam pl folyamatosan fut?
Ez nem segített
![]()
ATmega128 -at C-ben programozok. avr-gcc-vel fordítok. Az MCU 16MHz-es külső órajelet kap. Az ADC valamiért kissé érdekesen működik. A konverziót helyes eredménnyel elvégzi, csak folyamatosan megszakítást generál.
A következő képpen állítom be a perifériát:
Ennek hatására másodpercenként 7800-szor hívódik meg az ISR. (Ekkor nem sokat csináltam, csupán egy számlálót léptettem, amivel mértem ezt a 7800-at, és egy ledet ki-be kapcsolgattam a konverzió eredményétől függően. Ha több mindent is csináltam benne, akkor ez a szám csökkent valamennyit.)
Én azt vártam volna, hogy konverzió csak akkor induljon (és akkor is csak egy), ha ezek után az ADCSRA-ban beírom az ADSC bitet. Most kb. olyan mintha szabadon futó módban lenne, pedig nincs. (Próbálkoztam az ADFR bit beírásával/törlésével, de nem segített.) Valakinek valami ötlete esetleg? Előre is köszi!
Az ADC-t hol indítod el? A while(1)-ban van egy egyszer lefutó parancs, vagy még a main()-ben?
Csak gyűlnek a "jó" nyomógombkezelő rutinok. Íme az enyém amit régóta csiszolok, a mostani verziót az RFID kártyaolvasóba "fejlesztettem ki". Hiszterézises szimmetrikus pergésmentesítő:
Működés: a nyomógombot az időzítő megszakítás figyeli, állapotától függően egy számlálót növel vagy csökkent. A számláló értéke felülről és alulról is korlátos. Ha felfelé számláláskor eléri a felső határt, egy globális változót átbillent 1-re, ha lefelé számlálva éri el a nullát akkor 0-ra. A nyomógomb lenyomás (vagy felengedés) szoftveres érzékelése a Schmitt-triggerhez hasonlítható. Ha egyszer átbillen az állapotváltozó, a "visszabillentés" időbe telik. A számláló felső korlátját (így az átbillentés késleltetését) úgy kell meghatározni, hogy a nyomógomb pergése és az érzékelés késleltetése között elfogadható kompromisszumot találjunk. Érzékeny gépeknél inkább nagy értéket(100-200ms) adok meg, hadd nyomkodja a parasztja! A megoldás előnye, hogy az egész nyomógomb figyelés precíz, órajelhez igazított, és teljesen a "háttérben" fut. Úgy mintha a "BTN_PRESSED" változóval ténylegesen egy (nem-pergő) nyomógombot kérdeznék le. Az algoritmus tömbösíthető, több nyomógombra kiterjeszthető. Egy korábbi változatát 12-gombos charlieplexingre készítettem el! Külön köszönet egy korábbi hozzászólónak a "static" bemutatásáért, így szebb lett a kód. ![]() A hozzászólás módosítva: Feb 1, 2017
Én Atmel Studio 7-et szoktam használni.
Tetszik. Felépítésében hasonlít kicsit az arduino-féle debounce példaprogihoz. Azt csak egy gombra tudtam alkalmazni. Monduk így jó szolgálatot tett a fordulatszámmérő-gyújtásjeladó progim alapjaként.
A te rutinod hogyan terjeszthető ki több gombra, ciklussal alkalmazásával ès gombok bemeneteinek tömbbe(vektorba) pakolásával, igaz? Jók ezek a rutinok egyébként, működnek is, viszont szerintem én áttérek az IC-s pergésmentesítésre. A hozzászólás módosítva: Feb 2, 2017
A main fv-ben, a sei(); és a while(1) előtt.
Sziasztok!
Egy hete már kísérleteztem az UART perifériával több-kevesebb sikerrel és sikerült elérnem, hogy egy szöveget ki tudjak rakni egy soros monitorba. Aztán szerettem volna egy olyan programot készíteni, ami adatot (egy karaktert) fogad a PC-től és attól függően megváltoztatja egy villogó RGB led színét valamint egy visszajelzést is küld a PC-nek, hogy éppen milyen a led színe. A program viszont nem működik. A led nem csinál semmit és visszajelzés sem érkezik a PC felé. Szerintem valahol az adat fogadásnál lehet a hiba vagy az érték átadásnál, de eddig még nem jöttem rá. Tudnátok benne segíteni?
A nyomógombok bemeneteit ilyenkor switch-case szerkezetbe teszem, a számlálók és a kimeneti értékek mehetnek tömbbe. Tömb helyett bitmező is lehet a kimenet, de amennyit spórolni lehet vele, nem feltétlenül éri meg. Kivéve, ha a kimenet (pl. shift regiszter, USART) eleve bitmezőben kéri a gombok állapotát.
A hozzászólás módosítva: Feb 2, 2017
Szia!
Először meg kellene tudni, hogy a USART_RXC interruptba belép-e a program, pl. így
Ha adat érkezik a UART-on, akkor a PORTD pin7-je állapotot vált minden érkező karakternél (H->L,L->H) és ez látható lesz a LED-en. Ha ez működik, akkor a főprogramban célszerű lenne rögtön visszaküldeni, így
Ha ez is megy, akkor már sínen vagy. A soros porton érkező adatok lekezelése így nem lesz könnyű, mert ha több karakter is érkezik, amíg a főprogram éppen egy delay-ben várakozik, akkor mindig csak az utolsót fogod elkapni, ha sikerül. Ilyenkor FIFO (first input first output) adatszerkezetet kellene alkalmazni, ami lehet egy sima tömb is. (eleinte)
Ha nem is akarod használni, tanulás okán is érdemes belenézni egy bevált és jól működő lib-be.
Bővebben: Link
a dealy -ek használatához meg kell adni az órajelet. És mivel ebből fordításidőben számolódnak az értékek, ezért szigorúan a #include<util/delay.h> előtt.
Pl.:
Jelen esetben az egymásba ágyazott if() -ek használata fölöslegesen bonyolult. A switch-case szerkezetet pont arra vár, hogy egy ilyet váltsanak ki vele. Egy változó értéke alapján dől el, hogy melyik ágon (akármennyi lehet) fusson tovább a program. Jól működik ez így is, csak hát mégis elegánsabb így:
Sziasztok!
Szükségem lenne egy kis segítségre. Megépítettem ezt a netes kis hőmérőt. Kiválóan működik, de szeretnék egy másik hátteret használni e helyett a fehér helyett. Nézegettem a kódot, de ebből nem sokat értek... Azt tudom, hogy pl html-ben régen valahogy így meg lehetett oldani;
Tehát a kérdés az lenne, hogy ebbe a kódba ezt bele lehet aplikálni? Bocs mindenkitől, ha rossz helyen kérdeztem, de végül is, AVR ![]()
Ezzel én pár éve jól el voltam, amikor kicsit kontárkodni kellett egy honlapon. Az utolsó szakasz szól a háttérképről. Először notepadban a gépeden kísérletezz, és ha az biztató, akkor a main.c-ben is megpróbálhatod a kiegészítést. Bővebben: Link
Köszi a javaslatot. Kipróbáltam és azóta sikerült rájönnöm, hogy mi volt a hiba.
Az interrupt végrehajtódott, minden egyes karakter elküldése után a led állapota megváltozott. Viszont a visszaküldött karakterek között két üres sor maradt. Ha csak simán entert ütöttem, akkor meg csak egy pillanatra villant fel a led. Tehát megváltozott az állapota, aztán vissza is váltott. A baj az volt, hogy a terminálprogramban az volt beállítva, hogy a karakter után hagyjon ki egy sort. Tehát egy karakter helyett hármat küldött el: a leütött betű pl: w, új sor, és sor elejére. Enter esetén csak az utóbbi kettő. Tehát azért hagy ki két sort, mert visszaküldi a három karaktert amit az enterrel kapott, aztán még ezután rak új sort és ugrik a sor elejére amit ugye én írtam a programba. A kérdésem az, hogy hogy van ideje a mikrovezérlőnek visszaküldeni mind a három karaktert? Hiszen azok szünet nélkül követik egymást amikor megérkeznek a PC felől. Amikor egy interrupt végrehajtódik (megtörténik a kiolvasás) akkor a főprogram honnan folytatódik tovább? Onnan, ahol az if szerkezet kezdődik, vagy onnan, ahol az if szerkezeten belül abbahagyta? A probléma lényege már világos, a részleteket viszont nem igazán értem. A hozzászólás módosítva: Feb 5, 2017
Egy terminál akkor küldi el a leütött karakter kódját, amikor leütöd. A PC-s oldalon a terminálban van küldő puffer, ami nem engedi elküldeni a karaktert amíg az előző küldése tart.
Egy becsületes terminálban az "ENTER" a egy <CR> (kocsi vissza) karaktert jelent, 13-as kóddal. Ha úgy van beállítva, akkor mellé egy <LF> (soremelés) is társul 10-es kóddal. A szövegfájlokban (nem csak txt) is így van, annyi külnbséggel hogy linuxos cuccoknál az "új sor" kizárólag egy <LF> karaktert jelent. A mikrovezérlő oldalán nem kell feltétlenül fogadó puffer. Az nem gond ha egymásután jönnek a karakterek, mert 9600 baud esetén kb. 1ms van közöttük. Ennyi időd van rá hogy olvasd az UDR-t és várd a következő karaktert, esetleg elkezdd feldolgozni a kapott adatot. A hozzászólás módosítva: Feb 5, 2017
A megszakítás után oda tér vissza a program, ahol éppen tartott a program a megszakítás kiváltásának pillanatában. Pl. Van egymás után X, Y, Z utasítás a főprogramban, akkor ha Y végrehajtása után kiváltódik egy megszakítás, akkor amikor annak vége a főprogram a Z utasítással folytatja. Ezek már gépi kódú utasítások, ha egy magas szintű nyelvben programozol, pl. C, akkor annak egy utasítása több gépi kódú utasításból is állhat és így egy C nyelvű utasítás végrehajtását is félbevághatja a megszakítás.
A hozzászólás módosítva: Feb 5, 2017
Nos, ha ez egy honlap lenne, nem okozna gondot... De ezt akármennyire studírozom, nem jutok dűlőre vele :/
A hozzászólás módosítva: Feb 5, 2017
Sziasztok!
ATmega8 ADC-vel lenne egy kis problémám, rossz ADC értéket ad: 2 cellás lipo akku (max 8.4V) feszültségét szeretném mérni, az akku után van egy fesz. osztó (10K,15K értékekkel) ami a 8.4V-ból 5V-ra oszt, majd ezt az maximum 5V-os feszültséget szeretném mérni, 10 bit-es ADC-vel a PC5-ös porton, de valamiért egyfolytában 1023 értéket ad (8 bit-es módban is ugyanez a helyzet). Az Avcc rá van kötve a Vcc-re, az Aref és a gnd között van egy 100nF kondenzátor, a referenciát pedig az Avcc-ről veszi (5V).
Előre is köszönöm a segítséget! ttspeaker88
Szia!
Valószínűleg azért, mert a leosztott mérendő feszültség az AVCC felett van. Ez adódhat abból, hogy az osztót alkotó ellenállásoknak is van pontatlansága, a VCC sem biztos, hogy pontosan 5V. De próbáld megmérni műszerrel! Vagy esetleg cseréld meg a feszültség osztó két tagját és nézd meg mi történik akkor! |
Bejelentkezés
Hirdetés |