Fórum témák

» Több friss téma
Fórum » AVR - Miértek hogyanok
 
Témaindító: pakibec, idő: Márc 11, 2006
Témakörök:
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   697 / 840
(#) pont válasza Zsolt2 hozzászólására (») Okt 2, 2015 /
 
Egészen biztos, hogy akadálya nincsen, mert a PLC-ben is "csak" mikrovezérlő van, csak én még nem tudom megcsinálni, de majd beleásom magam, köszönöm a tippeket.
(#) Sipy hozzászólása Okt 3, 2015 /
 
Na csak sikerült működésre bírni, leírom hátha más is így jár. A bascom program volt rossz, újra akartam telepíteni de nem lehetett eltávolítani sem. Azt írta angolul hogy korrupt a telepítő fájl úgyhogy a windowst is újra kellett telepitenem. utána is ugyanúgy jártam úgyhogy megint windows telepítés, emiatt a vírust kizártnak tartom. Letöltöttem egy korábbi bascom verziót és pöcc-röff minden beindult normálisan. Köszönöm mindenkinek aki próbált segíteni. Ha a problémát nem is sikerült rögtön megoldani mégis tanultam új dolgokat.
(#) Max26 hozzászólása Okt 4, 2015 /
 
Sziasztok!

Lenne egy komplex feladat, aminek a megoldását még ha a fejem tetejére állok sem sikerül megtalálnom.
Mérésadatgyűjtésről lenne szó SD kártyára vagy UART-on át PC felé.
A feladat az alábbi libraryket tartalmazza:
- 4x4 keypad
- uart
- sd kártyaolvasó
- 2x16 LCD
- BMP180 barotmetrikus szenzor
- DHT11 páratartalom mérő szenzor

Tapasztalatom az, hogy a program néhány óra elteltével megáll' a kijelző nem frissül. Legelőször kontakthibára gondoltam. Mivel az áramkör már egyoldalas NYÁKon és nem breadboardon van úgy gondolom erről nem lehet szó. Az egyetlenegy összefüggés, amire rájöttem: a hiba csak akkor lép fel, ha használom a DHT11 páratartalom érzékelő könyvtárat.

A könyvtár számomra hibátlannak tűnik, mert áttanulmányoztam a szenzor adatlapját. Eszerint jó időzítésekkel van elkészítve ez a könyvtár: Bővebben: Link

Nem a dht11.c -ben kellene keresnem a hibát?
(#) Csirkefej hozzászólása Okt 4, 2015 /
 
Csak futólag néztem rá a programra, de ami elsőre feltűnt és elakadást okozhat a dht11.c 57. és 61. soraiban a timeout nélküli while ciklus.

Magáról az eszközről, amit használsz fogalmam sincs, csak mint programot vizsgáltam.

Első lépésnek ezt a két sort írnám át úgy, hogy legyen egy timeoutja aminek leteltével (unikum) hibakóddal tér vissza. Ha jól látom, akkor ez a hibakód meg fog jelenni a kijelzőn vagy hol -ha tényleg ebben az ágban akad el. Akkor látnod kell majd saját hibakódodat.
(#) Kovidivi válasza Max26 hozzászólására (») Okt 4, 2015 /
 
A DHT-11 szenzor nálam is ezt csinálta, nem válaszol néha, össze-vissza adatokat küld, ha olyan kedve van, a szolgáltatott érték pedig megbízhatatlan, 5 percen belül több értéket küld vissza 45-60% között. Próbáld ki a nagytestvérét, DHT-22, vagy másik szenzort, hátha az már jól működik.
A lib-et nálam is módosítani kellett. Sőt, ha nincs csatlakoztatva a szenzor, teljesen megáll a program, míg pl. DS18b20-nál szenzor nélkül is megy a program, csak a hőmérséklet 0 marad.
Ennyit számít, hogy egy lib rendesen van-e megírva. Ezt is ki kell javítani, ha elromlana a DHT, azért még a hőmérsékletet logolni tudja. Plusz a DHT-n szerintem egy NTC vagy PTC méri a hőmérsékletet, a pontossága nem valami sok.
A hozzászólás módosítva: Okt 4, 2015
(#) Csirkefej válasza Kovidivi hozzászólására (») Okt 4, 2015 /
 
Idézet:
„Sőt, ha nincs csatlakoztatva a szenzor, teljesen megáll”


Ez alátámasztani látszik a gyanúm.
Abban a két sorban a while ciklus végtelen ideig vár. Először high(57. sor) majd utána low(61. sor) input állapotra. Tehát ha nem vált állapotot az input megfelelő bitje akkor ott pörög a végtelenségig a program(a kijelzést sem kezeli ezért). Abszolút programozói hiba.

Be kellene tenni egy számlálót és egy késleltetést mindkét while ágba. Ha a számláló lejár, akkor visszatérhet hibakóddal.

Esetleg még tovább finomítani, hogy ez a hiba ha beáll akkor x időre zárja ki a telhjes funkciót, hogy ne terhelje időben a további eszközök kezelését.
A hozzászólás módosítva: Okt 4, 2015
(#) edison14 válasza Max26 hozzászólására (») Okt 4, 2015 /
 
Szia!

Én mondjuk ajánlani tudnám a Sensiron által gyártott SHT2X-es szenzort ami I2C-n kommunikál és méri a páratartalmat is és a hőmérsékletet is. Most is egy ilyennel dolgozom és nagyon pontosan és gyorsan tud mérni. Kínai barátainknál olcsón kapható egy kis nyákra forrasztva felhúzóellenállásokkal együtt. Már csak összekötöd és programozol.
(#) cimopata hozzászólása Okt 4, 2015 /
 
Sziasztok.

Szintaktikailag ezt hogy értelmezzem:

TCCR0A = 2<<COM0A0 | 2<<COM0B0 | 3<<WGM00;

Ez ugyan az mintha a regisztert így állítanám be:

TCCR0A = 0xA3;

ATMEGA324-ről van szó

köszi
(#) Kovidivi válasza cimopata hozzászólására (») Okt 4, 2015 /
 
Amit az arduinos topicba írtam nem segített semmit? Ennél már nem is nagyon lehet bővebben kifejteni.
(#) Droot válasza Max26 hozzászólására (») Okt 4, 2015 /
 
Ennek a fickónak a programjaiban az az érdekes, hogy elég sokat írt, de egyik se működik rendesen. Keress másik library-t.
(#) Csirkefej válasza cimopata hozzászólására (») Okt 4, 2015 /
 
Szintaktikailag mi a baj vele?

Egyébként ha pl COMxxx és WGM00 (ha feltételezem) a programban valahol egyetlen helyen definiált konstans és te TCCR0A-nak közvetlen értéket adsz, mint ahogy írtad (A3) akkor egy esetleges program módosításkor a programban meg kell keresned az összes TCCR0A-nak értéket adó sort és mindegyikben átírni A3-ra.
És ha következetesen a többi váltózónál is így adtál értéket akkor folytathatod pl a TBBZ7B változók keresés/cseréjével...és így tovább minden változóval.

Nem könnyebb a program elején például egy #define sorban egyetlen egyszer átírni?

+a konstansok neveinek helyes megválasztásával egy-egy ilyen sor szinte beszél. Azonnal át lehet látni, hogy milyen biteket állítasz be rajta például, míg egy hexadecimális számra ránézve még át kell fejben konvertálni bitekre majd a biteket azonosítani például egy port in/out pinjeivel.

Két példa volt a sok lehetségesből.
(#) cimopata válasza Csirkefej hozzászólására (») Okt 4, 2015 /
 
Értem.

Igazából azon fáradozok, hogy összehozzak egy teljes hidas PWM vezérlést motohoz és ahhoz kell fix freki de mind a 4 kitöltést külön-külön variálni. Az alap adott frekik nem jók mert 7,92kHz az hallható 64kHz meg túl magas és az osztó nem enged köztest.
Tényleg még csak az alapokat olvasgatom elsőnek arra gondoltam hogy a két 8 bites timerrel csinálni külön külön beállítani hogy kb 20kHz-en menjenek, de ahogy olvasgatom így nem nagyon fogom tudni állítani a kitöltést?

Kérdésem hogy az járható út lenne-e, hogy a 16 bites timerrel beállítom ICR1x regiszterrel hogy ne 65535-ig hanem kb 100-ig fusson a számláló és akkor ez kiadna kb 20Khz frekit. Ezután a TCNT1xL regisztert ami tárolja a számlálót ugye másolnám a TCNT0-ba. És így fázisban is lenne a két félhíd és meglenne mindenhol a 20kHz?

Azért kérdezem hogy járható út e mert tényleg még csak most nézegetem egyáltalán hogy kéne nekiálljak. Analóg hajtásszabályozást kenem vágom de a procikkal csak most ismerkedem.

Köszi a választ.
(#) Csirkefej válasza cimopata hozzászólására (») Okt 4, 2015 /
 
Sajnos én még azt sem biztos hogy tudmom, hogy mi az az AVR.

Csak azért tévedtem ide, mert a topiknyitó kérdés egy teljesen másik témában lett megnyitva kifejezetten "szoftveres" címmel csak valami admin megjegyzés nélkül átbuherálta ebbe a fórumcsoportba.
Ha már az elején itt nyitotta volna a kérdező, eszembe sem jutott volna belenézni.
(Jobb volt úgy, ahogy volt. Ez szoftveres probléma -függetlenül attól, hogy épp AVR is van benne)

Szóval - az utolsó kérdésedre reméljük majdcsak válaszol valaki.
(#) Sick-Bastard válasza cimopata hozzászólására (») Okt 5, 2015 /
 
Neked a Fast-PWM Mode kell.
adatlap 105. oldalon 12-8 tábla Mode 3.

16Mhz-es órajelet feltételezve használd az 1024-es osztást így meg is van a ~16Khz-es PWM frekvencia amit keresel.
  1. TCCR0B |= (1<<CS02) | (1<<CS00); // osztás 1024


Az OCRxA regiszterbe meg beleírod az értéket, hogy hány %-os jelet is kívánsz.
  1. pl.:
  2. OCRxA = 0; // 0%
  3. OCRxA = 25; // ~10%
  4. OCRxA = 128; // ~50%
  5. OCRxA = 255; // 100%
(#) cimopata válasza Sick-Bastard hozzászólására (») Okt 5, 2015 /
 
A PWM freki az adatlap szerint fpwm=fclock/(N*256)

99 oldal alja. 16kHz-et nem tudtam így összehozni mert ott van még a 256 osztó is.
(#) Max26 hozzászólása Okt 5, 2015 /
 
Igen, a hiba a dht11.c -ben van. Azt szeretném, hogy a kód ne menjen vissza alaphelyzetbe ha van hiba a DHT11 kommunikácóban, mert menüpontban kellene a páratartalom mérést megvalósítanom. Így az eredeti könyvtár szerint ha hiba lép fel a kommunikációban, akkor újra vissza kéne navigálnom a menübe.
A libraryt restart: cimkével egészítettem ki és goto-t használtam. Kérdéses, hogy jó ez így, létezik-e elegánsabb megoldás?

http://pastebin.com/y5XsGR4C
(#) Csirkefej válasza Max26 hozzászólására (») Okt 5, 2015 /
 
Első ránézésre én hiányolok egy delay-t a while cikluson belül mert így idozites++ a maximális programvégrehajtási sebességgel pörget felfelé.

Igen szerintem létezik "elegánsabb". Kicsit el lehet veszni a leismételt két ciklus késleltető ágában.
Nomeg az idozites==200-nál a 200-at is vagy egy darab konstansba vagy változóba tenném a jobb átláthatóság és biztonságosabb esetleges késleltetési idő változtatás miatt.

(Azt megint leírom, hogy én csak mint C programot nézem - az AVR-t sosem használtam (Max mint AutomaticVoltage Regulatort...haha))
(#) Droot válasza Csirkefej hozzászólására (») Okt 5, 2015 /
 
Én szinte minden programomba csinálok egy 1ms-os időzítést, ami a legtöbb esetben el tud látni mindent.
A helyedben én így csinálnám. A Timer-ben egy uint8_t változót növelnék, ha kisebb, mint 254. Mielőtt a dht-ben belefutna a while-ba, a változó értékét 0-zni kell. A while feltételben pedig OR-olni, hogy valtozo <=254, majd amikor a while-ból kilép megvizsglod, hogy, ha a valtozo == 255, akkor timeout-ba futott, ha nem, akkor van rendes mérési eredmény.
De pontosítok, én a helyedben egy másik library-t használnék, mint már ajánlottam.
(#) killbill válasza Droot hozzászólására (») Okt 5, 2015 /
 
Szerintem ezt nem jó helyre címezted...
(#) Droot válasza killbill hozzászólására (») Okt 5, 2015 /
 
Tényleg benéztem, Max26-nak ment.
(#) AxaGame hozzászólása Okt 11, 2015 /
 
Sziasztok!
Tesztre telepítettem az Atmel Studio 7 programot, majd egy 6.2 alatt működő egyszerű projektet nyitottam meg. A fordító tette a dolgát, de a debug rész gyakorlatilag hibával leállt, vagy el sem indult.
(13:42:35: [ERROR] Failed to launch. Error code 89710015)
Van valakinek valamilyen tapasztalata?
(#) rolandgw válasza AxaGame hozzászólására (») Okt 11, 2015 /
 
Release note-ban le van írva: frissítsd az intel vga drivert a gépeden.
(#) Kovidivi hozzászólása Okt 11, 2015 /
 
Sziasztok!
Van 4 db LED-em, PWM-el tudom őket szabályozni. Hogyan tudom azt leprogramozni, hogy egyik irányból a másikba haladva, a sorban lenne egy "sötétebb" folt, ami vándorol?
Ha leírom számokkal, akkor kb. ilyen (0-10-ig, de a pwm 0-255-ig mehet):
10 8 6 4
8 6 4 2
6 4 2 0
4 2 0 2
2 0 2 4
0 2 4 6
2 4 6 8
4 6 8 10
6 8 10 8
...
Köszönöm.
A hozzászólás módosítva: Okt 11, 2015
(#) Massawa hozzászólása Okt 11, 2015 /
 
Egy kérdés:

Mi a legjobb eljárás?
Van egy 8 bites bemenet ( gyakorlatilag 8 önallo bemenet) és 12 kimenetem.
A kimenetet szintén fel lehet fogni mint 8+4 bitet.
A bemeneten csak mintegy 20 állapot lehet és ezekhez kell 20 állapotot hozzárendelni a 12 bites kimeneten.
A bemenetet egy IRQ-vel rendszeresen lekérdezem, és a változásra kell a kimeneteket kapcsolni.
Én egy táblázatra gondolok, amiböl a bemeneti kod kiválasztaná a megfelelö kimenetet.
(#) zombee válasza Kovidivi hozzászólására (») Okt 11, 2015 /
 
Időzítő megszakítást használsz, amiben egy számlálót növelsz 1-10 között. A 4 LED-hez tartozik 1-1 volatile változó ami a fényerőt tárolja. Az időzítő megszakításban azt nézed hogy a számláló nagyobb-e mint a változók értéke, amelyiknél igen, ott kikapcsolod, különben bekapcsolod. Ennek a megszakításnak minimum 10x gyorsabbnak kell lennie mint amilyen ütemben változtatod a fényerőt, sőt érdemes ezzel szinkronizálni a változtatást.

Az általad leírt számértékeket egy kétdimenziós tömbbe töltöd be. Az időzítő megszakításnál akkor másolod át a következő négyes fényerőkódját a fent említett változókba, amikor a számláló éppen körbeért. Kétdimenziós tömb helyett használhatsz algoritmust is, az alapelv ugyanaz, de az irány meghatározására még egy segédváltozót is be kell iktatnod. Kódot nem írok, szerintem így is érteni fogod.
A hozzászólás módosítva: Okt 11, 2015
(#) zombee válasza Massawa hozzászólására (») Okt 11, 2015 /
 
Szerintem sokminden lehet. Ha időzítő IRQ-t használsz akkor a rendszernek eleve lesz egy késleltetése. Egyes esetekben nem baj, sőt inkább hasznos(pl. zajos bemeneteknél) ha egy kis "szőr" a bemeneten nem billenti át az egész rendszert.

Késleltetésre érzékeny cuccoknál vagy az időzítőt állítod be "nagyon" sűrűre, vagy PCINT-et használsz(pl. mega48/88/168). Az sem baj ha nem egy porton vannak: a megfelelő PCINT-es maszkokat beállítod, majd a különböző IRQ vektorok egy közös kezelőfüggvényt hívnak meg. Ez a kezelőfüggvény tartalmazza a táblázatot vagy algoritmust(ahogy tetszik), ami a kimeneteket beállítja a megadott állapotba.

Ha a 8 bemenetre csak 20 állapot lehetséges akkor neked két tömböt kell használnod. Az első egy 8 bites és 20 tagú (uint8_t allapotok[20]), ebbe egyesével beadod az állapotokat. Amelyikkel egyezik a bemenet, az az állapot lesz az érvényes. A másik, kimeneti tömb 16 bites a 12 bites (uint16_t kimenet[20]) kimenet miatt, ebben azt adod meg hogy a felismert bemeneti állapothoz(0-19 között) milyen kimenet tartozik.
A hozzászólás módosítva: Okt 11, 2015
(#) Kovidivi válasza zombee hozzászólására (») Okt 11, 2015 /
 
Szia.
Nem is a megszakítás a probléma, hanem hogy for ciklussal hogyan tudnám ezt leírni. És nem csak 0 2 4 6 8 és 10-zel szeretnék dolgozni, hanem 255 értékkel. A fot ciklusban simán lehet egy delay, semmi mást nem csinál a proci.
Valami ilyenre gondolok: for (int i=50;i<150;i++) (pwm_beallit(LED1, i-50); pwm_beallit(LED2,i);pwm_beallit(LED3,i+50); pwm_beallit(LED4,i+100) De ez mást csinál. Tehát nem tudom az gondolatot algoritmizálni. Pedig olyan könnyűnek néz ki...
(#) Massawa válasza zombee hozzászólására (») Okt 11, 2015 /
 
Kösz!
A késleltetés nem gond, söt valoszinü, hogy extra késleltetés is fog kelleni, hogy azonnal ne reagáljon a berendezés. Vagy a 2313-t vagy a Mega 328-t fogom használni ( ezekhez vannak kész NYÁKjaim némi perifériával).
A hozzászólás módosítva: Okt 11, 2015
(#) zombee válasza Kovidivi hozzászólására (») Okt 11, 2015 /
 
For ciklus nem is kell, csak egy végtelenített (pl. while(1) vagy for(;). E végtelenített ciklus végén az ominózus PWM változót növeled(ha eléri a maximumot akkor nulla), utána kell egy kis delay. Én úgy számolok hogy 1ms kell, ennél már nem villog. A ciklus elején nézed meg hogy a 4 beállított LED-fényerő változó nagyobb-e vagy kisebb-e mint a PWM változó, ez alapján állítod be a 4 kimenetet. A fényerő változtatást mindig olyan pillanatban csináldd amikor a PWM változó körbeért(tehát ezt is a végtelen ciklus legvégén).
(#) Kovidivi válasza zombee hozzászólására (») Okt 11, 2015 /
 
Hardveres PWM-em van Tehát ha pwm_beallit(LED1,10); -et meghívom, a LED1-et vezérlő timer OCR érték 10 lesz. Akárhogy akarom megoldani, mindig valami mást hozok össze. Le kell írnom sokkal több lépést, és abból kisakkozni, hogy mikor, melyik csatornát növelem, vagy csökkentem.
Következő: »»   697 / 840
Bejelentkezés

Belépés

Hirdetés
XDT.hu
Az oldalon sütiket használunk a helyes működéshez. Bővebb információt az adatvédelmi szabályzatban olvashatsz. Megértettem