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   651 / 837
(#) Kovidivi válasza Droot hozzászólására (») Márc 1, 2015 /
 
Bővebben: Link
Ebben már benne van a gyorsabb tekerés észlelése is! Ha jól látom, hiányzik belőle az irányváltás védelem, azt rád bízom! De ha nem rakod bele, akkor sem lesz zavaró, ha rendesen van kondival és soros ellenállással pergésmentesítve az encoder.
A hozzászólás módosítva: Márc 1, 2015
(#) Droot válasza Kovidivi hozzászólására (») Márc 1, 2015 / 1
 
Köszi! Én mondjuk soros ellenállást nem kötöttem be, csak párhuzamos kondit. Még sokat kell rajta faragni, mert ugye atmega8-on nincs millis függvény.
Tehát az irányváltás védelem úgy működik, ha tekertem pl jobbra, akkor ki van védve hogy utána csak x ms múlva tekerhetem balra, ugye?

Egyébként ötletes megoldás, tetszik!
Ha egy tippet elfogadsz, használd a #define-t! Pl: #define HIPERGYORS_VALT 50
Ez azért jobb, mintha változót használnál mert a fordító, de lehet hogy nem is az hanem a linker kicseréli a HIPERGYORS_VALT szót 50-re, tehát nem jut el a mikrovezérlőig, míg a változó plusz memóriát használ.
(#) phc hozzászólása Márc 1, 2015 /
 
Üdv mindenki!
Van egy probléma amire nem találtam megoldást hosszas keresgélés után sem.
Nem ketyeg a kvarc... (ATMEGA328P-AU TQFP32)
Pontosítok, mert azért mértem is.
A kavics egyik lábán alacsony szintet mérek, a másik láb rendben van. Külső oszcillátorral működik.
Első programfeltöltés után működött rendesen, majd apróbb változtatások, 2-3 újbóli feltöltés, és jött a hibaüzenet hogy nem elérhető. Segédórajellel persze ment rendesen.
feltöltöttem egy korábban írt programot teszt ként hátha ott van valami probléma.

Továbbá ezeknél a modelleknél i/o ként fel lehet használni az xtal lábakat is, de ezt a lehetőséget már kizártam.
kicseréltem a chipet is egy másikra, és ugyan ez lett a vége.
(#) TavIR-AVR válasza phc hozzászólására (») Márc 1, 2015 /
 
Órajelforrás megadásod hibás? Fusebitek elállítva...
Timer2-t óraként definiálod?
A hozzászólás módosítva: Márc 1, 2015
(#) phc válasza TavIR-AVR hozzászólására (») Márc 1, 2015 /
 
Egy pársoros alap programmal kizártam a programhibákat, ahol csak egy LED villog 100 as delay el.
(#) phc válasza TavIR-AVR hozzászólására (») Márc 1, 2015 /
 
És valóban a fusebit volt a hibás! Köszönöm a gyors választ!
(#) phc válasza TavIR-AVR hozzászólására (») Márc 1, 2015 /
 
És valóban a fusebit volt a hibás! Köszönöm a gyors választ!

ezt elsiettem.
Annyi történt, hogy bekapcsoltam a belső órajelet, de mikor külsőre váltottam teljesen elvesztettem.
Már nem tudom külső órajelgenerátorral sem elérni.
(#) TavIR-AVR válasza phc hozzászólására (») Márc 1, 2015 /
 
Kívül:
- szakadt/hibás/törött/forrasztáselengedett 2 db kondi (12...27pF)
- sérült kvarc
- hosszú vezeték, a kvarcok fele
- forrasztógyanta/nedvesség
(#) phc válasza TavIR-AVR hozzászólására (») Márc 1, 2015 /
 
Kb 18mm hosszú a szál a kvarc felé, a gyanta miatti kapacitásra gondoltam korábban, de rendesen le van takarítva.
A kondikat cseréltem, a szakadásokat mértem, a viákat is végigmértem.
kvarcokat cserélgettem 8, 16, 20 MHz... külső generátor 8MHz.
nedvesség kizárható, a kvarc egyik lábán alacsony logikai állapot volt eddig. Most viszont ez a jelenség megszűnt.

Marok egy új nyákot és meglátjuk.

Esetleg van valami ötlet mi eredményezhette ezt 2x egymás után ?
(#) zombee válasza Droot hozzászólására (») Márc 1, 2015 /
 
Én lehet hogy timert használnék amivel X időnként leolvasom az értéket ÉS fel is dolgozom, beállítom az enkódertől függő változót és kész. Ennek az időnek természetesen igazodnia kell a lehető leggyorsabb forgatáshoz, legfeljebb az "események" közt eltelt legkisebb időnek 1/4-e lehet, de ne legyen túl gyors(pl. ezred része) sem! Pl. ha motoros forgatásról beszélünk 3000/perc fordulatú motorral és egy 24 lépéses enkóderrel akkor kb. 4.8kHz-es leolvasásról beszélünk. Egy "humán interfész" ennél sokkal lassabb!

Egy működőképes enkódernél lehetetlen, hogy amikor az egyik jelnél váltás van, akkor a másik jel nem stabil. Függetlenül a szűréstől. Ezért nagyon érdekes számomra minden olyan esemény, amikor egy egységnyi elfordulásnál 5-10 egységeket is lép a változó. Legfeljebb 1-1 egységet ugrálhatna fel-le, azt is csak ha határon van a dolog.

Ezt az egyszerű kódot próbálta már valaki? Nem épp optimális, de egy 8MHz-es AVR-en simán elmegy:
  1. #DEFINE MAX 23
  2. #DEFINE MIN 0
  3. volatile int16_t pozicio = 0;
  4. uint8_t enkoder_elozo = PORTB&0b00000011; //feltéve ha PORTB1:0 az enkóder bemenete
  5.  
  6. ISR(TIMER_1_MATCH_A_INTERRUPT) //CTC-vel
  7. {
  8.   uint8_t enkoder = PORTB&0b00000011;
  9.   if(enkoder_elozo!=enkoder)
  10.   {
  11.     if(enkoder_elozo==00 && enkoder==10) pozicio++;
  12.     else if(enkoder_elozo==10 && enkoder==11) pozicio++;
  13.     else if(enkoder_elozo==11 && enkoder==01) pozicio++;
  14.     else if(enkoder_elozo==01 && enkoder==00) pozicio++;
  15.     else if(enkoder_elozo==10 && enkoder==00) pozicio--;
  16.     else if(enkoder_elozo==11 && enkoder==10) pozicio--;
  17.     else if(enkoder_elozo==01 && enkoder==11) pozicio--;
  18.     else if(enkoder_elozo==00 && enkoder==01) pozicio--;
  19.     enkoder_elozo = enkoder;
  20.     if(pozicio>MAX) pozicio = MIN;
  21.     else if(pozicio<MIN) pozicio = MAX;
  22.   }
  23.  
  24. }
A hozzászólás módosítva: Márc 1, 2015
(#) Massawa hozzászólása Márc 2, 2015 /
 
Egy kérdés

A studio4 szimulator üzemmodban nem akarja beolvasni a kézzel állitott port bemeneteket.
Ldi r16,$0
Out ddrd,r16. ; ddrd bemenet
In r16, pind

Ha a pinD ben az egérrel 11111110- állitok (7 fekete kocka 1 üres) akkor 254 helyett is csak 0-t olvas.
Nem tudok rájönni miért. Ez a rutin eddig mindig ment.
(#) rolandgw válasza Massawa hozzászólására (») Márc 2, 2015 /
 
Mikor állítod ? Mert ha a pin olvasás előtti utasításnál az már késő.
(#) Massawa válasza rolandgw hozzászólására (») Márc 2, 2015 /
 
2 lépéssel elötte.
(#) tkovacs válasza Massawa hozzászólására (») Márc 2, 2015 /
 
Szia!
Én bekapcsolnám a felhúzóellenállásokat.
ldi r16,0x00
out ddrd,r16
ldi r16,0xff ;enable pull-up
out portd,r16
in r16,pind
Üdv.
(#) Massawa válasza rolandgw hozzászólására (») Márc 2, 2015 /
 
Már sikerült 4-5 lepéssel korábban akkor megy.
(#) Massawa válasza tkovacs hozzászólására (») Márc 2, 2015 /
 
Kösz, azok ott vannak alapbol, most inkább a szimulátorral voltam gondban. Ahhoz meg nem kell a pull-up.
A hozzászólás módosítva: Márc 2, 2015
(#) rolandgw válasza Massawa hozzászólására (») Márc 2, 2015 /
 
Erre való a stimuli fájl .
(#) Droot válasza k3gy3tl3n hozzászólására (») Márc 2, 2015 /
 
Ez akkor is működik, ha a beteg egy ATmega8L és a doktor is egy mega8?
(#) Massawa hozzászólása Márc 2, 2015 /
 
Nincs valakinek irányváltos ASM kodja unipoláris léptetömotorhoz?
Egyirányu van és megy is, de van némi gondom az irányváltással. ( lépésvesztés).

Kösz
(#) k3gy3tl3n válasza Droot hozzászólására (») Márc 2, 2015 /
 
Szia elvileg azzal is mennie kell (tök ugyan az a lábkiosztása mint a mega48-nak), de ha gondolod holnap kifingatom az egyik mega8-amat és megnézem. Csak a C kódban kell a kívánt fuse biteket átírni.
(#) Droot válasza k3gy3tl3n hozzászólására (») Márc 2, 2015 /
 
Ki ne fingasd de megköszönném!
(#) k3gy3tl3n válasza Massawa hozzászólására (») Márc 2, 2015 /
 
Szia, én így léptetem az enyémet. Max 100-at engedem balra és jobbra lépkedni (stepcount) mert egy hajólapátot kormányoz. Értelemszerűen a dir az irány. dir==0 nál visszaáll középre, dir==1 balra lépked dir==2 jobbra lépked.
  1. void Turn(uint8_t dir)
  2. {
  3.         if(dir==1 && stepcount<100)//left
  4.         {
  5.                 if(stepcount % 4 == 0){
  6.                         PORTD |= (1<<PD6);
  7.                         delay_ms(10);
  8.                         PORTD &= ~(1<<PD6);  
  9.                 }
  10.            
  11.                 if(stepcount % 4 == 1 || stepcount % 4 == -3){
  12.                         PORTB |= (1<<PB0);
  13.                         delay_ms(10);
  14.                         PORTB &= ~(1<<PB0);  
  15.                 }
  16.  
  17.                 if(stepcount % 4 == 2 || stepcount % 4 == -2){
  18.                         PORTD |= (1<<PD7);
  19.                         delay_ms(10);
  20.                         PORTD &= ~(1<<PD7);
  21.                 }
  22.  
  23.                  if(stepcount % 4 == 3 || stepcount % 4 == -1){
  24.                         PORTD |= (1<<PD5);
  25.                         delay_ms(10);
  26.                         PORTD &= ~(1<<PD5);
  27.                 }
  28.                 stepcount++;
  29.         }
  30.        
  31.         if(dir==2 && stepcount > -100)//right
  32.         {
  33.                
  34.                 if(stepcount % 4 == 3 || stepcount % 4 == -1){
  35.                         PORTD |= (1<<PD5);
  36.                         delay_ms(10);
  37.                         PORTD &= ~(1<<PD5);  
  38.                 }
  39.            
  40.                 if(stepcount % 4 == 2 || stepcount % 4 == -2){
  41.                         PORTD |= (1<<PD7);
  42.                         delay_ms(10);
  43.                         PORTD &= ~(1<<PD7);  
  44.                 }
  45.  
  46.                
  47.                 if(stepcount % 4 == 1 || stepcount % 4 == -3){
  48.                         PORTB |= (1<<PB0);
  49.                         delay_ms(10);
  50.                         PORTB &= ~(1<<PB0);
  51.                 }
  52.  
  53.                 if(stepcount % 4 == 0){
  54.                         PORTD |= (1<<PD6);
  55.                         delay_ms(10);
  56.                         PORTD &= ~(1<<PD6);
  57.                 }
  58.                 stepcount--;
  59.         }
  60.        
  61.         if(dir==0 && stepcount > 0)
  62.         {
  63.                 if(stepcount % 4 == 3 || stepcount % 4 == -1){
  64.                         PORTD |= (1<<PD5);
  65.                         delay_ms(10);
  66.                         PORTD &= ~(1<<PD5);  
  67.                 }
  68.            
  69.                 if(stepcount % 4 == 2 || stepcount % 4 == -2){
  70.                         PORTD |= (1<<PD7);
  71.                         delay_ms(10);
  72.                         PORTD &= ~(1<<PD7);  
  73.                 }
  74.  
  75.                
  76.                 if(stepcount % 4 == 1 || stepcount % 4 == -3){
  77.                         PORTB |= (1<<PB0);
  78.                         delay_ms(10);
  79.                         PORTB &= ~(1<<PB0);
  80.                 }
  81.  
  82.                 if(stepcount % 4 == 0){
  83.                         PORTD |= (1<<PD6);
  84.                         delay_ms(10);
  85.                         PORTD &= ~(1<<PD6);
  86.                 }
  87.                 stepcount--;   
  88.         }
  89.        
  90.         if(dir==0 && stepcount < 0)
  91.         {
  92.                 if(stepcount % 4 == 0){
  93.                         PORTD |= (1<<PD6);
  94.                         delay_ms(10);
  95.                         PORTD &= ~(1<<PD6);  
  96.                 }
  97.            
  98.                 if(stepcount % 4 == 1 || stepcount % 4 == -3){
  99.                         PORTB |= (1<<PB0);
  100.                         delay_ms(10);
  101.                         PORTB &= ~(1<<PB0);  
  102.                 }
  103.  
  104.                 if(stepcount % 4 == 2 || stepcount % 4 == -2){
  105.                         PORTD |= (1<<PD7);
  106.                         delay_ms(10);
  107.                         PORTD &= ~(1<<PD7);
  108.                 }
  109.  
  110.                  if(stepcount % 4 == 3 || stepcount % 4 == -1){
  111.                         PORTD |= (1<<PD5);
  112.                         delay_ms(10);
  113.                         PORTD &= ~(1<<PD5);
  114.                 }
  115.                 stepcount++;   
  116.         }
  117.  
  118. }
(#) zombee válasza Massawa hozzászólására (») Márc 2, 2015 /
 
Kódom nincs, de talán segíthet az alábbi pár "tétel"
- legyen egy 8 bites változód (számláló), ami 0 és n-1 közötti értéket vehet fel
- n az a szám amennyi állapotból áll egy ciklus. Pl. 4 tekercses motornál általában 4, finomátmenetekkel 8.
- minden állapothoz legyen egy portmegfeleltetés, pl. 0=0011; 1=0110; 2=1100; 3=1001;
- egy előre vagy hátra léptetés a számláló növelésével vagy csökkentésével áll elő
- ilyenkor ellenőrizni kell hogy benne van-e a 0..n-1 tartományban, szükség esetén korrigálni azt
- és természetesen az új értéknek megfelelően meg kell változtatni a portkimenetet is

Csak szólok hogy ez igazából nagyon hasonlít az (inkrementális) enkóder kezeléséhez...
A hozzászólás módosítva: Márc 2, 2015
(#) k3gy3tl3n válasza Droot hozzászólására (») Márc 2, 2015 /
 
Kezdésnek csak beállítok valami külső kristályt meg kikapcsolom a SPIEN-t, de átgondolva ezt is felesleges, csak egyszerűen megpróbálok a jelenlegitől eltérő fuse biteket beirni és ha beveszi akkor boldogság!
(#) Massawa válasza zombee hozzászólására (») Márc 2, 2015 /
 
Én is valahigy igy okoskodom, de azt hiszem egyszerübb lesz megirni a semmiböl mint a meglevöt változtatni.

Sajnoc a C nyelvet nem értem...
(#) k3gy3tl3n hozzászólása Márc 2, 2015 /
 
Sziasztok! Építettem egy RFMxx modulokkal működő adót és vevőt (hajó), szeretném a vevőn elérni, hogy ha 1 másodpercig nem kap jelelt leállítsa a motorokat. Jelenleg ha kikapcsolom az adót a vevő a legutolsó állapotban ragad, azaz ha előre ment a hajó akkor kimegy a világból. Valami timerre gondoltam ami ha eléri az 1secet akkor csinál egy interruptot amiben lekezelem a motorok leállítását, ha pedig jön adat elkezd ismét 0-tol számolni. Van erre valakinek példakódja?
(#) k3gy3tl3n válasza Massawa hozzászólására (») Márc 2, 2015 /
 
Amit küldtem kódot nagyon minimális C tudást igényel. A leg bonyolultabb művelet a maradékos osztás "%" benne. A stepcount tartalmazza hogy hányat léptünk. Pédául ha lépkedünk balra akkor a stepcount értéke 1,2,3,4,5....100 lesz. Onnét tudom hogy melyik a következő lépés hogy a stepcountot elosztom 4-gyel maradékosan. Pl stepcount = 9 akkor stepcount%4 = 1 lesz ebböl tudom hogy ha jobbra akarok lépni akkor melyik a következő tekercs amit húznom kell. Ugyanígy a másik irányba lépkedve a stepcount -1,-2,...-100 lesz ekkor ha stepcount = -7 akkor stepcount%4 = -3 és ebböl tudom hol állok éppen (melyik tekercsen) és hogy mi legyen a következő.
(#) Massawa válasza k3gy3tl3n hozzászólására (») Márc 2, 2015 /
 
Nekem csak egy bajom van, hogy ha igy csinálom meg ( c ben amugy sem tudom) akkor lesz egy határ - tegyük fel 640 lépés egy fordulat, s ha a 640. poziciorol az 1. -re kell menni, akkor nekem vissza kell forogni 639-t, ahelyett, hogy egyet lépne elöre.

Ha jól értelmezem a te kododat.

Én ugy gondoltam, hogy gyakorlatilag elég volna elmenteni a 4 alaplépésböl ($05,$06,$09,$0A) az utolsot és onnan indulni a kivánt irányba. Igy nincs abszolut helyzet.
(#) holex hozzászólása Márc 2, 2015 /
 
Nem ismer véletlenül valaki olyan enkódert ami egy vezetéken kommunikál? Pl. Dallas OneWire buszon.
(#) k3gy3tl3n válasza Droot hozzászólására (») Márc 3, 2015 /
 
Szia, kipróbáltam, mega8-at is gyógyít A kódban csak a FUSE biteket írtam át erre:
  1. #define HFUSE   0xD9 //atmega8L
  2. #define LFUSE   0xE4

Kb 8-10 másodpercig kellett nyomnom a gombot mire a led ujra felvillant (kész lett a gyógyítás). Lehet nem árt leírni, ha feléled a doktor világít a led, amint lenyomod a gombot kialszik a led és nyomva kell tartani míg fel nem villan.
A hozzászólás módosítva: Márc 3, 2015
Következő: »»   651 / 837
Bejelentkezés

Belépés

Hirdetés
Lapoda.hu     XDT.hu     HEStore.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