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
Szervusz!
Én javaslatom egy at90usb647 Itt van ez az ingenyesen használható LUFA nevezetű C forrású "USB driver". A LUFA rendelkezik egy pöccre működő billentyű emulációval. Annyi dolgod van, hogy megírod hozzá azt a részt, hogy beolvassa a gombokat, és elküldi az infót róla USB-n keresztül. Előnyök: az at90usb647 gyárilag bootloaderrel van szállítva, így nem kell programozó, csak lehúzod a bootloader PIN-t földre (vagy tápra ?), rákötöd a PC-re USB-vel, és belép a bootloader üzemmódba. Ekkor egy javaban futó programmal fel tudod tölteni megírt programod. Reseteled és máris a te programod fut. Továbbá hardveres USB-vel rendelkezik, a LUFA egy eléggé stabil dolog, így biztosan nem kell problémára számítani az adatátvitellel kapcsolatban. Elég lába van ennek, hogy ne kelljen nagy C trükköket bevetned, hogy beolvasd a billentyűket. Minden billentyű egy bemeneten -> pofon egyszerű. Hátrány: kicsit sűrű smd lábkiosztás, de ha hardverben otthon vagy, akkor nem lehet gond. A programot nem hiszem, hogy bárki megírja helyetted, de segíteni segítünk. Ha van egy kis beragadt C skilled, akkor az legalább le lesz porolva.
Nem tudom, hogy hogy állsz, de itt a megfejtés:
Adott az alábbi programrészlet ami egy órából származik. Magát az órát beprogramoztam ébresztővel meg mindennelm és megy is, de egyetlen probléma van: az idő.
(8MHz-es kristályyról megy az atmega 128-as.) Bemásoltam a megszakításért felelős programrészletet, csak az a gond, hogy magát a megszakítás inicializálását suliban csináltuk és úgy gondoltam, hogy értem a működését, de úgy tűnik nem. ![]() Elvileg a megszakítás 1ms-onként történik, vagyis (elméletben) ha a programban megjelelolt masodperc változót 1000-szer csökkentem 1ms-onként akkor pont 1 másodperc telik el. Ezen elméletem megdőlt, hiszen kikisérleteztem hogy 1023 és1024 között jár közel pontosan az óra. De 1023-mal is 1 óra alatt már ~1 sec-ot késik. 1024-gyel pedig már ~1s-ot vagy többet is siet. A kérdésem az lenne, hogy miként tudom beállítani pontosan?!?! ////////////////////////////////A program/////////////////// #define bs(sfr,bit) (_SFR_BYTE(sfr)|=_BV(bit)) #define bc(sfr,bit) (_SFR_BYTE(sfr)&=~_BV(bit)) u8 masodperc=1024; ... void initinterrupt() { bs(TCCR1B,WGM12); bc(TCCR1B,CS12); bc(TCCR1B,CS11); bs(TCCR1B,CS10); OCR1A=8000;//elvileg 1ms-onként van megszakítás bs(TIMSK,OCIE1A); sei(); } .... ISR (TIMER1_COMPA_vect) //////megszakításkor lefutó részlet///////// { masodperc--; ... //ha a masodperc értéke nullázódik akkor elvileg pont 1 sec telt-el } ... ////////////////////////////////////END///////////////////////// Iszonyú hálás lennék ha valaki tudna adni egy jó megoldást, amiből akár meg tudom érteni a működést is. (Bár jelenleg csak az érdekelne hogy végre pontos legyen az óra, ha már egyszer minden mást amit egy órának tudnia kell azt tudja... leszámítva a pontosságot ![]()
Az OCR1A értékét mikor töltöd fel újra, mert azt hiszem ezt minden IT-nél meg kell tenned. S a legjobb azonnal azzal kezdeni az IT rutint. Vagy az újra töltődik?
Hát erről nem tok, hogy újra kell tölteni :s. Nálam csak egyszer van feltöltve, akkor is csak az initinterrupt függvényben, amit egyszer, a main legelején hívok meg. De azért kirpóbáltam, és sajnos így sincs semmi változás.
Valószínűleg szerkesztve lett, és újra engedélyezésre vár.
Az OCR1A -t nem kell piszkálni.
Nekem az a kérdésem, hogy milyen órajel forrásod van? Amennyiben belső oszcillátor, akkor annak ennyi is a pontossága. Annyival tudod javítani, hogy leveszed belső oszcillátort 1MHz- re, akkor egy fokkal jobb lesz, egyrészt kisebb sebességen pontosabb, másrészt a gyárban eleve 1MHz-re hangolták be neked az OSCCAL regisztert.
Egészen biztosan szerkesztve lett. Volt benne pár hiba, amit mindenféleképpen kiakartam javítani. Csak nem tudom miért ülnek rajta több mint 2 napot
![]()
Sziasztok!
Kicsit megakadtam egy dologban. Szóval adott egy gsm modul és egy Atmega8. Nos szeretnék egy olyat, hogy ha hívás jön, akkor csináljon valamit a kontroller. Eddig próbálkoztam megszakítással is, de semmit nem csinált. vagyis bekapcsoltam az Rx complete interruptot, de egyszer sem jelzett, hogy bármi történt volna. Most próbáltam olyat, hogy a main-ban betettem egy végtelen ciklusban az uart olvasást, megcsörgettem a modult, de semmi, így sem reagál semmire. Hogyan lehetne ezt megoldani? Mi lenne a legegyszerűbb megoldás?
1. Ugyanarról a feszültségről működnek?
2. Jól vannak összekötve? RX->TX -re TX->RX-re 3. Jó baudrate van beállítva? 4. Biztos? Lehet rosszul vannak beállítva a fuse-ok... Ha a PC-vel kötöd össze az AVR-ed, (max232 szintillesztővel pl) akkor megkapod az adatokat?
A kommunikáció működik, mert küldözgettem már parancsokat a gsm modulnak, amit az végre is hajtott és a kapott értékeket lcd-n meg is jelenítettem. Csak ez nem akar menni sehogy. Amikor csörgetem a modult, akkor pár másodpercenként ad ki a soros porton egy "RING" szócskát. Ezt kellene érzékelnem.
Hát, hogyha más adatokat képes vagy fogadni tőle, csak a bizonyos RING szó nem jön, akkor szerintem az nem is jön. Nem kell azt külön beállítani?
PC-re kötve a modult, adja a RING szót.
Köszi, de sajnos nekem ez egyenlőre semmit nem mond. Szeretném , ha menne a programozó, és azután tudnám a különböző programokon megtanulni a működését a mikrovezérlőknek. Viszont nem találtam sehol a beállításokat. Az előző hozzászólásomban csatolt képen berajzolva sokat segítene, ha kérhetném.
![]()
Oksika. Bár ez éppen nem az amit fentebb leírtam(D9:FF), hanem a lehető legbiztonságosabb beállítás.
Azaz: 2.7V alatt nem indul be(vagy kikapcsol), és erősíti az órajelet(de kb. 5mA-rel a fogyasztás is megnő).
Hello!
Egyik lelkes kolléga GSM-es paneljét is én raktam össze úgy, hogy kezdetben hülye voltam az egész témához. Most nem írom le a tortúrát, de az az érzésem hogy valamit kifelejtettél: engdélyezni az AT portot. Úgy emlékszem hogy a modul egészen addig nem küldött semmit, amíg nem kapott AT parancsot. Egy "AT\n" is megteszi(65,84,10 karakterkódok), innentől kezdve adni fogja. ![]() Már meg se kérdem hogy az USART beállítások jók-e, azaz 9600kbps/8bit/1stop/nincsparitás... Felhúzó ellenállás sem árt az Rx vonalra, de az AVR belső 47kOhm - os felhúzója is megteszi. Ha nem vagy biztos magadban akkor az AVR-t kösd a PC-re, és úgy adjál neki/fogadj adatot! Egy sima ECHO is megteszi, vagy az hogy a küldött karakterkódhoz hozzáad 1-et és azt küldi vissza...
Sziasztok.
Led sorokat akarok PWM vezérelni, de csak egy PWM kimenetem maradt, viszont sima I/O láb van még bőven. Feteket használok a vezérléshez, szerintetek így működhet ? ( Kép ) Az alsó FET csak az "engedélyező" lenne, azon állítanám a kitöltési tényezőt, a többi meg a csatornákat kapcsolgatná. Köszi
Hello!
A kapcsolás attól függ hogy a LED-sorok mekkora áramot vesznek fel, ugyanis ebben az open-drain kapcsolásban a GATE feszültség maximum az AVR tápfeszültsége, egy tiszteséges FET esetében ez max. 0.5-0.8A áramot jelent. Az fölött a feszültségesés már jelentősebb(0.5-1.5V), kisfeszültségű(5-12V) a LED-sornál ez már számottevő. A lehúzó ellenállások(R5-R8) elég nagyok lehetnek(~100kOhm), tényleg csak arra kellenek hogy az AVR inicializálása közben a GATE feszültség ne kússzon fel a kóboráramokkal. Amikor az AVR megy, az R1-R3 ellenálláson és az AVR-en keresztül a GATE is kisül ha kicsi az értékük. Ezeket én el is hagynám; persze a FET leégésekor egy kis védelmet már nyújthatnak ~1-2.2kOhm értéken. Ezt leszámítva nem igazán értem mi a para egy szoftveres PWM-en. Az én Knight Rider vezérlőm 18 csatornás LED-sorokat futtat ilyen módon, és közben már kiszámolja a következő ütemet is. Igaz, a program - különösen az időzítő interrupt és a szinkronizáló algoritmus - nem 12 soros...
Sziasztok!
32bites AVR mikroprocesszorral dolgozom, és azt szeretném megvalósítani, hogy a PWM-el vezérelt motoromnál kérek egy megszakítást a PWM időzítőjével. A programnak ezt a részét összegyűjtöttem (kép). A megszakítást ez a parancs kéri: INTC_register_interrupt(&pwm_interrupt,AVR32_PWM_IRQ, AVR32_INTC_INT0); Ez valószínűleg meg is valósul, mert debug üzemmódba megnéztem, viszont utánna ennél a sornál áll végig és nem megy sehova: isr=AVR32_PWM.ISR; Ezzel a parancssal gondoltam kiolvasni a regisztert, amely egyúttal törli is azt. Véleményem szerint ez nem valósul meg. Valakinek van ötlete, hogy miért, vagy mi lehet a probléma? A parancs lenne rosszul megírva amivel olvasnám? Üdv.:Gergő Idézet: „Teljesen félreértitek. Aztán mi a lócitromot csinál a shift regiszterekkel?” Olvasd el, oda volt írva: a portlábakat bővíti. És lepődj meg: Attól, hogy USB-s a cucc, még továbbra is tudja ezt az SPI-s portbővítést használni. Meglep, ugye? ![]()
Az illető írta hogy a hardver részében otthon van, így szerintem fölösleges volt a shiftregisztereket említeni.
Valószínű hogy az USB rész megvalósításában nagyobb segítségre lett volna szüksége, ennyi.
Most vettem észre, hogy van egy sor:
AVR32_PWM.IER.chid0=1; Ahol engedélyezem az interruptot. Ez a sor, ha már benne van, de azon kívül egyetlen egyéb szöveg nincs hozzá már megállítja a működést. Utóbbi esetben nem tudom hol áll.
Az alábbi oldalon van egy USB firmware. Ez kb 4 kbyte-ot eszik a program memóriából és 2 port kell: D- és D+ USB vonalra. Mivel az USB 3,3V-on működik, ezért ellenállás zéner párossal a legegyszerűbb csatlakoztatni az AVR-t. Egyetlen megkötés, hogy a D+ vonalnak megszakításos port-nak kell lennie (pl.: INT0).
A minták között van egy HID billentyűzet is. (HID előnye, hogy nem kell driver-t telepíteni a PC operációs rendszerének fel kell ismernie.) Ha megnézed a billentyűzet forrását, akkor az usbSetInterrupt(reportBuffer,2); állítja be, hogy épp melyik billentyű scan kódját küldje el a reportBuffer-ből a PC felé. Problémával amivel én találkoztam: - Windows alatt az USB_CFG_DEVICE_NAME csak 'HIDKeys' lehet (Linux alatt mindegy mi) - Windows alatt néha lefagy az USB ennek okára sajnos nem sikerült rájönni (Linux alatt nem tapasztaltam ilyet) A lefagyás ellen az lehet a megoldás, ha 3 port-ot használsz fel a 'D-' lábat egy 2k2 ellánáláson kötöd egy 3 portra, amit az usbconfig.h-ban USB_CFG_PULLUP_* alatt kell megadni. Ha "sokáig" nem ad igazat a usbInterruptIsReady() függvény, akkor ezzel a lábbal emulálni lehet az USB eszköz ki-be húzását és a Windows újra fel fogja ismerni és ismét működőképes lesz. A PC oprendszere rendszeresen poll-ozza az USB portot (rendszeres időközönként lekérdezi), ehhez képest kell érteni a "sokáig" jelzőt.
Még egy megjegyzés: én elképzelhetőnek tartom, hogy a normál billentyűk mátrix-ba vannak kötve a módosító billentyűk (pl.: Shift, Alt, Ctrl) pedig dedikált portra. Így egyszerre nem lehet pl. az 'a' és 'b' megnyomni, de a 'Shift' és az 'a' még működik. Feltéve persze, ha ez a kompromisszum elfogadható.
Annyi gombot nyomsz le amennyit tudsz
![]()
Köszönöm!
Ha holnap egy asztali géphez jutok, meg is csinálom!
Hello!
Lényegében én is ilyenre gondoltam, a forrást már 2 éve ismerem, csak nem akartam hülyeséget írni. ![]() Nekem az a konkrét bajom hogy AVR Studio-ból ezeket az obdev-es cuccokat nem tudom fordítani. A Doper példáján már említette valaki hogy a forrást nem WinAVR alá írták, de könyörgöm! Valaki tudna segíteni, hogy mégis miket kell importálni és átírni, vagy esetleg telepíteni? |
Bejelentkezés
Hirdetés |