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   569 / 840
(#) matheattila válasza Fizikus hozzászólására (») Okt 15, 2013 /
 
Szia.
Én is valahogy így oldottam meg, csak 4 szervóval és PIC18-al, de arra azért ügyelni kell, hogy a szervóknak is van saját elfordulási idejük (sebességük), ez álltalában 0.2sec/60º (Bővebben: Link), tehát nem lehet csak úgy váltogatni a pozícióját amilyen gyorsan csak akarjuk, mert akkor nem fog úgy mozogni ahogy várjuk és természetesen még a nyomatékából is veszít. Ahhoz, hogy ezt elkerüljük egy ú.n. "ramp"-et kell kialakítsunk az elvárt pozíció eléréséhez, azaz felosztjuk kisebb darabokra a megadott értéket és azt csak bizonyos időközönként növeljük.
Tehát a fenti szervónak 20ms-onként változtatjuk az elfordulását (az impulzus szélességét) akkor az azt jelenti, hogy maximum 6º-ot módosíthatjuk (ami nem túl sok). Ha el szeretnénk fordítani 90º-ot (0.3s) akkor azt nem adhatjuk ki neki egyből, hanem csak kisebb értékekben. Természetesen ez a maximális nyomaték eléréséhez sükséges (tudtommal), nem muszáj ezzel a módszerrel vezérelni, csak akkor fennáll annak a lehetősége, hogy ha nagyobb tömeget (természetesen a megengedettnél kisebbet) akarsz gyorsan elmozdítani vele akkor "elejti" azt és erőlködve próbálja visszavinni a kívánt pozícióba.
Ezt én sem tudtam annak idején mikor elkezdtem szervókkal foglalkozni, nekem is csak mondták, de javítsatok ki ha tévedek!
(#) zombee válasza gacserus hozzászólására (») Okt 15, 2013 /
 
Értem. Ilyenkor a szervó akkor is ugyanazt csinálja, amire a programod utasítja. Nálad ugyanaz a kontroller vezérli a motort, és magasabb szinten a FŐ program ad utasításokat a szervó rendszernek. Ez kimerül abban, hogy egy változóba valamilyen értéket ír bele.

A szervó részt tisztán interruptokkal kell megoldani, hogy bizonyos időközönként olvassa azt
a változót, és állítsa be a motorokra a PWM-et. Az adott változó(kívánt pozíció) mindenképp
volatile kell hogy legyen, mivel azt a főprogramból és interruptból is el kell érni.
(#) fifadani hozzászólása Okt 16, 2013 /
 
Sziasztok!
Van egy kis problémám...
  1. int main (void)
  2. {
  3.    DDRB = (1<<PB0); //PB0 kimenet
  4.    DDRD = (1<<PD1); //PD1 kimenet
  5.    DDRD &=~ (1<<PD2); //PD2 bemenet
  6.    PORTB = (1<<PB0); //PB0 kikapcsolva
  7.    PORTD &=~ (1<<PD0); //PD1 kikapcsolva
  8.    PORTD = (1<<PD2); //PD2 felhúzó ellenállás bekapcsolva
  9.  
  10.  while(PIND & (1<<PD2));
  11.  
  12.   while(1)
  13.    {
  14.  
  15.    PORTB ^= 0b00000001; //CPU működését jelző LED (0b0000001->(1<<PB0))
  16.    
  17.    DebugInit();   //Kijelző modul port inicializálása
  18.  
  19.    DebugClear();  //Kijelző törlése
  20.    
  21.    DebugSendStr("Hello");  //Küldött adat
  22.  
  23.    DebugNL();  //Adat megjelenítése és új sor
  24.    
  25.    m_delay_10ms(10);
  26.  
  27.    }
  28.  
  29.  
  30. return 0;
  31. }


(Topinak itt is köszönöm a munkáját a "DebugDisplay"-ért. Tökéletesen működik.)
Nos A regiszterek irányát beállítottam, felhúzó R-t bekapcsoltam PD2-n(logikai 1).
Az első while-ban figyelem azt, hogy a PD2[testre van kötve a kapcsoló] állapota milyen és ha teljesül a feltétel, lép tovább a következő while-ba.
A cikkek között láttam ezt a megoldás, de valamiért nekem nem okés.
Arra gondolok, hogy mivel a PD2-n lévő felhúzót bekapcsoltam, az őt figyelő while-ban már teljesül is a feltétel és ugrik egyből tovább.
Próbálkoztam megoldani de nem sikerült sehogy.
Mit szúrtam el?

Köszi!
(#) killbill válasza fifadani hozzászólására (») Okt 16, 2013 /
 
Mi a problemad? Mit csinal a program? Azaz mit nem csinal?
Az 5-os sorban levo utasitasnak nincs hatasa, mert az a bit egyebkent is torolve van, mert az elozo sor torli az osszes bitet a DDRD-ben, kiveve azt az egyet, amit beallit (PD1). Azon felul a 7-es sorban a program es komment nem ugyanazt mondja, bar jelen esetben nem szamit.
A 8-as sor egyebkent is felulirja a 7-es sor eredmenyet.
De elvileg a programod addig var, amig a PD2 lab magas szinten van. Ha lemegy alacsonyba, akkor rafut a masodik while-ra. Csak a jobb olvashatosag kedveert javaslom, hogy inkabb igy ird:
  1. DDRD &= ~(1<<PD2);
(#) fifadani hozzászólása Okt 16, 2013 /
 
Igen valamit elírtam és nem vettem észre, gondolok itt a kommentre.
Illetve oks az is, hogy a sorok felülírják egymást. Ezt elrontottam, de ezektől függetlenül nem műkszik a dolog.
Ráírom a programot a mega8-ra és már villog is a led, nem várja meg amíg én lenyomom a gombot. Ez a baj.
Javítottam:
  1. int main (void)
  2. {
  3.    DDRB = (1<<PB0); //PB0 kimenet
  4.    DDRD = (1<<PD1); //PD1 kimenet
  5.    PORTD = (1<<PD2); //PD2 felhúzó ellenállás bekapcsolva
  6.  
  7.  while(PIND&(1<<PD2));
  8.  
  9.   while(1)
  10.    {
  11.    PORTB ^= 0b00000001; //CPU működését jelző LED (0b0000001->(1<<PB0))
  12.    
  13.    DebugInit();   //Kijelző modul port inicializálása
  14.  
  15.    DebugClear();  //Kijelző törlése
  16.    
  17.    DebugSendU8(a);  //Küldött adat
  18.  
  19.    DebugNL();  //Adat megjelenítése és új sor
  20.    
  21.    m_delay_10ms(10);
  22.  
  23.    }
  24.  
  25. return 0;
  26. }
A hozzászólás módosítva: Okt 16, 2013
(#) killbill válasza fifadani hozzászólására (») Okt 17, 2013 /
 
Hm. Ennek pedig mukodni kellene. Kevesbe valoszinu, hogy az SFIOR regiszterben a PUD bit valamiert beall. Mert az tiltana a pull-up-okat. De inkabb az lehet, hogy a felhuzo bekapcsolasa es a while kozott nagyon keves ido telik el. Amikor bekapcsolod a pull-up-ot, utana a bemenet eleve egy kis ido elteltevel megy fel magasra, mert a szort kapacitasokat fel kell tolteni, es ahhoz a pullup ellenallas eleg nagy. Akar mikroszekundumok is lehetnek. Azon felul, ha rogton fel is menne a lab H-ba, a PIND olvasasa 2 orajelnyi kesessel adja csak a bemenet allapotat. Javaslom, hogy tegyel be egy kis kesleltetest az elso while ele. Eleg 1 ms. Ha ettol nem oldodik meg, akkor vagy elkotes, vagy nem tudom. Ha esetleg a kapcsoloval parhuzamosan van egy kondenzator, akkor annak fuggvenyeben nagyobb idozites is kellhet.
(#) fifadani hozzászólása Okt 17, 2013 /
 
Szia!
Most reggel kipróbáltam, hogy ha várok 1ms-t akkor mi történik.
Működik rendesen. Szóval akkor kell 1ms a felhúzás után.

Köszönöm!
(#) fifadani hozzászólása Okt 17, 2013 /
 
Sziasztok!
Folyamatosan haladok előre az avr-ek világában.
Szeretnék az LCD kijelzőmre egy órát.
Sikerült már megcsinálnom késleltetésekkel, viszont én megszakítást szeretnék sec-enként, hogy a főprogramban csak a kijelzés illetve a másodperc/perc/óra számítás legyen.
Tudna ebben valaki segteni?
Megfelelő nekem a Timer0? Gondolom igen, 0-255-ig elszámol.
Előosztással kellene a 16Mhz-s órajelemet "csökkenteni" a Timer0 számára?
Hogy tudom meghatározni, hogy mennyi a számomra ideális előosztás?
Illetve ha a Timer0 túlcsordul, akkor jön létre a megszakítás?
Ebből következik az, hogy a megszakításban adok a sec-hez +1et. Ugye?

Bocsi a sok kérdésért..
Köszönöm szépen.
A hozzászólás módosítva: Okt 17, 2013
(#) csabeszq válasza fifadani hozzászólására (») Okt 17, 2013 /
 
Én használtam már a timer0-t időmérésre. Minden millisec-enként interruptolt.

16.000.000/1.000=16.000 ciklusonként (64 * 250). Ebből következik, hogy az előosztást 64-re állítottam az OCRA-t meg 249-re. Ezután kiválasztottam egy olyan módot, ahol a TOP az OCRA.

Minden megszakításkor növeltem eggyel a millisec számát. Gyakorlatilag 16000 ciklusonként egy számláló-növelő interrupt az semmi, nincs hatással a sebességre.

A lényeg, hogy az interruptban a TCNT0-t eszedbe ne jusson beállítani.
A számláló eléri a TOP-ot -> interrupt -> látja, hogy cli()-vel éppen szórakozol és vár -> megkapod az interruptot (közben a TCNT0 már régen számol újra) -> lekezeled az interruptot és kiszállsz. Ha nem állítod át a TCNT0-t, akkor egyenletes interruptokat kapsz.

Kivéve: ha az interruptban kinullázod, mert akkor bizony az interruptra várakozás idejét elveszted és az óra késni fog.
A hozzászólás módosítva: Okt 17, 2013
(#) fifadani hozzászólása Okt 17, 2013 /
 
Szia!
Köszi, hogy válaszoltál.
Ez nekem még nehéz így...
Kód formájában, hogy nézne ki?
Hátha könnyebben felfogom, átlátom, hogy és mit kell....
A hozzászólás módosítva: Okt 17, 2013
(#) Fizikus válasza fifadani hozzászólására (») Okt 18, 2013 /
 
Milyen AVR-t hasznalsz?
En Timer0-t hasznaltam egy ATMega8-ason a szoftveres UART idozitesere:
szoftveres UART
ATMega8 Timer0
Az ATMega8-asnal a Timer0-nak nem tudod a TOP erteket allitani hogy meddig szamoljon, ezert a Timer1-et hasznalva pontosabb idozitest erhetsz el. Hasonloan mint az itt leirt szoftveres szervo idozitesnel:
Szoftveres szervovezerles
Neked csak a timer eloosztasat es a TOP erteket kell beallitanod + a tulcsordulasakor fellepo megszakitast kell hasznalnod.
(#) fifadani hozzászólása Okt 18, 2013 /
 
Szia!
Mega8-at használok.
A mellékelt szervóvezérlésből megpróbálom megcsinálni.
Köszönöm szépen!
(#) merlingerin hozzászólása Okt 19, 2013 /
 
Sziasztok!

Kis segítséget szeretnék kérni. Elkezdtem googlizni, meg itt is olvasni, de sajnos AVR ügyben teljesen kezdő vagyok. A lényeg: Építettem egy lépcső világítást, a következő fórum alapján:

http://www.ledstyles.de/ftopic15435-20.html

valami ilyesmi az eredmény:
Bővebben: Link

viszont az a baj, hogy én nagyon gyors vagyok, előbb fel/le érek, mint a fények kivilágosodnak, emiatt az időzítéseket módosítani kellene. Írtam is a szerzőnek, aki rendes volt, feltette a forrást is hozzá, ami itt van:

Bővebben: Link

De sajnos AVR lámaságom eredménye, hogy nem tudok mit kezdeni vele.

Programozóm, amivel eddig minden AVR-es utánépítésemet lábra állítottam egy ilyen: Bővebben: Link
software pedig PonyProg.

Mit kellene nekem telepítenem, illetve hogyan beállítani, hogy a mellékelt kódot módosítani tudjam? (én esetemben DELAY_FADE DELAY_LED értékeket. Sajnos google millió találata már kezd az őrületbe kergetni. Kikísérletezni ki tudom az értékeket, csak a "hogy" a kérdés

Tudtok nekem ebben segíteni?

Köszönöm!
(#) gtk válasza merlingerin hozzászólására (») Okt 19, 2013 /
 
Idézet:
„Mit kellene nekem telepítenem, illetve hogyan beállítani, hogy a mellékelt kódot módosítani tudjam?”
WinAVR. Ahogy nezem nincs Makefile hozza. Azt viszonylag konnyen el lehet kesziteni. Azt hiszem van itt az oldalon winavr cikk.
A hozzászólás módosítva: Okt 19, 2013
(#) zombee válasza merlingerin hozzászólására (») Okt 20, 2013 /
 
Vannak ebben érzékelők? Minden lépcsőfokon?
(#) merlingerin válasza gtk hozzászólására (») Okt 20, 2013 /
 
Szia!

Köszönöm!

Megtaláltam a cikket, végignyomkodtam, de valami nem kerek. Hiba nélkül lefordul, meg is van a hex, de az eredeti hex 3953 byte hosszú, az új hex 2934byte. Természetesen nem is fut az AVR-en. Nem csinál semmit. Ha nincs hiba, változtatás nélkül fordítom, azonosnak kellene lennie, nem? Mit ronthatok el? 1:1 leíást követtem.

Köszi!
(#) merlingerin válasza zombee hozzászólására (») Okt 20, 2013 /
 
Szia! Nincs, csak 1 fent, meg lent. Ha visszafordulsz, vagy más jön a másik irányból,az nincs kivédve.
(#) merlingerin válasza merlingerin hozzászólására (») Okt 20, 2013 /
 
A "soft-pwm.h"-t hozzá kell adni valahogy, vagy mivel include-ban szerepel a main.c-ben, így megeszi magától?

illetve a leírásban a main.c ikonja kis c betű, nálam meg text file ikon, de ugyan azt csináltam, mint a leírásban.
A hozzászólás módosítva: Okt 20, 2013
(#) zsuscsinyo válasza merlingerin hozzászólására (») Okt 20, 2013 /
 
A méret függ az optimalizációtól is.
(#) zombee válasza merlingerin hozzászólására (») Okt 20, 2013 /
 
Az, hogy az új kód 1KB-al kisebb, még nem jelenti hogy hibás. Ennyi a fordítón és az optimalizáláson is simán múlhat, vagy akár még több is! Lehet hogy ha én írnám meg, 1KB-nál alig lenne nagyobb mert a feladat nem bonyolult. Amúgy meg, ha csak két érzékelő van a rendszerben akkor a sebesség se így se úgy nem lesz jó. Ha pl. lassan mész akkor előreszalad...

A véleményem a dologról, hogy alapból a forrást kellett volna feltennie a szerzőnek és rendesen megcsinálni azt a részét hogy be lehessen konfigurálni. Nem mindenkinél van pontosan 16 lépcsőfok, maguk a lépcsők is különböznek, van amin gyorsan lehet menni és van amin csak nagyon lassan. Ezeket a paramétereket utólag kellene bevinni:
- sebesség, külön LEFELÉ és FELFELÉ (ezredmásodperc/lépcsőfok)
- fokozatos kigyulladás ideje(ezredmásodperc)
- tartási idő külön LEFELÉ és FELFELÉ (ezredmásodperc)
- fokozatos elalvás ideje(ezredmásodperc)
- lépcsőfokok száma
- portlista az egyes lépcsőfokoknak

Aztán látom magam előtt, hogy mielőtt leérek, valaki elkezd velem szembe felfelé jönni. Akkor most vagy az illető jön majd fel sötétben, vagy amikor leérsz, a rendszer elkezdi a LED-eket felfelé léptetni mert azt hiszi hogy elindult valaki felfelé...
A hozzászólás módosítva: Okt 20, 2013
(#) merlingerin válasza zombee hozzászólására (») Okt 20, 2013 /
 
Szia!

Jumperekkel állítható a lépcsőfokok száma. Nálunk keskeny a lépcső, nem jön szembe senki. Felérek, lekapcsol. Van time out, ha letelik, kikapcsol. Nekem tökéletes lenne.Magam megírni nem tudom, átírni át szeretném, de ehhez kérek segítséget. Csak hozott anyagból tudok dolgozni, mert ez van.
(#) gtk válasza merlingerin hozzászólására (») Okt 20, 2013 /
 
Az F_CPU be van allitva valahol a megfelelo ertekre ? A Makefileban, vagy ahol szerkeszted az aoptimalizalasi szintet allitsd at kissebbre. Valami CFLAGS -Os, -O0..4
(#) merlingerin válasza gtk hozzászólására (») Okt 20, 2013 /
 
Szia! Köszi a tippet. Makefile-ban próbáltam az optimalization level értéket 0, 1, s, 2, 3 változatban is, majd újrafordítva újra programozni. Sajna nem jött be...
(#) fifadani hozzászólása Okt 20, 2013 /
 
Sziasztok!
Próbálkoztam sokat, de nem sikerült az órámhoz a pontos 1 másodpercet előállítani.
Tudna valaki segíteni?
16Mhz-zől ketyeg egy atmega8.
A megszakítás makrójában akartam a sec-hez adni 1-et, illetve ott vizsgálni, hogy a sec több-e mint 59, ha több akkor min+1 stbstb..
Nem sikerült.
(#) matheattila válasza fifadani hozzászólására (») Okt 20, 2013 / 1
 
Szia!

Használd pl. a Timer1-et CTC üzemmódban, azaz ne túlcsorduláskor generáljon megszakítást hanem egy általad megadott értéknél amit te pontosan 1sec-re kiszámítottál. Ezzel a megoldással nagyon pontosan be tudod állítani azt az 1 másodperces megszakítást.
Itt egy példa ahogy én használtam:
  1. OCR1A   = 15624;  //  F_CPU/presc/1sec - 1;  16000000/1024/1 - 1
  2. TCNT1 = 0;
  3. TCCR1B |= (1 << WGM12);              // Mode 4, CTC on OCR1A
  4. TIMSK  |= (1 << OCIE1A);             // Set interrupt on compare match
  5. TCCR1B |= (1 << CS12) | (1 << CS10); // Set prescaler to 1024 and start the timer
  6.  
  7. sei();
  8. ...

és a megszakítás rutin:
  1. ISR (TIMER1_COMPA_vect)
  2. {
  3.    sec++;
  4.    if(sec >= 60) {sec = 0; min++}
  5.    if(min >= 60) {min = 0; hour++}
  6.    if(hour >= 24) {hour = 0; day++}
  7.    ...
  8. }

A megszakítás rutin mindig legyen a lehető legrövidebb (csak épp növelsz egy-két változót, beállítasz egy flag-et stb), ha egy változót a megszakítás rutinban is és a főprogramban is használsz akkor az legyen volatile (pl. volatile unsigned char sec, min, hour, day; )
(#) fifadani hozzászólása Okt 21, 2013 /
 
Nagyon szépen köszönöm!
Azért nem lehetett nekem jó, mert én timer0-át használtam.
Az meg ugyebár 255-ig számol. De így már értem az egészet.
(#) blackdog hozzászólása Okt 21, 2013 /
 
Sziasztok!

Elméleti kérdés:
AVR-el megvalósítható, hogy egy kimenetének a digitális jelsorozatát pl. 0x2E a tápfeszültségen küldjek tovább?
(#) blackdog válasza blackdog hozzászólására (») Okt 21, 2013 /
 
Kicsit érhetőbben.

Adott egy eszközöm amit egy távirányító vezérel. Ezeket kéteres vezeték köti össz. Ezen alapból 16VDC feszültség van, ha nincs bekötve a távirányitó.
Ha bekötöm akkor megindul a két eszköz között a kommunikáció oda-vissza és ez látható is szkópon.
Ennek a megvalósíthatósága érdekelne, ha tudtok segíteni.
(#) Massawa válasza blackdog hozzászólására (») Okt 21, 2013 /
 
Elöször ehhez a protokollt kéne tudnod - egy sereg ilyen rendszer van és sokban az AVR a központi processzor ( mindkét oldalon vevö-ado)
(#) blackdog válasza Massawa hozzászólására (») Okt 21, 2013 /
 
Miért kell ehhez előbb a protokoll?
Először a technikai része érdekel. Hogyan lehet ezt megoldani. Aztán jöhet, hogy az adatfolyam milyen protokoll szerint történik. Vagy tévedek?
Azért egy példát jó lenne látnom. (kapcsolás)
Következő: »»   569 / 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