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
Az égetőhöz való csatlakozáskor ez a kép fogad és nem csatlakozik az eszközhöz.
Bővebben: Link
Ez azt jelenti, hogy nem megy. Nem sikerült belépnie programozó módba.
Új IC, vagy HVPP kell.
ATMega8-16 (16 MHz, 5V)
Mega8L-8 (8MHz, 3V-on tesztelt, de 5Von 16MHz megy) Mega8A (8 és 16 MHz-s chipet egyesíti, kisebb csíkszélesség, azonos a 2 chip). Az eltérés pár helyen van: - belső ellenállások 20k-> 80...120k - resetellenállás 20k -> 82k - a Vcc és VccA közti belső ellenállás kikerült. Azaz be kell kötni a Vcc és a VccA lábat is, hogy a GND és a GNDA-t is Bővebben: Link - A vagy Nem A A hozzászólás módosítva: Márc 12, 2015
Ez a kép nem azt mutatja, hogy a SPIEN kivan kapcsolva, hanem hogy nem tudtad kiolvasni a fuse biteket. Szóval nem tudhatod, hogy ki van e kapcsolva. Ha rádobsz egy külső kristályt ÍGY és úgy sem tudsz kapcsolódni akkor valszeg kikapcsoltad a SPIENT. A két kondi 22pF-os a kristály meg pár MHz (mondjuk 4).
Sziasztok!
Szeretnék készíteni egy várakozó függvényt, ami úgy működik, hogy pl. szeretnék 100mS-ot várakozni, ilyenkor közbejöhet akár több interrupt is, a lényeg, hogy a 100mS 100mS legyen, ne pedig 100mS+interrupt hossza. Beállítottam az egyik timer-t, ami 1024uS-ként növel egy long változót, tehát majdnem 1mS-ként. Kezdetnek ez is megteszi, később lehet finomítani a pontosságot. Ez az Arduino-s millis() függvény egyszerűsített változata. Működik is, viszont néha rövidebb időt várakozik. 1000mS-nál a soros porton 1000-et küld vissza a főprogram általában, de kb. 15-ből 1x kisebb értéket kapok, 890-950-975 körülit. Nagyobbat soha. Ez a várakozó függvényem:
A főprogramban:
Ha a normál _delay_ms(1000) függvényt használom, akkor mindig megfelelő az időzítés, viszont az interrupttal megnövelt értéket kapom vissza. 1035-1036-ot, amikor minden interrupt működik, és ha csak a millis()-t kiszolgáló megy, akkor 1031, ami 4ms eltérés. Nem sok, de ezt is szeretném kiküszöbölni. Mit gondoltok, mitől lehet ez a rövidebb várakozás? Én ezt a részt érzem hibásnak: "while (millis()<kezdeti_ido)" Ha igaz, hogy lehetne javítani? Köszönöm! szerk: Tettem egy gyors próbát, így jónak tűnik:
A hozzászólás módosítva: Márc 12, 2015
Szia!
Nem ertek valamit. Miert kell letiltani a megszakitast a "kezdeti_ido = millis();" miatt? Ha a millis() nem igazi fuggveny, hanem egy makro, ami csak egy valtozot ad vissza, akkor a while()-ban is le kellene tiltani a megszakitast. Ha a millis() egy valodi fuggveny, akkor meg nem kell tiltani. Felteve, hogy a millis() fuggveny vigyaz arra, hogy ne tudjuon rossz erteket visszaadni. Azt a fuggvenyt lehetne latni?
Szia.
A millis() kb. ennyi: void millis() {return millis_;}, ez unsigned long, a millis_ pedig az interruptban van növelve, 1mS-ként. Mostanában olvasgattam, hogy okozhat gondot 8bit-es AVR-en egy 32bit-es változó átvétele, ha közben az interrupt azt változtatni tudja, mert két részben történik a változó kezelése. A kódot, amit utoljára hozzáadtam még, ha megnézed, ott már nincs cli() és sei(). Ez a kód így jól működik, mert ha falsch értéket kapok a millis()-től, akkor harmadjára is megtörténik az értékadás, ami már 100%-osan jó lesz. Próbálkoztam ugyanezt megoldani uS-ra, ez még kicsit problematikusabb, dolgozni kell rajta... A problémáról itt találsz további infókat: Bővebben: Link. Volt korábban is hasonló probléma egy változóval ebben a topicban. A hozzászólás módosítva: Márc 13, 2015
A problemadra a kovetkezo az egyik megoldas:
De, ha nem akarod letiltani az interrupt-ot minden egyes lekerdezesnel, akkor csinalhatsz egy olyan timer interrupt-ot, ami a kert ido elteltevel beallit egy flag-et, es azt kell csak figyelned. Azt viszont figyelheted engedelyezett megszakitas mellett is.
Fölöslegesen az interruptot ne kapcsold le. Csak akkor kell, ha tényleg nem tudsz mást csinálni. Bevallom Arduino alatt állandóan agybajt kapok attól, hogy TIMER0 mindenbe bekavar.
Kinek a pap, kinek a papné. Errol mar beszeltunk itt par oldallal ezelott. En inkabb tiltom 5 utasitasnyi idore az IT-t, mint hasznaljak 8 byte stack-et, egy kazal kodot es meg lassitsak is a programon a 32 bites hasonlitgatassal. Ha egy rendszerben gondot okoz egy ilyen rovid ideju IT tiltas, akkor a te modszered jo, de amugy nem latom ertelmet.
A hozzászólás módosítva: Márc 13, 2015
Mindkettőtöknek igaza van! Csabeszq kódja tetszik, köszi. Az ok, amiért nem lehet az interruptot kikapcsolni: LED-mátrix van multiplexálva interruptból. Ha megáll az interrupt, bevillan a kép, megáll egy pillanatra. Ha a LED-ek nem 20mA-rel vannak hajtva, hanem 100mA-rel (mivel úgy is csak 1/8-ad ideig van bekapcsolva), akkor egy interrupt tiltás egyben a LED-ek végét is jelenti!
Egyik órámban a fényerősség is interrupttal van szabályozva, ha kikapcsolom az interruptot, akkor felvillannak a LED-ek maximális fényerővel, mert be még bekapcsolódnak, de ki már nem, vagy nem akkor, amikor kellene. És minél később vannak kikapcsolva, annál nagyobb a fényerő. Ezek az okok. Ez miatt kell megoldanom pl. a DS18b20 hőmérő szenzorral a kommunikációt is interrupt kikapcsolása nélkül. Az I2C egyáltalán nem kavar be, ott megvárom szép türelmesen, amíg beáll a megfelelő flag. A főprogram lehet lassú, az interrupt sajnos nem.
Ez nagyon szimpatikus: " csinalhatsz egy olyan timer interrupt-ot, ami a kert ido elteltevel beallit egy flag-et, es azt kell csak figyelned", átgondolom hogyan lehetne megoldani szépen. Abból állna a delay függvény, hogy lenullázná a számlálót, és beállítaná az OCR értékét a megfelelő értékre. Ezután az interrupt beállítja a flag-et, és lenullázza a számlálót, meg kikapcsolja a megszakítását. A várakozó függvény vár, amíg a flag be nem lesz állítva, amikor ez megtörténik, egyből meg is vizsgálhatja, hogy a számláló azóta hol tart. Ugyanis ha egy másik interrupt miatt a várakozó függvény túl sokáig volt várakoztatva, akkor az eltelt idő több, mint ami kell. Ilyenkor újra kell kezdeni a kommunikációt, remélve, hogy most nem lesz pont rosszkor félbeszakítva. Esetleg a másik megszakításból lehetne figyelni az időzítő interruptot
![]()
5 utasitas idore az interruptot egesz nyugodtan le lehet tiltani, nem fog latszani a LED-en. Persze, ha ciklikusan hivogatod azt a fuggvenyt, ami letiltja, akkor igen. De normalisan ez teljesen elfogadott dolog, hogy par utasitasnyi idore letiltjuk a megszakitast. Amikor egy megszakitasi rutin fut, akkor az sokkal hosszabb idore tiltja. Igaz, ez csak akkor erdekes, ha tobb is van.
Egy interrupt van, aminek mindig mennie kell, ez küldi az adatot a portoknak és a shift regisztereknek. 5 utasításidő valóban nem sok. A gond ott van, hogy így kommunikál a DS18b20: cli(); delay-us(48); sei();, na ez már bőven látszik.
A hozzászólás módosítva: Márc 14, 2015
Idézet: Ha felted a LED-eket, akkor megfelelo HW-rel meg kell vedeni oket. Pl. egy idozito (555 vagy akarmi), ami ha lejar, akkor lekapcsolja az egesz LED tapot, vagy hasonlo. Az idozitot meg valami olyan jel triggereli, ami a kijelzo meghajtasbol szarmazik. Ez eleg regi modszer a SW-es LED matrixok vedelmere. A SW-ed barmi mastol is megallhat, es akkor ugyanugy kinyirja a LED-eket, ha nincs hardware-es vedelem. „Ha a LED-ek nem 20mA-rel vannak hajtva, hanem 100mA-rel (mivel úgy is csak 1/8-ad ideig van bekapcsolva), akkor egy interrupt tiltás egyben a LED-ek végét is jelenti!” Idézet: Ez a DS18B20 egy problemas dolog, mert se nem gyors, se nem lassu. Ahhoz tul gyors, hogy egy jofele interrupt rutin elkezelje egy AVR-en (bar lehet, hogy lenne ertelme elgondolkodni rajta), viszont ahhoz lassu, hogy le lehessen tiltani a megszakitast egy bit idore. „A gond ott van, hogy így kommunikál a DS18b20: cli(); delay-us(48); sei();, na ez már bőven látszik.”
Mesélhetek még nyalánkságokat.
Például, hogy úgy kezded a hosszú interruptot, hogy kikapcsolod az IE flag-et, nehogy rekurzív legyen, utána sei(). Interruptból lehet másik interruptot meghívni. Amikor jöttek befelé az SPI parancsok miközben software PWM-et futtattam, akkor volt erre szükségem. Se az SPI, se a PWM nem várt. Az történt, hogy mentek az interruptok és ha SPI parancs érkezett be, akkor elindított egy szálat a főprogram helyett, ami mindaddig futott, amíg a bejövő SPI parancsok le nem lettek kezelve. Utána visszaadta a vezérlést a főprogramnak. Eközben ment a software PWM. Ha éppen egy új SPI interrupt jött be, azt pufferbe raktam. Addig dolgoztam fel az SPI-t, ameddig volt még parancs, utána visszaadtam a vezérlést a főprogramnak. A hozzászólás módosítva: Márc 14, 2015
A 48us meglátszik a kijelzésen?
Milyen frekvenciával váltod a sorokat? Nálam 800Hz-es timer küldi az adatot ki, tehát egy sorra 10ms jut, ilyenkor a 48us nekem nem tűnik kritikusnak.
Bocs, 1,25ms jut egy sorra.
Üdv!
Van egy Atmega 328p xplained mini fejlesztői kártyám , és egy lcd-s ébresztőórát akarok csinálni ds1307 rtc áramkörrel.Kezdő vagyok még , és az i2c kommunikációt próbálom megoldani a mikrokontroller és az rtc között , de a programom mindig megakad egy bizonyos részen.Ezt a példaprogramot néztem ki: Bővebben: Link Ebben a függvényben akad el mindig a while ciklusnál:
Szia esetleg próbáld ki ezzel, nekem bevállt. Ez egy példaprogram az RTC beolvasására, az adatok feldolgozása nincs benne.
Felhúzóellenállásokat ne felejtsd el!
A hozzászólás módosítva: Márc 14, 2015
Ennél is valamiért ugyanott , amikor először belép a for ciklusba a főprogramban akkor meg akad.Felhúzó ellenállások vannak , és az áramkörnek jónak kéne lennie , mert arduinoval kipróbáltam , és ott kitudtam olvasni az rtc-ből az időt.
Na sikerült megoldani a problémát!A fejlesztői panelen egyel elcsúsztam és nem az 5V tápfeszt adtam az ic-nek . hanem a 3,3 V-ot.
Szia. Nem csak csak 1x 48uS, hanem sokkal többször. 1bithez kell ennyi idő, én is küldök utasításokat, DS is küld vissza. Egy DuoLED-es matrixomnál 3x250uS-ig világít egy sor, amikor 3xtúlcsordul a timer, jön a következő sor, összesen 8. Azért 3x255uS, mert így 3+1 féle színárnyalatom van (kikapcsolva, halvány, közepes, max), így tudok színeket kikeverni. Ehhez jön hozzá a fényerőszabályzás, amit pedig az OCR szabályoz. Ha OCR 10, akkor 0-10ig világít a sor, 10-255ig nem, tehát sötét lesz az a sor.
Esetleg egy másik időzítőt használhatnál az 1-Wire kezelésére, ami meg is szakíthatja a mátrixot kezelő interruptot. Ezt azért lehet megcsinálni mert a mátrixoknál az interrupt legelején megcsinálod az "átkapcsolást" a következő sorra vagy színárnyalatra, a többi részében meg a számításokat végzed el, és ha shift regisztered(74HC595) van akkor kiküldöd de nem csinálsz STORE-t (azt majd a következő megszakítás legelején). Tehát ezen interrupt LEGELEJÉN megcsinálod az átkapcsolást, ami kb. annyit tesz egy 8MHz-es IC esetében hogy kb. 1-1.5 us alatt megvan a dolog. Ezután (és csak ezután!) beraksz egy "sei"-t hogy a "számolós-kiküldős" részt az 1-Wire időzítő lejárta bármikor meg tudja szakítani.
Bármilyen hihetetlen, de az 1-Wire időzítőjének megszakítását is csinálhatod ugyanígy: az időzítéskritikus részeket(port beolvasás, port átbillentés) a megszakítás legelső néhány utasítására teszed, majd kiadsz egy "sei"-t hogy az 1-Wire számolós-shiftelgetős részeit a mátrix meg tudja szakítani, hiszen sort/árnyalatot kell váltania. Azért a mátrixod nem annyira ördöngős hogy 5-10us-nél tovább tartson a következő sor konverziója. Persze nem Arduino-ban...
Igazából azt olvastam ki a DS18B20 adatlapjából, hogy egy "time slot"-ot el lehet nyújtani, tehát nem kell feltétlenül 60us-nek lennie, akár 255us is lehet mivel minden bit átvitelét a master kezdeményezi. Persze ha a DS tolerálja a többszörösére nyújtott timeslot-ot.
Ekkor a kezelés a következő: a mátrix megszakításában egy flag-et beállítasz, amit a főprogramban figyelsz. Utóbbi törli a flag-et és belefog a következő timeslot kezelésébe. Mivel éppen le lett kezelve a legutóbbi megszakítás a mátrixon, a következő 60us-ban biztosan nem fog jönni egy újabb hogy elrontsa a delay függvényt. Innentől tiszta sor. Mondani persze könnyű. Én úgy próbálnám ki hogy fogok valami "semleges" áramkört, az egyes timeslotok közé teszek valami hosszabb várakozást a delay függvénnyel és megnézem mi az eredmény. A DS adatlapja szerint elvileg végtelen is lehet ez a várakozás... A hozzászólás módosítva: Márc 14, 2015
Köszi a tippeket! Ezt még meg kell emésztenem... Most már legalább van többféle irány, csak ki kell választani, hogy melyik lenne a legjobb megoldás.
Sziasztok! Tegnap próbáltam ki először avr programozóm (kezdő vagyok még, ezért kérem a segítségetek). USBasp-t használok, atmel studio 6.2-ben. Atmega8-as processzort használok, sikerült rátölteni a programot, teszteltem is, működik. A probléma viszont az, hogy én 16Mhz-en akarom üzemeltetni, de a processzor 1Mhzen jár. A cikkek közt találtam egy bekezdést, hogy másnak is volt már ez problémája, hogy elvileg a CLKDIV8 fuse leosztja az órajelet 1Mhz-re. Tudnátok segíteni, hogyan állíthatom át, hogy 16Mhzen működjön? Előre is nagyon köszönöm a segítséget.
|
Bejelentkezés
Hirdetés |