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   681 / 840
(#) killbill válasza Max26 hozzászólására (») Júl 22, 2015 /
 
Az F_CPU definicio vegerol vedd le az UL-t. Az a baja. A szokozoket visszateheted a / ele es utan.
(#) Droot hozzászólása Júl 22, 2015 /
 
Sziasztok!

ATmega8-al szeretnék 1us-os Timer megszakítást. Az órajel viszont adott, 8MHz, ezt más feladatok miatt nem változtathatom.
Van valami ötletetek?
Én próbáltam a Timer 1-el, de nem sikerült... A Timer 0 viszont már foglalt.
(#) Zsolt2 válasza Droot hozzászólására (») Júl 22, 2015 /
 
Az azt jelentene, hogy minden 8. orajelre kene generaljon egy megszakitast (8Mhz periodusa 125nS; 1000/125=8). Ahhoz, hogy egy megszakitasba be tudjon lepni legalabb 4 orajelre van szukseg es ahhoz, hogy kilepjen a megszakitasbol szinten 4 orajelciklus szukseges (adatlap 16.o).
Idézet:
„The interrupt execution response for all the enabled Atmel®AVR® interrupts is four clock cycles minimum.
A return from an interrupt handling routine takes four clock cycles.”

Ezzel nem maradna tobb processzor ido semmi mas muveletnek.
A hozzászólás módosítva: Júl 22, 2015
(#) Droot válasza Zsolt2 hozzászólására (») Júl 22, 2015 /
 
Tehát az órajelet növelni kellene?
16MHz megoldható, átnéztem hozzá a többi részt is.
A hozzászólás módosítva: Júl 22, 2015
(#) Zsolt2 válasza Droot hozzászólására (») Júl 22, 2015 /
 
Eppen ellekezoleg, meg kene novelni, hogy a periodus csokkenjen, habar ugyis eleg szukosen fog kijonni, ha a maximalis 16Mhz-et hasznalsz.
(#) Droot válasza Zsolt2 hozzászólására (») Júl 22, 2015 /
 
Közben rájöttem hogy rosszul írtam és javítottam.
Van nagyobb kvarcom is, de az a kérdés, hogy meddig bírja az ATmega8. Én úgy tudom 16MHz a maximum.
(#) Zsolt2 válasza Droot hozzászólására (») Júl 22, 2015 /
 
Feljebb menni a megengedett frekvencianal nem ajanlott. En azt javasolom, hogy probalj meg mas megoldast keresni, ahol eleg nagyobb megszakitasi ido is, vagy valassz mas processzort.
(#) Droot válasza Zsolt2 hozzászólására (») Júl 22, 2015 /
 
Úgy tűnik jó a 16MHz-es kvarccal.
Több funkciója van az eszköznek, de egyszerre csak egy, és egy funkciónak nem nagy az erőforrás igénye. Így szerintem nem lesz gond, de le fogom tesztelni a végleges helyén is.

Szerk.: Tévedtem, valóban elfingja magát.
Egy négyütemű motor fordulatszámát méri ez a rész egyébként.
A hozzászólás módosítva: Júl 22, 2015
(#) killbill válasza Droot hozzászólására (») Júl 22, 2015 /
 
Egy motor fordulatszamat nem 1us megszakitassal kell merni, hanem a bejovo impulzusok kozotti ido meresevel. Ehhez eleg, ha csak a bejovo jel (mondjuk) lefutó éle kér megszakitast es te minden egyes alkalommal eltarolod a timer erteket, es kivonod a timer erteket az elozoleg eltarolt timer ertekbol. A kulonbseg a periodusido.
A hozzászólás módosítva: Júl 22, 2015
(#) Droot válasza killbill hozzászólására (») Júl 22, 2015 /
 
Egy példát találtam rá. Négyütemű motor és a gyújtásról veszi az impulzust.
Elvileg úgy működik, hogy megméri hogy az impulzusok között mennyi idő telik el és 12000-ret elosztja vele.
Van esetleg valami ötletetek?
(#) killbill válasza Droot hozzászólására (») Júl 22, 2015 /
 
Gyakorlatilag is ugy mukodik, hogy megmeri az impulzusok kozti idot. De ehhez nem kell 1us megszakitas. Az otletet meg fent. A gyujtas impulzus csinal megszakitast, es egy timerrel mered az eltelt idot. Kicsit szamolni kell mielott nekiallsz programozni. Mekkora a minimum es maximum ido? Ebbol kell kiindulni.
(#) Droot válasza killbill hozzászólására (») Júl 22, 2015 /
 
Példának egy már működőt néztem, de elég nagy baromságnak tűnt, de megpróbáltam az alapján elindulni, ami persze nem vezetett sehová.
Aztán elkezdtem gondolkozni, hogy 4 hengeres, ott a gyújtáselosztó, egy tengelyfordulaton 4 impulzust kap a 4 hengernek, és ezt végiggondolva már működik.
(#) killbill válasza Droot hozzászólására (») Júl 22, 2015 /
 
Szerintem egy fotengelyfordulatra ket gyujtas jut. A vezermutengely fele olyan gyorsan forog, mint a fotengely, es egy vezermu fordulat alatt negy gyujtas van.
(#) k3gy3tl3n hozzászólása Júl 22, 2015 /
 
Sziasztok, valamiért az alábbi kóddal meg sem tudom moccintani a szervóimat, kézzel simán tudom tekerni, még csak nem is egy helyben áll. Atmega48 uc-t használok, 8MHz órajelen megy és a PB1 lábat használom signalnak. Valakinek van ötlete?
  1. #include <avr/io.h>
  2. #include <util/delay.h>
  3. #include <avr/interrupt.h>
  4. #include <avr/wdt.h>        // Supplied Watch Dog Timer Macros
  5. #include <avr/sleep.h>      // Supplied AVR Sleep Macros
  6.  
  7.  
  8.  
  9. int main(void)  
  10. {
  11. int i;
  12.  
  13. // set pwm output (OC1A)
  14.    DDRB |= (1<<PB1); //mega8, 88
  15.  
  16. // set pwm mode 14
  17.    TCCR1A = (1<<WGM11);
  18.    TCCR1B = (1<<WGM12)|(1<<WGM13);
  19.  
  20. // set non-inverted output
  21.    TCCR1A |= (1<<COM1A1);
  22.  
  23. // set prescaler to 8  
  24.    TCCR1B |= (1<<CS11);
  25.  
  26. // set period = 20 ms  
  27.    // ICR1 = (F_CPU[MHz] * period[us]) / prescaler) - 1;
  28.    // ICR1 = (8 * 20000 / 8) - 1;
  29.    ICR1 = 19999;
  30.  
  31.    for(;;)
  32.    {
  33.  
  34.    //move servo to the center (pulse = 1.5 ms)
  35.       // OCR1A = (F_CPU[MHz] * pulse[us]) / prescaler) - 1;
  36.       // OCR1A = (8 * 1500) / 8) - 1;
  37.       OCR1A = 1500; //rounded
  38.        
  39.    //stay there for 2 seconds
  40.       _delay_ms(2000);
  41.  
  42.    //move servo to end position (pulse = 1 ms)
  43.       // OCR1A = (F_CPU[MHz] * pulse[us]) / prescaler) - 1;
  44.       // OCR1A = (8 * 1000) / 8) - 1;
  45.       OCR1A = 1000; //rounded
  46.  
  47.    //stay there for 2 seconds
  48.       _delay_ms(2000);
  49.  
  50.    //now move servo to the other end position (pulse = 2 ms)
  51.       // OCR1A = (F_CPU[MHz] * pulse[us]) / prescaler) - 1;
  52.       // OCR1A = (8 * 2000) / 8) - 1;
  53.       OCR1A = 2000; //rounded
  54.  
  55.    //stay there for 2 seconds
  56.       _delay_ms(2000);
  57.  
  58.    //move servo slowly from one end to the other
  59.       for (i=2000; i>=1000; i-=50)
  60.       {
  61.          OCR1A = i;
  62.          _delay_ms(100);
  63.       }
  64.       _delay_ms(2000);
  65.    }
  66. }
(#) Kovidivi válasza csabeszq hozzászólására (») Júl 22, 2015 /
 
Leírom a hiba valószínűsíthető okát, tanulságos:
A Timer2 ébreszti az AVR-t, ha az túlcsordul, az AVR felébred (8MHz-en megy, belső RC oszcillátorról), növeli a mp változót, majd ha nem nagyobb, mint 60, akkor szinte azonnal el megy aludni, mert más dolga nincs. Befejeződik a Timer2_OVF interrupt, viszont a Timer2 még nem lépett tovább (a 32768Hz-es kvarc sokkal lassabb), tehát még mindig 0-n van, és így újra fel lesz ébresztve az AVR. (Így működik az OVF interrupt? Amikor 0-n van a számláló, automatikusan meghívódik az ISR?) Az interrupt request ugye törlődik, amikor kilépünk a Timer2_OVF-ból, tehát a programon belüli interrupt kérés törlése elméletileg nem segítene.
Itt találtam az instrukciókat: Bővebben: Link , mégpedig:
  1. // WICHTIG!
  2.         // Wenn der Timer2 im asynchronen Modus periodisch zum Wecken aus dem Sleep Mode
  3.         // genutzt wird, dann muss vor dem Wiedereintritt mindestens
  4.         // 1 Oszillatortakt des Timers abgewartet werden (~30us), um die Interruptlogik
  5.         // wieder zu aktivieren, anderenfalls wacht der AVR nicht mehr auf.
  6.         // Die folgenden zwei Zeilen tun dies.
  7.         // Nur wenn sichergestellt ist, dass der Interrupt + Hauptschleife länger als 30µs dauern,
  8.         // kann man den Test weglassen

Vagyis: várni kell minimum 1 oszcillátor tick-et (órakvarcnál), mielőtt újra meghívódhatna az interrupt kb. 30uS (kiszámítható a kvarc és az előosztó alapján), különben nem ébred fel az AVR soha (vagy az én esetemben túl sűrűn ébredt fel). Ha az AVR ennél hosszabb ideig biztosan csinál valamit, akkor nem kell ezzel törődni.
Én most csak tesztként beraktam 100uS-nyi késleltetést, majd letesztelem, hogy mennyi a minimális.
Most jónak tűnik az időmérés, nem siet sehova az idő.
Ha valaki tudja, hogy miért kell várni, amíg lép egyet a számláló, az kérem írja le, kíváncsi vagyok. Köszönöm.
(#) csatti2 válasza k3gy3tl3n hozzászólására (») Júl 22, 2015 /
 
A kód jónak tűnik (én legalábbis nem látok hibát). Nézted szkóppal a kijövő jelet? Használtad már ezt a szervót máskor is? Próbáltad megnövelni a periódus időt 40-50ms-re?
(#) k3gy3tl3n válasza csatti2 hozzászólására (») Júl 22, 2015 /
 
Sajnos idehaza nincs szkópom. A szervó jó, melóban kipróbáltuk és tényleg működik 50Hz-es periódussal 1-2ms kitöltéssel ahogy az adatlap írja.
Szerk.: uc-t lecseréltem egy újra és már működik is...
A hozzászólás módosítva: Júl 22, 2015
(#) k3gy3tl3n válasza k3gy3tl3n hozzászólására (») Júl 22, 2015 /
 
Na sikerült az új uc-t is kifingatni. Rátettem a nagyobb szervót és kész. Már programozni sem lehet... Elsirom magam. A PWM lábra kell ellenállás?
A hozzászólás módosítva: Júl 22, 2015
(#) csatti2 válasza k3gy3tl3n hozzászólására (») Júl 22, 2015 /
 
Alapból nem kéne, de védelem miatt, ahol lehet érdemes áramkorlátozó ellenállásokat betenni.
(#) Kovidivi válasza Kovidivi hozzászólására (») Júl 22, 2015 /
 
Érdekes: Adatlap Atmega328 155. oldal.
Idézet:
„• If Timer/Counter2 is used to wake the device up from Power-save or ADC Noise Reduction
mode, precautions must be taken if the user wants to re-enter one of these modes: If reentering
sleep mode within the TOSC1 cycle, the interrupt will immidiately occur and the
device wake up again. The result is multiple interrupts and wake-ups within one TOSC1 cycle
from the first interrupt. If the user is in doubt whether the time before re-entering Power-save or
ADC Noise Reduction mode is sufficient, the following algorithm can be used to ensure that
one TOSC1 cycle has elapsed:
a. Write a value to TCCR2x, TCNT2, or OCR2x.
b. Wait until the corresponding Update Busy Flag in ASSR returns to zero.
c. Enter Power-save or ADC Noise Reduction mode.”
A hozzászólás módosítva: Júl 22, 2015
(#) k3gy3tl3n válasza csatti2 hozzászólására (») Júl 23, 2015 /
 
A PWM lábon egyébként lehet visszarúgás motor felől? Nem értem mitől fingott ki az AVR. Nem lehet közös tápról menetni az AVR-t meg a szervo-t?
(#) tursaba válasza k3gy3tl3n hozzászólására (») Júl 24, 2015 /
 
Szia ! A kis (9g) szervók induláskor felvehetnek 1 - 1.5 A-t is.
Ha a tápod nem tudja, okozhat meglepetéseket....
(#) Max26 válasza killbill hozzászólására (») Júl 26, 2015 /
 
Bevált, köszi.
(#) zsozsoX hozzászólása Júl 27, 2015 /
 
Sziasztok!
Atmega 8-al probálok meghajtani egy nokiából bontott lph7366-1 kijelzőt. Ha összerakom probapanelon be kötve a táp és az adat lábak is, a programozó hibát ír - nem tud kapcsolódni az uC-vel. A kijelzőt kiveszem oké a kapcsolat. Lehet az, hogy a kijelző kavar be, vagy rosszul kötöttem valamit?
(#) csatti2 válasza zsozsoX hozzászólására (») Júl 27, 2015 /
 
1, Feszültség problémák: az internet szerint ez a modul 3V3-as, annyiról hajtod a rendszert?
2, SPI jellegű kapcsolodása van. Az SPI lábakat használtad? Ha igen, tettél 1k körüli ellenállásokat a kijelző és a uC közé (hogy a programozód prioritást élvezzen a kijelzővel szemben) ?
3, Bármi egyéb. Kapcsolási rajz nélkül honnan tudjuk mit rontottál el?
(#) vzoole válasza zsozsoX hozzászólására (») Júl 27, 2015 /
 
Kijelző CS láb fel van húzva ellenállással?
(#) zsozsoX válasza vzoole hozzászólására (») Júl 27, 2015 /
 
A kijelző cs lába negativon van mert aktivra tettem, de csináltam úgy is hogy sehova nem volt kötve. Nincs köztük ellenálás, majd megpróbálom így is. Köszönöm a segítséget.
(#) csatti2 válasza zsozsoX hozzászólására (») Júl 27, 2015 /
 
A chip select lábat illene egy alapból felhúzó ellenállással bekötni, és a uC egyik lábával lehúzni, amikor szükséges. Ha folyamatosan aktív volt az IC és ugyanazokat a lábakat használod a programozódon és a kijelzőn is (SPI), akkor gyakorlatilag rövidrezártad az áramkört és örülhetsz ha nem szállt el...
(#) rolandgw hozzászólása Júl 27, 2015 / 1
 
Üdv!Ha valakit érdekel az assembly,letölthető ez a könyv,legjobb a témában.Kicsit macerás de lejön innen.
(#) Max26 hozzászólása Júl 29, 2015 /
 
Sziasztok!

Kb 30 perc futásidő után a programom megáll. A main.c-ben watchdog timer van. Tudom mire való a wdt.

Használok:

- UART kommunikációt
- I2C kommunikációt - Hőmérséklet, páratartalom, légnyomás mérést
- SD kártya loggolást
- 4x4 gombmátrixot
- LCD kijelzőt
- ADC lábat

Eddig SD kártya nélkül futott a hőmérséklet, légnyomás, páratartalom mérés. Működött az UART és LCD kommunikáció is megállás nélkül és nem használtam WDT-t.

Ha hozzáillesztem az eddigi projektemhez az SD kártya loggolást is(amiben már van WDT), akkor a program újraindul 30 perc után. Feltételezem a kód 30 perc alatt lelassul annyira, és a wdt életbe lép.

Ha SD kártya loggolást ( fájlokat feltöltöm csupa "a" betűvel) + UART kommunikációt tesztelem és a többi nincs benne a projektbe, akkor nincs reset.

Pontosan nem tudom megmondani, de az SD kártya illesztőprogramja használ interruptot és timert is ugyanazon a porton van nekem más is illesztve. Lehet ez játszik közre? Csatlotam a kapcs rajzot.

kapcs.png
    
Következő: »»   681 / 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