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   489 / 840
(#) Reggie válasza Jáger László hozzászólására (») Okt 21, 2012 /
 
Nem fog menni, mert megvaltozott nehany dolog(pl. nehany bit elnevezese egyes regiszterekben).
Ez a migracios doksi, ami alapjan at kell irnod a kodot. Azert nem veszes, a nagyresze search&replace muvelettel megoldhato.
(#) Jáger László válasza Reggie hozzászólására (») Okt 21, 2012 /
 
Köszönöm! Még egy kérdés, a fenti *.c kiterjesztésű fájlt melyik programmal tudom szerkeszteni? AVR Studio?
(#) ZsoltyFM hozzászólása Okt 21, 2012 /
 
sziasztok!
egy kis segítségre lenne szükségem. mégpedig egy attiny2313-al kapcsolatban.
írtam egy igen egyszerű kis progit pic16f628-ra, és az a problémám hogy ott sehogy nem tudok megoldani egy kis időzítési problémát. aki ismeri a pic-eknél a goto utasítást azt tudja hogy a végrehajtása 8 órajejet emészt fel. a feladat egészen pontosan az lenne hogy egy 8 bites portra tetszőleges állapotokat írjak ki. viszont az is fontos lenne hogy az állapotfrissítések közt mindig ugyanannyi legyen az idő. és az értékeket újból az elejéről kezdve kellene a portra kiíratni
a pic-nél sajnos a lista elejére való ugráskor, a goto miatt az állapotfrissítések közt kétszer annyi idő telik el mint amennyi kellene. Még mielőtt azt a bölcs javaslatot kapnám hogy használjak dupla frekijű kavicsot. NINCS !!!
(#) blackdog válasza ZsoltyFM hozzászólására (») Okt 21, 2012 /
 
Egyáltalán nem ismerem a PIC lelkivilágát, de nem állhat messze az AVR-től. Gondolom a működési logika hasonló.
A lényeg, ha az időzítést a főprogramban kezeled akkor nem jársz sikerrel. A TIMER megszakítás segíthet neked. Okosabbat majd mondanak az okosabbak nekem ez az észrevételem.
(#) ZsoltyFM hozzászólása Okt 21, 2012 /
 
a megszakítás nekem is megfordult a fejembe de sajnos nincs idő sem rá hogy folyamatában lekezeljem.
(#) zolee1209 válasza ZsoltyFM hozzászólására (») Okt 21, 2012 /
 
Bár nem ismerem a kívánt pontos működést, így ennyiből nem mondanám, hogy az AVR-re való áttérés az egyetlen megoldás...
(#) zolee1209 válasza ZsoltyFM hozzászólására (») Okt 21, 2012 /
 
Szakadozik a wifi, duplapostolok már megint... :@
A hozzászólás módosítva: Okt 21, 2012
(#) ZsoltyFM hozzászólása Okt 21, 2012 /
 
akkor közlöm a lényeget a pic nél ahhoz hogy az ugrással együtt kitegyem a portra az új értéket 16 órajelnek kell minimum eltelnie. azt hiszem hogy az avr-nél ez az idő lerövidülne .
(#) blackdog hozzászólása Okt 21, 2012 /
 
Sziasztok!

Szabadon marad egy ADC portom és nem tudtam mit kezdjek vele. Végül találtam neki feladatot.
A kapcsolásomba végülis egy DS3107 RTC IC került. Ennek van battery lába.
Az ADC-t arra szeretném használni, hogy figyeljem a 3V elem feszültségét. És itt elbizonytalanodtam. Ezt a 3V feszültséget köthetem közvetlen az ADC lábra vagy itt is kell feszültség osztást használnom? Az ADC referencia 5V.
(#) benjami válasza ZsoltyFM hozzászólására (») Okt 21, 2012 /
 
Ha videojelet akarsz előállítani akkor itt van némi minta.
AVR: Uzebox
PIC: Video game wirh PIC18
(#) Sick-Bastard hozzászólása Okt 21, 2012 /
 
Üdv!

Egy kis segítséget szeretnék kérni interrupt ügyben.

AVR-rel szeretnék mint óra használni, amihez egy 32,678kHz-es kristályt használnék a TOSC1/2 lábakon. A TCNT2 és a OCR2 összehasonlításával mérnék 1mp-et. Amikor ezt elérné, akkor beugrik az interruptba, aminek annyi lenne a feladat, hogy egy integernek az értéket növelje meg 1-el. Na itt akadtam el.
interrupt rutin:
  1. ISR(TIMER2_COMP_vect)
  2. {
  3. PORTB ^= 1<<PINB0;      
  4. sec++;
  5. }


Egy nem használt lábra raktam egy ledet, hogy lássam történik e valami. Igen a led villog, ahogy kell.

Lehet hogy az a hiba, hogy az eredeti kódban array-ben használtam a set-et? Valahogy így:

  1. ISR(TIMER2_COMP_vect)
  2. {
  3. PORTB ^= 1<<PINB0;      
  4. sec[0]++;
  5. }
(#) ZsoltyFM válasza (Felhasználó 15355) hozzászólására (») Okt 21, 2012 /
 
igazad van! ezzel én is tisztában vagyok, viszont én ezt ismerem inkább. ezt be tudom programozni. meg hát assembly-ben tudok csak programot írni. és a 16f-es családról vannak inkább információim magyarul. pll-t nem akartam használni és mivel tudom hogy ez a problémám megoldódna egy egyszerűbb attiny2313-al is. mellékesen abból van is egy.
mivel itt sokan vagytok akik avr-ekkel foglalkoztok,bíztam abban hogy segítséget kapok a kitűzött célommal kapcsolatban. de ti már megint csak ötletekkel dobálóztok és nem abban kapok segítséget amiben kérek. ezt ne vedd magadra általánosságban ez a szokás. mivel más nem ismeri az egyébb okokat. szóval rőviden nekem csak egy sablon progira lenne szükségem erre a procira azaz egy sablon kell configokkal együtt ahová nekem mondhatni csak be kell illesztenem azokat az értékeket amiket én ki szeretnék iratni a portra.
(#) fekete123 hozzászólása Okt 21, 2012 /
 
Üdv!

Atmega32A-PU-n próbálok soros kommunikációt létrehozni interrupt-al ennek a tutorialnak a segítségével:
Bővebben: Link Belső 8MHz-es órajelet használok, tudom ez nem feltétlen elég pontos ehhez, de értelmezésem szerint max az történne hogy hibás adatok mennek át.

AVR Studio6-ot használok, ahol mindig kiválasztom íráskor hogy 32A. Ez az egy program azonban csak akkor hajlandó működni ha sima 32-őt választok. 32A-t választva mintha egy végtelen ciklusba kerülne, és semmit nem csinál miután az első adatot megkapta és vissza kéne küldenie.

Tud valaki valamit mondani arról hogy a 32 és 32A-pu között mi a különbség? Az ATMEL oldalán nem találtam olyat ami ezt magyarázná.
(#) sikolymester válasza Sick-Bastard hozzászólására (») Okt 22, 2012 /
 
A sec változód definiáld volatile-nak.
Máskülönben kioptimalizálja a fordítód. Magyarul: nem futtatja le.
(#) sikolymester válasza fekete123 hozzászólására (») Okt 22, 2012 /
 
Az AtmegaXX és AtmegaXXA (XX tetszőleges típus) között csak szilikon revízió különbség van. Teljesen kompatibilisnek kellene lenniük.
Honnan tudod, hogy végtelen ciklusba kerül? Valamilyen debuggert használsz? Vagy egyéb módon következtetted ki?

Azt tudod, hogy mire kerül végtelen ciklusba? Ha igen, akkor azt a kód részletet postold be.
(#) blackdog válasza Sick-Bastard hozzászólására (») Okt 22, 2012 /
 
Szia!

Én a következő képpen használom, hogy órám legyen. Nálam 16 MHz az órajel.
  1. #ifndef F_CPU
  2. #define F_CPU 16000000UL
  3. #endif
  4.  
  5. //......
  6.  
  7.  
  8. unsigned char hours = 0;
  9. unsigned char minutes = 0;
  10. unsigned char seconds = 0;
  11.  
  12. //......
  13.  
  14. char ido[10];
  15. char buffer[7];
  16. char *digit_string(uint16_t digits)
  17. {
  18.         if (digits == 0)
  19.                 return "00";
  20.         else if (digits < 10) {
  21.                 utoa(digits, buffer, 10);
  22.  
  23.                 buffer[1] = buffer[0];
  24.                 buffer[0] = '0';
  25.                 buffer[2] = '\0';
  26.                 return buffer;
  27.         }
  28.         else
  29.                 return utoa(digits, buffer, 10);
  30. }
  31.  
  32. void LCD_update_time()
  33. {
  34.  
  35. lcd_gotoxy(7,3);
  36.  
  37. lcd_puts(digit_string(hours));
  38. lcd_putc(':');
  39. lcd_puts(digit_string(minutes));
  40. lcd_putc(':');
  41. lcd_puts(digit_string(seconds));
  42.  
  43. }
  44.  
  45. //.......
  46.  
  47. int main(void) {
  48.  
  49. // alapbeállítások....
  50.  
  51. TIMSK1=0x01;
  52. TCCR1A = 0x00;
  53. TCNT1=0x0BDC;
  54. TCCR1B = 0x04;
  55.  
  56. sei();
  57.  
  58. while (1) {
  59.    // főprogram
  60. }
  61. }
  62.  
  63.  
  64. ISR(TIMER1_OVF_vect)
  65. {              
  66.               TCNT1=0x0BDC;
  67.         seconds++;
  68.  
  69.         if(seconds == 60)
  70.         {
  71.                 seconds = 0;
  72.                 minutes++;
  73.                        
  74.         }
  75.         if(minutes == 60)
  76.         {
  77.                 minutes = 0;
  78.                 hours++;               
  79.         }
  80.         if(hours > 23)
  81.                 hours = 0;
  82.  
  83.         LCD_update_time();
  84.  
  85. }


Remélem nem hagytam ki semmit. Amúgy most térek át RTC IC használatára. Konkrétan DS1307.
(#) blackdog válasza blackdog hozzászólására (») Okt 22, 2012 /
 
Nos közben arra gondoltam, hogy jobb, ha teszek be osztást pl. 100k+220k így 3,3V elemfeszültség esetén 512-t mérek. Gyakorlatilag 0-512 között kell számolnom.
Úgy gondolom, hogy ennek alapvetően nincs jelentőssége csak talán a kódolás lesz könyebb/áttekinthetőbb.
Mivel 5V a referencia így köthetném direkt is az elemet, de maceránsabbnak érzem a kódolást.
Mi a véleményetek?
(#) Reggie válasza Jáger László hozzászólására (») Okt 22, 2012 /
 
Barmivel tudod szerkeszteni, de a leforditashoz kelleni fog az AVR Studio es a Toolchain is.
(#) Reggie válasza ZsoltyFM hozzászólására (») Okt 22, 2012 /
 
Igazabol azert nem adott senki sem ertelmes valaszt, mert elmondod, hogy mi a problema, de azt nem, hogy konkretan milyen segitseget varnal.
(#) fekete123 válasza sikolymester hozzászólására (») Okt 22, 2012 /
 
Köszönöm az infót!

Nem biztos hogy jól fogalmaztam a végtelen ciklussal. 1 Atmega 32A-PU-m van, a másik (sima 32) ISIS-ben fut, vagy mindkettő ISIS-ben, teljesen mindegy a végeredmény ugyan az.

Az egyik interrupt-al fogadja a másik által elküldött jelet.

Adó ilyen formán:
  1. void USART_Transmit( unsigned char data )       //155. oldal
  2. {
  3.         /* Wait for empty transmit buffer */
  4.         while ( !( UCSRA & (1<<UDRE)) )
  5.         ;
  6.         /* Put data into buffer, sends the data */
  7.         UDR = data;
  8. }


A vevő így:
  1. #include <avr/delay.h>
  2. #include <avr/io.h>
  3. #include <avr/interrupt.h>
  4. #define F_CPU 8000000UL
  5. #define USART_BAUDRATE 9600
  6. #define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
  7.  
  8. int main (void)
  9. {
  10.         DDRA = 0xff;
  11.         UCSRB |= (1 << RXEN) | (1 << TXEN);   // Turn on the transmission and reception circuitry
  12.         UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1); // Use 8-bit character sizes
  13.  
  14.         UBRRH = (BAUD_PRESCALE >> 8); // Load upper 8-bits of the baud rate value into the high byte of the UBRR register
  15.         UBRRL = BAUD_PRESCALE; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register
  16.  
  17.         UCSRB |= (1 << RXCIE); // Enable the USART Recieve Complete interrupt (USART_RXC)
  18.         sei(); // Enable the Global Interrupt Enable flag so that interrupts can be processed
  19.  
  20.        
  21.         for (;;) // Loop forever
  22.         {
  23.                
  24.         }
  25. }
  26.  
  27. ISR(USART_RXC_vect)
  28. {
  29.         char ReceivedByte;
  30.         ReceivedByte = UDR; // Fetch the received byte value into the variable "ByteReceived"
  31.                                                 //      UDR = ReceivedByte; // Echo back the received byte back to the computer
  32.         _delay_ms(1000);
  33.         PORTA ^=1<<2;
  34. }


Ha a vevő 32-es beállítással van lefordítva akkor minden tökéletes, villog a ledem ha bejön az adat, még akkor is ha rossz BAUD-ot állítok be ha viszont 32A beállítással fordítom le akkor csak az első pár utasítás hajtódik végre (tehát ha ott kapcsolok ki-be egy-egy portot azt még látom), gondolom addig amíg az első adat be nem érkezik. És ami a ISR alatt van utasítás azokból semmi nem hajtódik végre.

Debuggert nem használok, nem rég óta próbálkozok csak ilyesmivel, lényegében arra voltam kíváncsi lehet e hátránya annak ha 32-őt állítok be 32A helyett
A hozzászólás módosítva: Okt 22, 2012
(#) ZsoltyFM válasza Reggie hozzászólására (») Okt 22, 2012 /
 
hello!
Úgy véltem hogy a legelső bejegyzésem elég információt ad arról mit is szeretnék.
Mivel azt nem várom el senkitől hogy megírja helyettem a programot, ezért nem is mentem bele a részletekbe hiszen felesleges és csak körítést tennék a lényeg köré.
Nekem csak egy 8 bites érték kiírás kell a portra. ami olyan 32 lépésből áll. Ami ha lejár
újból elölről kezdődik. És sima számláló léptetéssel nem valósítható meg, mert semmiféle rendszere nincs a kiíratandó értékeknek. De akkor leírok kicsit még többet
2 független feladatot kell ellátnom vele. 3 bit-en egy multiplexert vezérlek, 5 biten
vele szoros szinkronban egy szinuszt rajzolok ki ellenálláslétrával és fontos a szinkron ezért kell mindezt egy porton megoldani.
(#) Reggie válasza ZsoltyFM hozzászólására (») Okt 22, 2012 /
 
Az utasitasok idoigenye:
ugras 2
adatbetoltes memoriabol regiszterbe 2
adatbetoltes kozvetlenul(utasitasbol) regiszterbe 1
regiszter kiirasa a portra 1
nop 1

Sorrendben ezek az utasitasok:
jmp cim
ld regiszter,memoriacim
ldi regiszter,adat
out portcim,regiszter
nop

A lyukakat ertelemszeruen nop-pal kell kitolteni.
(#) ZsoltyFM válasza Reggie hozzászólására (») Okt 22, 2012 /
 
kb ilyesmire van szükségem.
A legfőbb problémám a konfiguráció, mivel nem igazán tudok sok mindent az attiny2313-ról.
minden portlábát szeretném kimenetté konfigolni és 4.864-es kvarcot ráakasztani.
Szeretném hogy stabilan menjen a program benne. akárhonnan érkező zavar (pl:táp ingadozás) se állítsa le a futást vagy ha le is állna induljon újra.Ezt nem tudom ilyen esetben hogy kell, hogy érdemes beállítani. Szóval egy fejléc és konfiguráció ami nekem gondot okoz.
(#) Sick-Bastard hozzászólása Okt 22, 2012 /
 
Üdv!
Ismét én, más problémával.
Egy MCP 23S17-E/SP IC-t próbálok beüzemelni.
Az írással nincs gond, csak az olvasás nem megy valamiért.
Megpróbáltam a felhúzó ellenállásokat is bekapcsolni, amolyan tesztelésnek, de az sem ment.

Ezt a kódot a netten 2 helyen is megtaláltam, csak nem másoltam, hanem leírtam, így valószínű, hogy valamit én írtam el.

A kódban hol lehet a gond?

  1. #include <avr/io.h>
  2. #include <util/delay.h>
  3.  
  4. // SPI settings
  5. #define SPI_PORT        PORTB
  6. #define SPI_DDR         DDRB
  7. #define MCP                     PB3
  8. #define MOSI            PB5
  9. #define MISO            PB6
  10. #define SCK                     PB7
  11.  
  12. // Address
  13. #define IODIRA          0x00
  14. #define IODIRB          0x01
  15. #define GPIOA           0x12
  16. #define GPIOB           0x13
  17. #define IOCONA          0x0A
  18. #define IOCONB          0x0B
  19. #define GPPUA           0x0C
  20. #define GPPUB           0x0D
  21.  
  22.  
  23. int data;
  24.  
  25. void SPIWR(int dataout)
  26. {
  27.         SPI_PORT &= ~(1<<MCP);
  28.         _delay_us(1);
  29.         SPDR = dataout;
  30.         while(!(SPSR & (1<<SPIF)));
  31. }
  32.  
  33. void MCPWR(int addr, int dataout)
  34. {
  35.         SPI_PORT &= ~(1<<MCP);                  // MCP select
  36.         SPDR = 0b01000000;                              // Opcode
  37.         while(!(SPSR & (1<<SPIF)));    
  38.         SPDR = addr;                                    // Address
  39.         while(!(SPSR & (1<<SPIF)));
  40.         SPDR = dataout;                                 // Data
  41.         while(!(SPSR & (1<<SPIF)));
  42.         SPI_PORT |= (1<<MCP);
  43.         _delay_us(1);
  44. }
  45. int MCPRD(int addr)
  46. {
  47.         SPI_PORT &= ~(1<<MCP);                  // MCP select
  48.         SPDR = 0b01000001;                              // Opcode
  49.         while(!(SPSR & (1<<SPIF)));    
  50.         _delay_us(1);
  51.         SPDR = addr;                                    // Address
  52.         while(!(SPSR & (1<<SPIF)));
  53.         _delay_us(1);
  54.         SPDR = 0x00;                                    // DummyData
  55.         while(!(SPSR & (1<<SPIF)));
  56.         _delay_us(1);
  57.         SPI_PORT |= (1<<MCP);
  58.         return(SPDR);
  59. }
  60. int main(void)
  61. {
  62.         SPI_DDR |= (1<<SCK)|(1<<MOSI)|(1<<MCP);
  63.         SPCR |= (1<<SPE)|(1<<MSTR);
  64.         SPCR &= ~(1<<DORD);
  65.         SPSR |= (1<<SPI2X);
  66.         SPI_PORT |= (1<<MCP);
  67.        
  68.         _delay_ms(100);
  69.        
  70.         /*set &= ~(BANK);                               // BANK0, address pins disabled
  71.         set |= (SEQOP | HAEN);                  // Sequential operation disabled */
  72.         MCPWR(IOCONB, 0x28);
  73.         MCPWR(IODIRB, 0xFF);
  74.         MCPWR(GPPUB, 0xFF);
  75.         MCPWR(IOCONA, 0x28);
  76.         MCPWR(IODIRA, 0xFF);
  77.         MCPWR(GPPUA, 0xFF);
  78.        
  79.         _delay_us(1);
  80.        
  81.         while(1)
  82.         {
  83.                 data=MCPRD(GPIOA);
  84.                 MCPWR(GPIOB, data);
  85.                 _delay_ms(500);
  86.         }
  87. }
(#) sikolymester válasza fekete123 hozzászólására (») Okt 23, 2012 /
 
Na kiderítettem neked a dolgot, bár azt hiszem anyázok majd Atmelnek emiatt.
Voltak olyan kedvesek és megváltoztatták az Interrupt Vektor define -ját.

A helyes atmega32A-nál:
  1. USART__RXC_vect


Két aláhúzás kell...
Az iom32a.h fileban találod meg, hogy mik a helyes elnevezések.

Tehát:
  1. ISR(USART__RXC_vect)
  2. {
  3.         char ReceivedByte;
  4.         ReceivedByte = UDR; // Fetch the received byte value into the variable "ByteReceived"
  5.         //      UDR = ReceivedByte; // Echo back the received byte back to the computer
  6.         _delay_ms(1000);
  7.         PORTA ^=1<<2;
  8. }


Az lss fileban akadtam rá, hogy atmega32a -ra fordítva be sem kerül az interrupt vektorokba az uart recieve interrupt, lásd a képen.
A hozzászólás módosítva: Okt 23, 2012
(#) fekete123 válasza sikolymester hozzászólására (») Okt 23, 2012 /
 
Hehe, érdekes. Biztos szükség volt erre a változtatásra

Köszönöm szépen a kitartó segítséget!
(#) zsozsoX hozzászólása Okt 23, 2012 /
 
Sziasztok
Egy ki segítség kellene. Atmega8-ban c nyelven egy tömböt szeretnék feltölteni betükkel.
Csak azt nem tudom merre induljak.
(#) blackdog válasza zsozsoX hozzászólására (») Okt 23, 2012 /
 
Kérdésedből úgy gondolom nem ismered magát a C nyelvet sem. A C-ben nincs string változó. A char valójában egy tömb. Kérdés hogyan definiálod.
Mi a konkrét problémád ami Atmega8 specifikus?
(#) sikolymester válasza zsozsoX hozzászólására (») Okt 23, 2012 /
 
Ezt javaslom:
A C programozási nyelv
(#) zombee válasza zsozsoX hozzászólására (») Okt 23, 2012 /
 
Alap C tudás itt nem elég! AVR-nél többféleképp lehet, kérdés pl. az is hogyan definiálod.
Egyszerű definícó, túl nagy tömböknél nem ajánlott, egyetlen előnye hogy sima változóként használhatod:
  1. char s[] = "xxxxxxxxx";
  2. char u[3] = {'v','u','w'};

Jegyezd meg: ha sztringként definiálod, a mérete +1 bájttal nagyobb lesz a sztring végi "\0" miatt!

Ezen kívül még van 2 féle konstans definíció, ami vagy a FLASH, vagy az EEPROM-ba tárol.
Mindkettő előnye hogy a tömb feltöltéséhez tulajdonképpen nem kell semmilyen utasítás,
a HEX vagy EEP fájlba a tömb tartalma bele van égetve. Hátránya hogy nem használhatod
őket sima változóként, mindig makrókkal kell jelölnöd, és futás közben nem változtathatod meg.
Ezek leírását, használatát a "pgmspace.h" és "eeprom.h" leírásában megtalálod feketén-fehéren.
A hozzászólás módosítva: Okt 23, 2012
Következő: »»   489 / 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