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   695 / 840
(#) k3gy3tl3n válasza vyky hozzászólására (») Szept 25, 2015 / 1
 
Ahogy Kovidivi is írta, úgy elég szemléletes a kapcsolgatás. A kedvedért elrondítottam azt a kódot tessék:
  1. /*****************************************************************
  2. //  Fajlenev : 74HC595.c
  3. //  Verzio   : 1.0
  4. //  Leiras   : SPI hasznalata 74HC595 8-bites shift regiszterrel
  5. //  2011 Majus 14.
  6. ******************************************************************/
  7. #define F_CPU 7372800UL // rendszer orajel: 7.3728 MHz
  8.  
  9. #include <avr/io.h>
  10. #include <util/delay.h>
  11.  
  12. #define SPI_PORT PORTB
  13. #define SPI_DDR  DDRB
  14. #define SPI_74HC595_CS  PB2 // 74HC595 SPI-t aktivalo Chip Select lab
  15.  
  16.  
  17. void SPI_74HC595_Write(unsigned char adatki)
  18. {
  19.   // 74HC595 SPI bekapcsolasa (CS lab logikai alacsony szint)
  20.   SPI_PORT &= ~(1<<SPI_74HC595_CS);
  21.   _delay_us(1);
  22.   // Adattranszfer elinditasa (MOSI)
  23.   SPDR = adatki;
  24.   // Varakozas amig az adattranszfer befejezodik
  25.   while(!(SPSR & (1<<SPIF)));
  26.   // 74HC595 SPI kikapcsolasa, Latch kimenetek bekapcsolasa
  27.   SPI_PORT |= (1<<SPI_74HC595_CS);
  28. }
  29.  
  30. int main(void)
  31. {
  32.   unsigned char cnt;
  33.   // AVR ATMega8 SPI periferia beallitasa
  34.   // MOSI es SCK kimenet, a tobbi bemenet
  35.   SPI_DDR = (1<<PB3)|(1<<PB5)|(1<<PB2);
  36.   // SPI engedelyezese, Master mod, SPI orajel beallitasa
  37.   SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
  38.   // 74HC595 SPI kikapcsolasa, Latch kimenetek bekapcsolasa
  39.   SPI_PORT |= (1<<SPI_74HC595_CS);
  40.   // 74HC595 shift regiszter reszetelese
  41.   SPI_74HC595_Write(0);
  42.  
  43.   for(;;)
  44.   {
  45.         cnt=0b00000001;
  46.         SPI_74HC595_Write(cnt);
  47.         _delay_ms(500);
  48.  
  49.         cnt=0b00000011;
  50.         SPI_74HC595_Write(cnt);
  51.         _delay_ms(500);
  52.  
  53.         cnt=0b00000111;
  54.         SPI_74HC595_Write(cnt);
  55.         _delay_ms(500);
  56.  
  57.         cnt=0b00001111;
  58.         SPI_74HC595_Write(cnt);
  59.         _delay_ms(500);
  60.  
  61.         cnt=0b00011111;
  62.         SPI_74HC595_Write(cnt);
  63.         _delay_ms(500);
  64.  
  65.         cnt=0b00111111;
  66.         SPI_74HC595_Write(cnt);
  67.         _delay_ms(500);
  68.  
  69.         cnt=0b01111111;
  70.         SPI_74HC595_Write(cnt);
  71.         _delay_ms(500);
  72.  
  73.         cnt=0b11111111;
  74.         SPI_74HC595_Write(cnt);
  75.         _delay_ms(500);
  76.  
  77.         cnt=0b01111111;
  78.         SPI_74HC595_Write(cnt);
  79.         _delay_ms(500);
  80.  
  81.         cnt=0b00111111;
  82.         SPI_74HC595_Write(cnt);
  83.         _delay_ms(500);
  84.  
  85.         cnt=0b00011111;
  86.         SPI_74HC595_Write(cnt);
  87.         _delay_ms(500);
  88.  
  89.         cnt=0b00001111;
  90.         SPI_74HC595_Write(cnt);
  91.         _delay_ms(500);
  92.  
  93.         cnt=0b00000111;
  94.         SPI_74HC595_Write(cnt);
  95.         _delay_ms(500);
  96.  
  97.         cnt=0b00000011;
  98.         SPI_74HC595_Write(cnt);
  99.         _delay_ms(500);
  100.  
  101.         cnt=0b00000001;
  102.         SPI_74HC595_Write(cnt);
  103.         _delay_ms(500);
  104.  
  105.         cnt=0b00000000;
  106.         SPI_74HC595_Write(cnt);
  107.         _delay_ms(500);
  108.  
  109.   }
  110.   return 0;
  111. }
A hozzászólás módosítva: Szept 25, 2015
(#) vyky válasza k3gy3tl3n hozzászólására (») Szept 25, 2015 /
 
Köszönöm szépen.Tökéletes
(#) PIC hozzászólása Szept 25, 2015 /
 
Sziasztok!
Végső elkeseredésemre szeretnék egy kis segítséget kérni tőletek. AVR Atmega32-őt használok. Szeretném megoldani, hogy a sleep módból felkeljen a proci több perc alvás után. Külső interruptról már szépen működik, de a timer2-őt nem tudom úgy be konfigolni, hogy felébredjen magától egy idő elteltével. Watch Dog-ot nem szeretnék erre használni mert számolnia kell egy felfutó élt, tehát nem jó ha újraindul a proci. Rengeteg mintakódot néztem. Valaki csinált már ilyet? Segítsen valaki legyen szíves.
(#) Kovidivi válasza PIC hozzászólására (») Szept 25, 2015 /
 
A Watchdog ha jól tudom, nem csak resetelni tud, hanem simán interruptot hív meg, és ha kell, resetel is utána. Nézd meg az adatlapban, hogy melyik alvási módból tud a timer2 interrupt ébreszteni, mert vannak olyan lehetőségek, amikor nem ébreszt.
(#) rolandgw válasza PIC hozzászólására (») Szept 25, 2015 /
 
Melyik sleep módról van szó ?
(#) rolandgw válasza PIC hozzászólására (») Szept 25, 2015 /
 
Idle mód jöhet szóba és a power-save mód,de ez utóbbi csak akkor,ha a timer2 aszinkron módban van.
(#) Istvanpisti válasza PIC hozzászólására (») Szept 25, 2015 /
 
Szia!
A Timer2-ről csak aszinkron módban ébred fel, de ekkor 32,768kHzes kvarc kell a bemenetre és belső oszcillátorról kell járjon az eszköz. Ekkor max 8sec lehet az alvási periódus, mert 1024-es osztót lehet beállítani és az OVF miatt van még 256-os osztás. A uC leírásában nézd meg mire kell figyelni, mert elég háklis üzemmód, csak figyelni kell pár dologra. .
Az alábbi kód mutatja mit kell beállítani a timer beállításánál.

  1. void timer_init()
  2. {
  3.   ASSR|=(1<<AS2);      
  4.   OCR2A=0;
  5.   CNT2=0;
  6.   while(ASSR&0x07);
  7.   TCCR2A=0;
  8.   TCCR2B|=(1<<CS22)|(1<<CS20); //itt egy mp alvás után ébred fel 128 az osztó x 256-> 32.768
  9.        
  10.   TIMSK2|=(1<<TOIE2);
  11.   sei();
  12. }
  13.  
  14. int main(void)
  15. {
  16.   timer_init();
  17.   while(1)
  18.   {
  19.      ...//itt megy el aludni
  20.      set_sleep_mode(SLEEP_MODE_PWR_SAVE); //itt most éppen a Power-save módba megy aludni
  21.      sleep_mode();
  22.      ...//itt ébred fel
  23.  
  24.   }
  25. }
  26.  
  27. ISR(TIMER2_OVF_vect)   
  28. {
  29.         ....
  30. }
(#) PIC hozzászólása Szept 25, 2015 /
 
Köszönöm a sok infót mindenkinek! A PWR_SAVE módot szeretném használni mert nagyon lényeges a fogyasztás. A 8sec az még nekem kevés lenne, legalább egy percig kéne, hogy aludjon, majd utána felébredne mérne uart-on küldene adatokat és visszaaludna. Nem lehet, egy számlálóval valahogyan túllépni azt a 8sec-et?
(#) kapu48 válasza PIC hozzászólására (») Szept 26, 2015 1 /
 
Akkor felejtsd el a 8 Bites AVRt!

Használj inkább 32 Bites ARMot.
(#) Kovidivi válasza PIC hozzászólására (») Szept 26, 2015 /
 
Növelsz egy számlálót, utána egy if, ha nem igaz a feltétel, akkor alvás, ha igaz, akkor furhat a főprogram. Az a pár órajel nem fogyaszt sokat.
(#) PIC hozzászólása Szept 26, 2015 /
 
Máris kipróbálom a számlálót! De előtte felvázolom, hogy mi ez tulajdonképpen, és akkor jobban képbe lesz mindenki. Ez egy időjárás állomás lelke lesz ami méri a szélsebességet, szélirányt, esőmennyiséget, relatív páratartalmat, légköri nyomást, levegő hőmérsékletet, talajhőmérsékletet, és megvilágítást ir és látható tartományban. Ezeket az adatokat leméri a proci aztán alszik egy percet. Eközben a szélsebesség és az esőmennyiség mérőktől ha jön jel akkor az külső megszakításként kezelném felkelne növelne egy változót és visszaaludna. Hiszen ha alvás közben fúj a szél akkor is kell mérni. Ezeket az infókat vezeték nélkül elküldi egy ARM-nak (STM32F4 Discovery Board) ami színes érintős TFT-vel velfegyverkezve várja az adatokat, hogy szépen kirajzolhasson karakterisztikákat és egyéb dolgokat "jósoljon"
Az AVR egyszerűsége miatt (és azért mert a lux-mérőn kívül minden szenzor kész kb.) használnám egy kis napelemes akkumulátoros modullal. Csak tényleg altatni kéne a procit mert akkor 6uA-t eszik méréseim szerint. Vezeték nélküli modulnak is egy 3,3V-os RFM modult használok ami pár 10mA-t vesz fel csak küldésnél egy pillanatra.

Szóval máris tesztelem először a 8sec-es felébredést, aztán majd bővítjük. Először csak szép lssan ahogy írtátok megpróbálom megcsinálni. Először is a 20MHz-s kvarcot levettem, helyére raktam egy órakvarcot. Átállítottam a FUSE biteket gyári állapotra. (belső 1MHz 64ms-os indulási késleltetéssel). Ezek után ha asszinkron módba állítom stb.. akkor működni fog a kód amit Istvanpisti bemásolt. Remélem. Hamarosan jelentkezem, remélem jó hírekkel
(#) PIC hozzászólása Szept 26, 2015 /
 
Egyelőre nem túl sok siker élményem van. Az xtal1 és xtal2-re most egy órakvarcot tettem, fuse bitek jól vannak beállítva szerintem. Mellékeltem egy képet amin mutatom, hogy van beállítva. (csak szimulátor de meg tudom nézni a hex-ből hogy mit takar). A LED nem villog szerintem az a gond hogy más regiszterek vannak ebben a prociban.

  1. #define F_CPU                   32768UL
  2. #include <util/delay.h>
  3. #include <avr/io.h>
  4. #include <avr/sleep.h>
  5. #include <avr/power.h>
  6. #include <avr/interrupt.h>
  7.  
  8. ISR(TIMER2_OVF_vect)
  9. {
  10.         PORTD ^= (1<<PD0);
  11. }
  12.  
  13. int main(void)
  14. {
  15.         DDRD |= (1<<PD0) | (1<<PD1);    //Teszt LED-ek
  16.         PORTD &= ~(1<<PD0);
  17.         PORTD &= ~(1<<PD1);
  18.  
  19.        
  20.         ASSR|=(1<<AS2);
  21.         OCR2=0;
  22.         TCNT2=0;
  23.         while(ASSR&AS2);
  24.         TCCR2=0;
  25.         TCCR2|=(1<<CS22)|(1<<CS20); //itt egy mp alvás után ébred fel 128 az osztó x 256-> 32.768
  26.        
  27.         TIMSK|=(1<<TOIE2);
  28.         sei();
  29.            
  30.         while(1)
  31.         {
  32.                  set_sleep_mode(SLEEP_MODE_PWR_SAVE); //itt most éppen a Power-save módba megy aludni
  33.                  sleep_mode();
  34.                  
  35.                  
  36.                  
  37.         }
  38. }


Próbáltam másképpen is, hogy több mindent beállítok pl sei(); cli(); látom sok mintakódban de akkor sem jó. :/ Szerintetek?

fuses.jpg
    
(#) Istvanpisti válasza PIC hozzászólására (») Szept 26, 2015 /
 
Szia!
Az F_CPU=1000000 legyen, mert a kontroller 1 MHz-ről jár.
A sleep_mode(); sor után kellene valami kis késleltetés, mert a leírás írja, hogy legalább egy órajelnyi időnek (a TIMER2 órajeléről van szó, ami 32,768kHz) el kell telni a felébredés és az újra elalvás után, különben sosem ébred fel. Erre írtam, hogy egy kicsit háklis üzemmód.
Ez lehet pl._delay_ms(10);, vagy ez a három sor a sleep_mode(); sor után.
  1. OCR2=0;
  2. TCNT2=0;
  3. while(ASSR&AS2);
A hozzászólás módosítva: Szept 26, 2015
(#) PIC válasza Istvanpisti hozzászólására (») Szept 26, 2015 /
 
Ha kikapcsolom a sleep-et és a while-t ahol írtam, akkor fut csak a főprogram while-ja. Mellékeltem egy mérést amin látszik a PORTD0 és PORTD1.
A TCCR2A és TCCR2B regiszterek nincsenek meg ebben az avr-ben ahelyett TCCR2-őt írtam. Szerintem ez is lehet probléma.

  1. #define F_CPU 1000000UL
  2. #include <util/delay.h>
  3. #include <avr/io.h>
  4. #include <avr/sleep.h>
  5. #include <avr/power.h>
  6. #include <avr/interrupt.h>
  7.  
  8. ISR(TIMER2_OVF_vect)
  9. {
  10.         PORTD ^= (1<<PD0);
  11. }
  12.  
  13. int main(void)
  14. {
  15.         DDRD |= (1<<PD0) | (1<<PD1);    //Teszt LED-ek
  16.         PORTD &= ~(1<<PD0);
  17.         PORTD &= ~(1<<PD1);
  18.  
  19.        
  20.         ASSR|=(1<<AS2);
  21.         OCR2=0;
  22.         TCNT2=0;
  23. //      while(ASSR&AS2);        //itt megakad
  24.         TCCR2=0;
  25.         TCCR2|=(1<<CS22)|(1<<CS20); //128 az osztó x 256-> 32.768
  26.        
  27.         TIMSK|=(1<<TOIE2);
  28.         sei();
  29.        
  30.         _delay_ms(40);
  31.          
  32.                 while(1)
  33.                 {
  34.                         set_sleep_mode(SLEEP_MODE_PWR_SAVE); //itt most éppen a Power-save módba megy aludni
  35.                 //      sleep_enable();
  36.                 //      sleep_mode();
  37.                 //      sleep_disable();
  38.                
  39.                         _delay_ms(20);
  40.                         PORTD ^= (1<<PD1);
  41.                 }
  42. }

logic.jpg
    
(#) Kovidivi válasza Istvanpisti hozzászólására (») Szept 26, 2015 /
 
Én ezt úgy küszöböltem ki, hogy várok, amíg a TCNT2=0. Amint átvált, már megyek is aludni. Előtte mindent elvégzek, amit kell.
(#) Kovidivi válasza PIC hozzászólására (») Szept 26, 2015 /
 
A set_sleep_mode nem biztos, hogy elküldi aludni a procit, az csak beállítja az alvás módját. Az igazi altató parancs a sleep_mode(); . Kikapcsolni sem kell a sleep_disable(); -vel, ez automatikusan megtörténik, amint lefut egy interrupt. Tehát minden mp-ben, amikor a Timer2 felébreszti. Én így altatok a leggyorsabban:
  1. while(aludni_kell)
  2. {
  3. while (TCNT2==0) {;} //megvárjuk amíg elhalad a változó a 0-ról.
  4. sleep_mode(); //elküldjük aludni
  5. // itt ébredek fel. Ha nem lett az aludni_kell változó nullázva, akkor a
  6. // while újra kezdődik, és amint lehet, alszok.
  7. }
  8. //ide pedig jöhet a programkód, ami ébredés után lefut azonnal.
A hozzászólás módosítva: Szept 26, 2015
(#) PIC válasza Kovidivi hozzászólására (») Szept 26, 2015 /
 
Értem amit mondasz de sajnos a ISR(TIMER2_OVF_vect) sem fut már le ha kikapcsolom a sleep dolgokat akkor se. Van valami a timer beállításánál amit kifelejtek de nem jövök rá hogy mit..
Ha sikerül elindítanom sleep nélkül akkor kipróbálom ahogy mondtad.
A hozzászólás módosítva: Szept 26, 2015
(#) Istvanpisti válasza PIC hozzászólására (») Szept 26, 2015 /
 
Lehet, hogy nem megy az órakvarccal a TIMER2. Én is jártam már így, kipróbáltam többet, míg megoldódott.
Raktál-e rá kondenzátorokat a kvarc ás a föld közé?
(#) PIC válasza Istvanpisti hozzászólására (») Szept 26, 2015 /
 
Igen van két 22pF-os kondi. És nem próbapanelen csinálom hanem, egy saját minimum board-on szóval az érintkezési hiba is kizárva. Viszont gyanús hogy a kvarc lábain nem mérek frekit. Viszont ha ugyan azt a kvarcot átteszem egy elemes gyári rtc modulra akkor ott simán mérhető a 32kHz. Nem hiszem hogy a 22pF sok lenne. A legvalószínűbbnek én is azt látom, hogy nem megy a kvarc miatt, hiszen nincs órajele. Ugyan úgy kell rákötni mintha egy normál kvarcot kötnék?
(#) Istvanpisti válasza PIC hozzászólására (») Szept 26, 2015 / 1
 
Azt írja a doksi, hogy nem szükséges ilyenkor külső kapacitás.
(#) Kovidivi válasza Istvanpisti hozzászólására (») Szept 26, 2015 /
 
Emiatt be sem indul a rezgés. Így van.
(#) PIC válasza Kovidivi hozzászólására (») Szept 26, 2015 /
 
Leforrasztottam a kondikat, és direktbe ráforrasztottam a kvarcot a panelre (eddig precíziós tüske volt hogy cserélhető legyen, de most nem bíztam Mörfire). Az eredmény egyelőre ugyan az. Arra jöttem még rá, hogy ha assinkron módba van a proci akkor a timer2 megáll. Ha nem kapcsolom át assinkronra akkor megy mindkét timer és a while-is szépen fut.
(#) Istvanpisti válasza PIC hozzászólására (») Szept 26, 2015 /
 
Találtam még valamit. Bár ettől csak az interrupttal lesz baj, de az oszcillátornak menni kellene.
(#) rolandgw válasza PIC hozzászólására (») Szept 26, 2015 /
 
Ezt érdemes lenne kipróbálni,csak pár regiszternevet kell módosítani.
(#) Sick-Bastard válasza PIC hozzászólására (») Szept 26, 2015 /
 
Üdv!
PIC írta:
Idézet:
„Sziasztok!
Végső elkeseredésemre szeretnék egy kis segítséget kérni tőletek. AVR Atmega32-őt használok.”

Idézet:
„Az xtal1 és xtal2-re most egy órakvarcot tettem,”


Ha atmega32-ről van szó, akkor a 32,768Hz-es kristálynak az xtal1/2 helyett nem a TOSC1/2 lábakon kellene lennie?
A hozzászólás módosítva: Szept 26, 2015
(#) Sick-Bastard válasza Sick-Bastard hozzászólására (») Szept 26, 2015 /
 
PIC:
Idézet:
„Arra jöttem még rá, hogy ha assinkron módba van a proci akkor a timer2 megáll. Ha nem kapcsolom át assinkronra akkor megy mindkét timer és a while-is szépen fut.”


Ez is erősíti a gyanúmat, hogy rossz helyen van a kristály.
(#) rolandgw hozzászólása Szept 26, 2015 /
 
Kijött a studio 7.Jól gurul,szelektív lett a telepítés ,érdemes váltani.
(#) Istvanpisti válasza Sick-Bastard hozzászólására (») Szept 26, 2015 /
 
Igazad van, ez lehet a baj.
(#) PIC válasza Sick-Bastard hozzászólására (») Szept 27, 2015 /
 
Jó híreim vannak. Átraktam a kvarcot és a kvarc lábán gyönyörűen ott van az órajel
Még jobb ezek után működött egyből a kód sleep-móddal együtt... Úgyh mindenkinek nagyon köszönöm a segítséget, most nagyon örülök Megígérem hogy még elvileg ma, ha megírom szépen a kódot, hogy mondjuk 8sec-ig sleep-módban legyen akkor mellékelem a kódomat ÉS a kapcsrajzot fuse bitekkel... Csak mert tudom milyen segítség ha épp valaki ilyesmit szeretne csinálni mint én. Estefele jelentkezem, most sajnos kicsit el kell mennem de inkább elkések de ezt meg akartam nézni. Megérte
Szép napot mindenkinek!

muxik.jpg
    
(#) roland8811 hozzászólása Szept 27, 2015 /
 
Sziasztok.
Van 1 mápna pc , 1 atmega 328-pu . 3.3v kap a málnáról.

És 1 höérzékelő , ami valamiért többet mér mint kellene.

Ha 5 v kötöm az avr-t. Uart ugyanúgy 3,3 v fog komunikálni?
( Txd Rxd )

Vagy ellenálásozni kell?
Következő: »»   695 / 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