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   486 / 840
(#) sikolymester válasza blackdog hozzászólására (») Okt 8, 2012 /
 
Miből gondoltad ezt?
Sőt, ha már külön ref tápfeszt állítasz elő, akkor azt nem piszkálnám, mert a végén csak felesleges zavar kerül rá.

Tehát kössed ezt ugyanarra a tápra, amire az AVR van kötve.
Adatlapban is ilyen javaslatok vannak: Bővebben: Link
(#) Reggie válasza blackdog hozzászólására (») Okt 8, 2012 /
 
Az AVR AVCC labara kell kotni. Az AVR AVCC es a VCC laba ne legyen kozvetlen osszekotve, kozejuk tegyel induktivitast, hogy kevesebb zaj keruljon at.
(#) Fizikus válasza Sick-Bastard hozzászólására (») Okt 9, 2012 /
 
Kulso kristalyrol vagy a belso 8MHz-es oszcillatorrol megy az AVR?
Az orajel 8-al valo osztasa ki van kapcsolva (CLKDIV biztositekbit)?
(#) Sick-Bastard válasza Fizikus hozzászólására (») Okt 9, 2012 /
 
Üdv!

Egy külső 4MHz-es kristályról megy. (legalábbis úgy gondolom)
A biztosíték bitekhez nem hiszem, hogy hozzányúltam. Legalábbis szándékosan nem.

Amit módosítottam az a fenti kódban vastagon jelöltem.

Lehet, hogy a belső oszcillátort használom, miközben egy külső kristályt kötöttem az XTAL1 és XTAL2 lábakra... :S

Egy külső kristály használatához miket kell beállítani?
(#) sikolymester válasza Sick-Bastard hozzászólására (») Okt 9, 2012 /
 
Ha nem nyúltál a fuse bitekhez, akkor bizony belső oszcillátorról jár, mégpedig 1MHz sebességen.
Külső kristályhoz a megfelelő fuse biteket kell beállítanod.
Itt meg tudod nézni, hogy mit kell állítanod: Bővebben: Link
A hozzászólás módosítva: Okt 9, 2012
(#) zsozsoX hozzászólása Okt 9, 2012 /
 
Sziasztok
Atmega162-ben betudom állítani a két uart-ot különböző sebbességre?
(#) Sick-Bastard válasza sikolymester hozzászólására (») Okt 9, 2012 /
 
Igen megnéztem, tényleg belsőről megy a szerkezet.
A link még nem segített sokat, de az adatlappal együtt ha jól értelmezem.
A 8535-ös adatlapja 23-25. oldal alapján az órajel beállításához (külső kristály 1-16MHz között) ezeket kéne beírnom:
  1. CKOPT = 0
  2. CKSEL0 = 1
  3. CKSEL1 = 1
  4. CKSEL2 = 1
  5. CKSEL3 = 1
  6. SUT0 = 0
  7. SUT1 = 1
  8. + még
  9. SPIEN;BOOTSZ0;BOOTSZ1 ezek = 1

Az SPIEN ha jól értem az kell, hogy SPI-n keresztül lehessen felprogramozni, de a másik 2 nem tudom, hogy mit csinálnak, így hagyom őket is.
Az AVRDude-ba meg ezt kéne beírni:
  1. -U lfuse:w:0xd0:m -U hfuse:w:0xd9:m

Közel járok az igazsághoz?

A másik kérdésem, hogy ezt WinAVR-el hogyan tudnám beírni? Vagy csak AVRDude-al lehetne?
A hozzászólás módosítva: Okt 9, 2012
(#) zsolti002 hozzászólása Okt 9, 2012 /
 
Sziasztok. Szeretnék építeni egy olyan hőmérőt ami egyszerre négy helyről érzékeli a hőmérsékletet és egy kijelzőre teszi ki az értékeket. Ha valakinek esetleg lenne rajza egy ijenhez, az jólenne. Köszönöm előre is!.
(#) Sick-Bastard válasza Sick-Bastard hozzászólására (») Okt 9, 2012 /
 
Nos estére ezt hoztam össze:
  1. #include <avr/io.h>
  2.     #include <util/delay.h>
  3.         #include <avr/fuse.h>
  4.    
  5.     #define SPI_PORT PORTB
  6.     #define SPI_DDR  DDRB
  7.     #define SPI_74HC595_CS  PB4 // 74HC595 SPI-t aktivalo Chip Select lab
  8.     #define F_CPU 4000000UL // rendszer orajel: 4 MHz
  9.        
  10.         FUSES =
  11.         {
  12.                 (FUSE_BODLEVEL & FUSE_BODEN & FUSE_SUT0), // .low
  13.                 (FUSE_BOOTSZ0 & FUSE_BOOTSZ1 & FUSE_CKOPT & FUSE_SPIEN), // .high
  14.     };


Ez így helyes, működőképes?
Egy picit már zavarban vagyok, mivel az adatlapon volt egy ilyen megjegyzés:
Idézet:
„Note: 1. For all fuses “1” means unprogrammed while “0” means programmed.”

Tehát ha jól értem lényegében invertálva vannak itt a dolgok.
Amelyik fuse bit nekem kell azt nem 1-el hanem 0-val aktiválom, vagy rosszul gondolom?
(#) sikolymester válasza zsozsoX hozzászólására (») Okt 10, 2012 /
 
Igen.
(#) sikolymester válasza Sick-Bastard hozzászólására (») Okt 10, 2012 /
 
Az invertalas dolog igaz.
A honlapon kivalasztod az avr-ed utana egy ertheto feluleten latod, hogy milyen fuse beallitas mit eredmenyez.

En a helyedben ott megneznem ,hogy kulso kristalyra milyen erteket kell beirni, majd egy kozvetlen avrdude parancsot hivnek meg azzal a parameterrel. Bar igaz, hogy a fuse.h segitsegevel a forrasban is meg lehet adni fuse beallitasokat, de nekem azzal nincsen tapasztalatom. Nem tudom, hogy az nem invertalva lesz ahhoz kepest, amit igazabol is szeretnel. Masnak hatha van ezzel tapasztalata.
(#) Sick-Bastard válasza sikolymester hozzászólására (») Okt 10, 2012 /
 
Üdv!

Akkor az AVRDude-dal állítsam be a fuse biteket.

Inkább a belső oszcillátort emelem meg 8MHz-re így a próbapanelen a programozás is egyszerűbb lesz.

Ez a beállítás jo e? 8MHz belső + 4,1ms 6CK
  1. avrdude -dasa -P com1 -p m8535 -U lfuse:w:0xd4:m -U hfuse:w:0xd9:m
(#) sikolymester válasza Sick-Bastard hozzászólására (») Okt 10, 2012 /
 
Szerintem jó lesz.
(#) Sick-Bastard válasza sikolymester hozzászólására (») Okt 10, 2012 /
 
sikolymester és Fizikus köszönöm szépen a segítséget.
Még most sem olyan gyors mint a videóban, de jóval gyorsabb lett. Már csak a késleltetést kell csökkentenem és szerintem meg is van.

A következőkben az SPI-n való adat fogadást próbálom ki egy majd 2db 74HC597-el.
(#) imreke hozzászólása Okt 11, 2012 /
 
Sziasztok!

Azt szeretném megkérdezni, hogy atmega8-nál megoldható-e, hogy watchdog ébressze fel a power_down módú alvásból a vezérlőt, anélkül hogy reseteljen. (el kellene mentenem egy számlálót, mert csak kb 5 percenként kéne műveletet végezni és elemről menne)
(vagy felőlem resetelhet, csak a számláló értéke élje túl... eepromba írás nélkül)

Köszi: Imre
(#) Sick-Bastard hozzászólása Okt 11, 2012 /
 
Ismét én

Nos írtam egy kódot még tegnap este utolsó hozzászólásom után. Azt hittem nem működik jól, de csak én voltam az ostoba.

A kód így néz ki:
  1. #include <avr/io.h>
  2. #include <util/delay.h>
  3.  
  4. #define SPI_PORT PORTB
  5. #define SPI_DDR  DDRB
  6. #define CS0 PB4
  7. #define F_CPU 8000000UL
  8.  
  9. int main(void)
  10. {
  11.   SPI_DDR = (1<<PB7)|(1<<PB5)|(1<<PB4);
  12.   SPI_PORT &= ~(1<<CS0);
  13.   SPCR = (1<<SPE)|(1<<MSTR);
  14.   SPSR = (1<<SPI2X);
  15.   TCCR1B |= 1<<CS10 | 1<<CS11;
  16.   unsigned char adatbe_h;
  17.   unsigned char adatbe_l;
  18.  
  19.   while(1)
  20.         {
  21.                 if (TCNT1 > 30000)
  22.                 {
  23.                         TCNT1 = 0;
  24.                         SPI_PORT |= (1<<CS0);
  25.                         _delay_us(5);
  26.                         SPI_PORT &= ~(1<<CS0);
  27.                
  28.                         SPDR = 0x00;                                    // Adattranszfer elinditasa (MOSI)
  29.                         while(!(SPSR & (1<<SPIF)));     // Varakozas amig az adattranszfer befejezodik
  30.                
  31.                         adatbe_h = SPDR;                                // Beerkezett adat;
  32.                         SPDR = adatbe_h;                                // Adattranszfer elinditasa (MOSI)
  33.                         while(!(SPSR & (1<<SPIF)));     // Varakozas amig az adattranszfer befejezodik
  34.                
  35.                         adatbe_l = SPDR;                                // Beerkezett adat;
  36.                         SPDR = adatbe_l;                                // Adattranszfer elinditasa (MOSI)
  37.                         while(!(SPSR & (1<<SPIF)));     // Varakozas amig az adattranszfer befejezodik
  38.                
  39.                         SPI_PORT |= (1<<CS0);
  40.                         _delay_us(5);
  41.                         SPI_PORT &= ~(1<<CS0);
  42.                 }
  43.         }
  44. }


Ezt is szintén Fizikus által írt cikkből merítettem és módosítottam.

A lényege az adatok(16bit) SPI-n keresztül való beolvasása lenne. Szépen teszi a dolgát.
Annyi lenne a kérdésem, hogy ennél egyszerűbben is meg lehetne ezt oldani?

A másik dolog amit ki akarok próbálni az RTC (real time clock - valós idejű óra) használata.
Ezzel próbálkoztam:
  1. #include <avr/io.h>
  2. #include <util/delay.h>
  3.  
  4. #define SPI_PORT PORTB
  5. #define SPI_DDR  DDRB
  6. #define SPI_CS0 PB4
  7. #define F_CPU 8000000UL
  8.  
  9. void SPI_74HC595_Write(int dataout)
  10. {
  11.         SPI_PORT &= ~(1<<SPI_CS0);
  12.         _delay_us(1);
  13.         SPDR = dataout;
  14.         while(!(SPSR & (1<<SPIF)));
  15. }
  16. int main(void)
  17. {
  18.     SPI_DDR |= (1<<PB7)|(1<<PB5)|(1<<PB4);
  19.         SPCR |= (1<<SPE)|(1<<MSTR);
  20.         SPSR |= (1<<SPI2X);
  21.     SPI_PORT |= (1<<SPI_CS0);
  22.     SPI_74HC595_Write(0);
  23.         ASSR |= (1<<AS2);               // 0x08 (1<<AS2)
  24.         TCCR2 |= 0x0F;  // 0x0F (1<<CS20)|(1<<CS21)|(1<<CS22)|(1<<WGM21)
  25.         TCNT2 = 0x00;
  26.         OCR2 = 0x20;
  27.         TIMSK = (1<<OCIE2);
  28.         int LED[2];
  29.        
  30.         while(1)
  31.         {
  32.                 if (TCNT2 = 32)
  33.                 {
  34.                         TCNT2 = 0;
  35.                         SPI_74HC595_Write(1<<LED[0]);
  36.                         SPI_74HC595_Write(1<<LED[1]);
  37.                         SPI_PORT |= (1<<SPI_CS0);
  38.                         LED[0] ++;
  39.                         if (LED[0] > 7)
  40.                         {
  41.                                 LED[0] = 1;
  42.                                 SPI_74HC595_Write(1<<LED[0]);
  43.                                 SPI_74HC595_Write(1<<LED[1]);
  44.                                 SPI_PORT |= (1<<SPI_CS0);
  45.                                 LED[1] ++;
  46.                                 if (LED[1] >7)
  47.                                 LED[1] =1;
  48.                         }
  49.                 }
  50.         }
  51. }


A kód működik a TCNT1-el, de nem tudtom a regisztereket a TCNT2-höz beállítani...
(Aszinkron működés 32,768KHz-es kristállyal)

Egy link, vagy egy működő kód is megteszi, onnan már fel tudom fogni mi hogyan is van. (legalábbis azt hiszem google-n érthető kódot nem találtam)
(#) sikolymester válasza imreke hozzászólására (») Okt 11, 2012 /
 
Miért nem egy timert használsz erre?
Javaslom az adatlapban megnézni a "Power Management and Sleep Modes" részt.
(#) Suncorgo hozzászólása Okt 11, 2012 /
 
Sziasztok,

Atmel AVR studio6-ban szeretnék egy char tömböt deklarálni és globálisan elérhetővé tenni. Vagyis deklaráció a main fv kívül(és minden fv-en kívül):

  1. char[] str1= "Hello";
  2. char[] str2= "World!";


Ilyen hibaüzeneteket kapok rá:

Error 3 expected unqualified-id before '[' token
Error 4 expected unqualified-id before '[' token
Error 12 'str1' was not declared in this scope
Error 13 'str2' was not declared in this scope


A main fv végtelen ciklusa:

  1. while(1)
  2.         {
  3.                 Set_Cursor_1line;
  4.                 lcd_putstr(str1);
  5.                 Set_Cursor_2line;
  6.                 lcd_putstr(str2);
  7.                 dms(100);
  8.                 Clear_Home;    
  9.         }


Az lcd_putstr(char[]) fv írja vagyis írná ki a szöveget a kijelzőre. Ami működik is ilyen formában:

  1. lcd_putstr("Hello World!");


És itt az lcd_putstr fv:

  1. void lcd_putstr (char data[])
  2. {
  3.         int i=0;
  4.         while (data[i])
  5.         {
  6.                 sendLCD(data[i],0);             //adatkuldes
  7.                 i++;
  8.         }
  9. }



Miért nem jön létre a 2 tömb?
(#) thomas3 válasza Suncorgo hozzászólására (») Okt 11, 2012 / 1
 
Így a helyes:
  1. char str1[]= "Hello";
  2. char str2[]= "World!";
A hozzászólás módosítva: Okt 11, 2012
(#) imreke válasza sikolymester hozzászólására (») Okt 11, 2012 /
 
Szia!
Power down módból (ezt szeretném mindenképpen) csak a külső megsz.-ok ébresztik fel a cuccot, úgy tudom. (+TWI)
Viszont nekem az kéne hogy magától is megtegye ezt időközönként.
Minél kevesebb külső alkatrészt szeretnék.

Ezen az oldalon:
http://www.embedds.com/using-watchdog-timer-in-your-projects/
ez ragadta meg a figyelmem:
Watchdog Interrupt mode->
"...And there is a special case where watchdog can generate both: interrupt and system reset. By using this feature you may have ability to preserve valuable parameters before reset."

Ez kéne.

Imre
(#) sikolymester válasza imreke hozzászólására (») Okt 11, 2012 /
 
Hoppá, téves
Elnéztem egy sort én is a nagy igyekezetben. Csakugyan INT1 INT0 és TWI képes rá.

A watchdog ébresztéssel az a gond, hogy az mindenképpen kitöröl minden változót. Legalábbis a papírforma szerint.

szerk:

Elolvastam az említett részt.
Az adatlapban nincsen felsorolva a watchdog interrupt forrásként. Attól félek be kell érned a power save móddal.
A hozzászólás módosítva: Okt 11, 2012
(#) Suncorgo válasza thomas3 hozzászólására (») Okt 11, 2012 /
 
Úristen.... Ezt elnézni köszi
(#) imreke válasza sikolymester hozzászólására (») Okt 11, 2012 /
 
Köszönöm a gyors választ akkor még filózgatok a dolgon.....
(#) sikolymester válasza imreke hozzászólására (») Okt 11, 2012 /
 
Ha alacsony fogyasztás a cél, akkor kukkants rá at atmega88PA-ra.
Ha minden igaz, akkor lábkompatibilisek.
(#) Reggie válasza sikolymester hozzászólására (») Okt 11, 2012 /
 
A nem stackben levo valtozokat meg lehet menteni, csak at kell irni a gyari avr libc fuggvenyt, ami inicializalja a memoriat.
A hozzászólás módosítva: Okt 11, 2012
(#) sikolymester válasza Reggie hozzászólására (») Okt 11, 2012 /
 
Átnyálaztam az adatlapot és csakugyan.
Ez akkor remek hír imreke kollégának.
(#) Reggie válasza sikolymester hozzászólására (») Okt 11, 2012 /
 
Mondjuk kezdonek/kozephaladonak nem javaslom. Nagyon alaposan meg kell tervezni a szoftvert. Egyszerubb egy olyan tipust valasztani, ami tamogatja a WDT interruptot.
(#) Sick-Bastard válasza Sick-Bastard hozzászólására (») Okt 11, 2012 /
 
Nos erre jutottam, de sajnos ez sem működik.... Mi lehet a baj?
  1. #include <avr/io.h>
  2. #include <util/delay.h>
  3. #include <avr/interrupt.h>
  4.  
  5. #define SPI_PORT PORTB
  6. #define SPI_DDR  DDRB
  7. #define SPI_CS0 PB4
  8. #define F_CPU 8000000UL
  9.  
  10. int LED[2];
  11.  
  12. void SPI_74HC595_Write(int dataout)
  13. {
  14.         SPI_PORT &= ~(1<<SPI_CS0);
  15.         _delay_us(1);
  16.         SPDR = dataout;
  17.         while(!(SPSR & (1<<SPIF)));
  18. }
  19. int main(void)
  20. {
  21.     SPI_DDR |= (1<<PB7)|(1<<PB5)|(1<<PB4);
  22.         SPCR |= (1<<SPE)|(1<<MSTR);
  23.         SPSR |= (1<<SPI2X);
  24.     SPI_PORT |= (1<<SPI_CS0);
  25.     SPI_74HC595_Write(0);
  26.         ASSR |= (1<<AS2);               // 0x08 (1<<AS2)
  27.         TCCR2 |= 0x0F;  // 0x0F (1<<CS20)|(1<<CS21)|(1<<CS22)|(1<<WGM21)
  28.         OCR2 = 0x1F;
  29.         TIMSK = (1<<OCIE2);
  30.                
  31.         while(1)
  32.         {
  33.                 SPI_74HC595_Write(LED[0]);
  34.         SPI_74HC595_Write(LED[1]);
  35.         SPI_PORT |= (1<<SPI_CS0);
  36.         if (LED[0] > 7)
  37.         {
  38.             LED[0] = 1;
  39.             SPI_74HC595_Write(LED[0]);
  40.             SPI_74HC595_Write(LED[1]);
  41.             SPI_PORT |= (1<<SPI_CS0);
  42.             LED[1] ++;
  43.             if (LED[1] >7)
  44.             LED[1] =1;
  45.         }
  46.     }
  47. }
  48. ISR(TIMER2_COMP_vect)
  49.         {
  50.                 LED[0] ++;
  51.         }
(#) trudnai válasza Suncorgo hozzászólására (») Okt 12, 2012 /
 
Biztosan azert, mert ha pointerkent deklaralod, akkor a csillagocska a nev ele kerul:

  1. char *str1 = "Hello";
  2. char *str2 = "World!";
En amugy jobb szeretem igy megadni...
(#) icserny válasza Sick-Bastard hozzászólására (») Okt 12, 2012 /
 
  1. SPI_DDR |= (1<<PB7)|(1<<PB5)|(1<<PB4);


Az ilyen szörnyűségek elkerülésére definiálni lehetne a biteket így:
  1. #define BIT0                (0x0001)
  2. #define BIT1                (0x0002)
  3. #define BIT2                (0x0004)
  4. #define BIT3                (0x0008)
  5. #define BIT4                (0x0010)
  6. #define BIT5                (0x0020)
  7. #define BIT6                (0x0040)
  8. #define BIT7                (0x0080)


S akkor a fenti sor helyett ezt lehetne írni:
  1. SPI_DDR |= BIT7 | BIT5 | BIT4;

Következő: »»   486 / 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