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   539 / 840
(#) xNorbi hozzászólása Jún 8, 2013 /
 
Helló

Iskolába kell egy feladatot csinálnom, ami a következő: egy LED kijelzőn kell 99től 2másodperces intervallumokban visszafelé számolni 0ig, megszakítások segítségével, utánna ha a kijelző értéke elérte a 0át, akkor villogtatni két LEDet majd folytatni a számlálást megint 99től.

Az egészet leprogramoztam csak az egyik megszakítás után ahol a reti utásítással vissza kéne ugrania a kód elejére egy teljesen más helyre ugrik és fogalmam sincs miért csinálja, felvettem az egészet videóra a reti parancs után pár sorral feljebb ugrik az ldi kezdetű sorhoz, ahelyett hogy az elejére ugrana. Valaki tudna segíteni? Köszönöm
A hozzászólás módosítva: Jún 8, 2013

asm.asm
    
(#) kurosaki hozzászólása Jún 9, 2013 /
 
Sziasztok bocsi hogy zavarok na szoval sikerült némi előrelépést csinálni a projektemben csak elakadtam.
Forráskód:Bővebben: Link
Eredeti: Bővebben: Link ez alapján csináltam/módosítottam de akármit csinálok a led nem világit se fényre se sötétségre.Valaki segítene, hogy mit ronthattam el??Köszönöm előre is.

Link javítva.
Kérlek használd a LINK gombot!
A hozzászólás módosítva: Jún 9, 2013
(#) Fizikus válasza kurosaki hozzászólására (») Jún 9, 2013 /
 
Szia!
Az eredeti kodban 2 db LDR-en let megmerve ADC-vel a fenyero. Az ingerkuszob valtozoval azt lehetett beallitani hogy a 2 mert ADC ertek kulonbesege legalabb mekkora legyen, aminel a robot elkezd fordulni (a cikkben 8-as erteket hasznaltam).
Te nem 2 erteket hasonlitasz ossze, a kododban hasznalt 1-es ertek nagyon keves. Probald meg 50, 100, 150 es 200-as ertekkel (nem tudom milyen LDR-t mekkora ellenallasokkal egyutt hasznalsz).
(#) kurosaki válasza Fizikus hozzászólására (») Jún 9, 2013 /
 
Akkor az ingerküszöböt állítgassam csak?
(#) Fizikus válasza kurosaki hozzászólására (») Jún 9, 2013 /
 
Igen. Az ADC-vel mersz egy 0-255 koze eso szamot. Ez fog valtozni ha az LDR-t megvilagitod majd letakarod hogy sotetben legyen. A legjobb az lenne ho soros porton kiiratnad az ADC ertekeket PC-re, akkor pontosan latnad hogy mennyit valtoznak az ADC ertekek es a kuszoberteket is konnyebb lenne beloni...
(#) kurosaki válasza Fizikus hozzászólására (») Jún 9, 2013 /
 
Tranzisztorral meg csináltam ott egy 100K ellenállást használtam és pöpecül ment. Gondolom ide kisebb kell de hiába cserélgetem az ellenalasokat es az értékeket semmise történik.
(#) kurosaki válasza Fizikus hozzászólására (») Jún 9, 2013 /
 
Tranzisztorral meg csináltam ott egy 100K ellenállást használtam és pöpecül ment. Gondolom ide kisebb kell de hiába cserélgetem az ellenalasokat es az értékeket semmise történik.
Modositás:Bővebben: Link ezt használom.
A hozzászólás módosítva: Jún 9, 2013
(#) Fizikus válasza kurosaki hozzászólására (») Jún 9, 2013 /
 
Merjed ki hogy az ellenallasoszto kapcsolasban mekkora feszultseg van az LDR labain, ebbol is lehet kovetkeztetni arra hogy kb mekkora lesz az ADC ertek.
(#) kurosaki válasza Fizikus hozzászólására (») Jún 9, 2013 /
 
Őő rendben bár ha 255 re van allitva (ahol érzéketlen akkor vagy világítania kéne vagy világítania kéne nem?).Bár lehet maga a kód is hibás ahogy átírtam.
(#) Fizikus válasza kurosaki hozzászólására (») Jún 9, 2013 /
 
Csak a nagyobb logikai hibakat neztem a kodban, reszletesen nem neztem hogy mas hiba is van-e.
(#) kurosaki válasza Fizikus hozzászólására (») Jún 9, 2013 /
 
Mert van a kép az LDR ADC bekötésére megcsináltam (az ADC lábról megy az ellenállás ugye a GND re?)
(#) Fizikus válasza kurosaki hozzászólására (») Jún 9, 2013 /
 
Ugy kell bekotni, ahogy ezen az oldalon a vonalerzekelo szenzorra vonatkozo reszben leirtam (a LED-et es az 510 ohm-os ellenallast hagyd ki, az nem kell neked)
Bővebben: Link
(#) kurosaki válasza Fizikus hozzászólására (») Jún 9, 2013 /
 
Szerintem a kóddal van a gond mert lehet kivettem a jobb "LDR" de lehet az összehasonlítás vagy az IF ami nem jó.mert most is végig próbáltam 10 töl az értékeket de semmi és 47K,100K,100Ohm 47ohm ellenállásokkal próbáltam végig.
(#) Fizikus válasza kurosaki hozzászólására (») Jún 9, 2013 /
 
A program sem jo. A PB0-as labra kotott LED-et kapcsolgatod.
A PB4-es labat allitod be bemenetnek es erre kotod az LDR-t, a kodban viszont az LDRbal = Beolvas8bitADC(0); utasitassal a PC0-as labon levo feszultseget olvasod be. Raadasul ha Atmega8-ast hasznalsz, akkor csak a portC labai az analog bemenetek nem a portB ...
(#) zombee válasza ThompsoN hozzászólására (») Jún 9, 2013 /
 
Látom, alapvető villamosságtani ismeretek hiányoznak. A képen egy ilyet látsz.
A tekercs legyen 47uH-100uH, a kondi 470nF-10µF közötti.
A hozzászólás módosítva: Jún 9, 2013
(#) kapu48 válasza zombee hozzászólására (») Jún 9, 2013 /
 
Bocs!
A sietség átka!
Töröld a linkből a ;-őt!
60 nap alatt Arduino #35 - Programozás/Bootloader

Közben Robert Mester is bejelentkezet!
(#) csabeszq válasza xNorbi hozzászólására (») Jún 9, 2013 /
 
1. miért assembly-ben programozol? A C simán lekezeli az egészet helyetted.
2. a RETI a vermet használja, mint visszatérési címet

Ha lenyomsz a verembe push-sal valamit, amit elfelejtesz kivenni, vagy pop-pal többet veszel ki, mint kellene, akkor a RETI értelemszerűen máshová fog visszaugrani.

Ha C-ben programoznál assembly helyett, ilyen problémád nem lenne egyáltalán, mert a C elintéz mindent helyetted

3. minthogy a reti visszatérési értéke a veremben van simán felül tudod írni, lásd a kódomat

  1. void igy_szoktuk_szetbarmolni_a_retit()
  2. {
  3.   uint32_t puffer[16];  // 4*16 byte lefoglalasa a vermen
  4.   puffer[16] = 0xDEADBEEF; // a verem 4 byte-os tulirasaval szetcsesszuk a RETI visszateresi erteket
  5. }
A hozzászólás módosítva: Jún 9, 2013
(#) zombee válasza csabeszq hozzászólására (») Jún 9, 2013 /
 
Iskolába kell neki(le is írta az elején) azaz meg van kötve a keze. Assembly és kész!
Nálunk (BME) szintén assembler volt a kötelező, az AVR GCC-vel évekkel később találkoztam.
(#) kurosaki válasza Fizikus hozzászólására (») Jún 9, 2013 /
 
Attiny45 használok az Atmega8 at írtam át mert alapvetően PORTC volt. Attiny45 csak PortB van.Vagy nem így kell megírni, hogy Éjszaka kapcsolja a ledet?.
A hozzászólás módosítva: Jún 9, 2013
(#) Massawa hozzászólása Jún 9, 2013 /
 
ASM rutint keresek léptetömotorhoz.

Adott az idö és a lépésszám. A motornak optimálisan kellene gyorsulnia illetve lassulnia az adott határok között ( pl. 10 mp alatt tegyen meg 100 lépést szépen kigyorsulva és lassulva).

Kösz.
(#) zombee válasza xNorbi hozzászólására (») Jún 9, 2013 / 1
 
Nem akarlak megsérteni, de ez MICSODA? Alapvető problémák vannak a programoddal! És nem az a legnagyobb hogy rossz helyre térsz vissza. Kezdeném a legsúlyosabbal: az SREG-et és a felhasznált regisztereket miért nem mented és töltöd vissza az interruptban? Ülj le fiam, egyes!
  1. int_timer2:
  2.         push r16
  3.         in r16,SREG
  4.         push r16
  5.         //ide jön az interrupt többi része. csak az r16-ot használhatod, a többit csak akkor ha lemented!
  6.         pop r16
  7.         out SREG, r16
  8.         pop r16
  9.         reti


A következő probléma már az átláthatósággal van. Látom hogy kiugrasz az interruptból, és máshol adod ki a reti parancsot. Ez nem olyan súlyos, mert az ugrással nem végzel veremműveletet, bátran lehet ugrálni egy interrupton belül. De: az előző bekezdésben láthattad hogy vissza kell tölteni az r16-ot és az SREG-et, ami a RETI előtt még 3 sor. Ezt minden RETI elé be kéne tenni, ami macerás és veszélyes ha valamit elfelejtesz megduplázni. Ezért a Te érdekedben tartsd tiszteletben a szabályt: az interrupt legyen egy független blokk, egyetlen belépési és egyetlen kilépési ponttal! Hogy érthető legyen:
  1. int_timer2:
  2.         push r16
  3.         in r16,SREG
  4.         push r16
  5.         out PORTB, R16          //enable leds
  6.         in R19, PORTB           //read led status
  7.         cpi R19, 255            //if leds on
  8.         brne interrupt_vege     //ugrik, ha NEM TELJESÜL a feltétel.
  9.         out PORTB, R17          //disable leds - tehát ezt ide kell beszúrni!
  10. interrupt_vege:
  11.         pop r16
  12.         out SREG, r16
  13.         pop r16
  14.         reti

Itt direkt ugrást tettem be hogy látványos legyen, de az SBIC sokkal szebb(SBIC SREG,Z).

A harmadik probléma, hogy inicializáláskor nem állítod be a stack pointer-t.
Pedig kell, ha a programodban használsz 1:szubrutin hívást; 2:interruptot; 3: stack-ben tárolást.
Elvileg körbefordul(indításkor zérus), de azért jobb ha beállítod:
  1. stack_pointer_setup:
  2.         LDI     R16, low(RAMEND)
  3.         OUT     SPL, R16
  4.         LDI     R16, high(RAMEND)
  5.         OUT     SPH, R16


Egy kis segítség assemblerhez a csatolmányok között, hasznos!!!
A hozzászólás módosítva: Jún 9, 2013
(#) csabeszq válasza zombee hozzászólására (») Jún 9, 2013 /
 
Úgy beszélsz, mintha sosem lettél volna diák életedben.

Egyelőre nem tiszta számomra, hogy mi akadályozza meg abban, hogy megírja a programot C-ben, a generált assembly kódot meg kisebb-nagyobb változtatásokkal beadja.

Én úgy tanultam meg az AVR assembly-t, hogy kielemeztem, hogy mit fordít a fordító. Sajnos időnként még előfordul, hogy jobb kódot generál nálam, de ahhoz több tudás kell, hogy megverjem sebességben és méretben.
A hozzászólás módosítva: Jún 9, 2013
(#) xNorbi válasza zombee hozzászólására (») Jún 9, 2013 /
 
Köszönöm a bő választ, sokminden tisztázódott belőlle. Abból a hibás feltételezlsből indultam ki, hogy a ret és reti utasítások vissza ugranak az elágazás, megszakítás, stb, helyére.
(#) zombee válasza csabeszq hozzászólására (») Jún 9, 2013 /
 
Ha azt adja be aztán rákérdez hogy ez miért, az miért? Neki assemblerben kell MEGÍRNI és BEADNI. Melyik része nem érthető?
(#) csabeszq válasza zombee hozzászólására (») Jún 9, 2013 /
 
Igen, mondjuk puskázni is tudni kell. Egy pedagógus mondta nekem, hogy aki hülye, az puskával is 1-esre írja a dolgozatát.

Természetesen ha az avr-gcc LIBC-s részét bemásolod az interrupt tábla utánra, akkor ha életében egy C projektet már lefordított a tanár, látni fogja, hogy a kód generált.

Diákéveimben gyakran éltem olyan eszközökkel, hogy megnéztem, hogy a nagyfiúk hogyan számolnak ki egy elektronikai kapcsolást. Utána a saját egyenleteimet úgy alakítottam, hogy az jöjjön ki és fele annyi idő alatt oldottam meg a feladatot, mint mások.

A számológépemben ott volt a 3-ad 4-ed fokú egyenletmegoldó képlet, kivágta az összes gyököt, ezután leírtam, hogy "vegyük észre, hogy a 12 megoldása az egyenletnek"...

(nem mertek a tanárok csak olyan köbös egyenleteket írni, ahol az egyik gyök találgatással kiszámolható volt, de hülye lettem volna találgatni).
(#) xNorbi válasza zombee hozzászólására (») Jún 9, 2013 /
 
Még azt szeretném kérdezni, hogy ha beugrok egy elágazásba így:
  1. MAIN:
  2.       cp r1,r2        //ha egyenlő
  3.       breq LOOP   //ugrás
  4. LOOP_RET:
  5.       NOP
  6.       ...
  7.       rjmp MAIN
  8.  
  9. LOOP:
  10.       NOP
  11.       rjmp LOOP_RET //ugras vissza

Visszaugorni és folytatni a főprogramot így kell, vagy van rá valami szebb trükk?
(#) csabeszq válasza xNorbi hozzászólására (») Jún 9, 2013 /
 
Nem tiszta, hogy a LOOP-ot mire akarod használni,

C-ben:
  1. uint8_t i;
  2. for(i=1; i <10; i++)
  3. {
  4.   PORTD = i;
  5.   if( i == 8 )
  6.   {
  7.      PORTB |= 2;
  8.   }
  9. }


Lefordítva:
  1. ldi r24, 1
  2. ciklus:
  3.   out   PORTD, r24
  4.   cpi   r24, 8
  5.   brne hamis_feltetel
  6.   sbi PORTB, 1
  7. hamis_feltetel:
  8.   subi  r24, 0xFF
  9.   cpi   r24, 10
  10.   brne  ciklus
(#) csabeszq válasza csabeszq hozzászólására (») Jún 9, 2013 /
 
Te a kódodban összevissza rjmp-zel, ez pedig szerintem felesleges.

Ami még itt érdekes, hogy a gcc fordító
  1. inc r24
helyett
  1. subi r24, 0xff
-et használt.

Ergo: levont a regiszterből -1-et növelés helyett. A két utasítás teljesen egyenértékű, mégis látszik, hogy a kód generált, mert normális ember inkább növeli a számlálót, mintsem -1 -gyel csökkentse.
(#) ThompsoN válasza zombee hozzászólására (») Jún 9, 2013 /
 
Igen, ez így van, még csak ismerkedek a témával.

Még egy olyan kérdésem lenne, hogy ezt a kis részt az AVR és a MOSTFET közé tegyem, vagy a MOSFET és a ventilátor közé?
(#) zombee válasza xNorbi hozzászólására (») Jún 9, 2013 / 1
 
LOOP részbe nem szokás beleugrani, pontosan az ellenkezőjét kell csinálni. Ha a korábbi, azaz a LOOP-ba ugrás feltétele NEM teljesül, akkor ÁTUGROD, egyébként "belefutsz" a LOOP-ba.
Illusztrálom:
  1. MAIN:
  2.       cp r1,r2        //ha NEM egyenlő
  3.       brne LOOP_RET   //ÁT-ugrás
  4. LOOP:
  5.       ...
  6.       (feltétel, rjmp LOOP ha újabb ciklus kell)
  7. LOOP_RET:
  8.       (ciklus vége)
  9.       ...
  10.       rjmp MAIN
Következő: »»   539 / 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