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   490 / 840
(#) icserny válasza sikolymester hozzászólására (») Okt 24, 2012 /
 
Idézet:
„Turkálj bele bátran bármilyen open source AVR projektbe és látni fogod, hogy ezzel kisebbségben lennél.”
Nem kellene úgy tenni, mintha én lennék csodabogár az olvasható programok igényével. Máshol, más vezérlőknél a bitdefiníciók gyárilag benne vannak a fordítóhoz tartozó fejléc állományokban (IAR EW, Code Composer Studio).

Természetesen mindenki olyan programot ír, amilyet akar. "Az igazi programozó bármilyen programnyelven képes FORTRAN programot írni"
(#) sikolymester válasza icserny hozzászólására (») Okt 24, 2012 /
 
Ezt csak azert mondtam a hozzaszolasodra, mert ugy veltem erosen leoltod a delikvenst egy olyan dologgal, ami szerintem nem abszolut igazsag.
Ha mondjuk azt allitod, hogy nem erdemes nyolcas szamrendszerben megadni valtozokat, akkor teljes mellszelesseggel alltam volna ki a kommented mellett.
(#) Adam329 hozzászólása Okt 24, 2012 /
 
USART-on keresztül, hogy lehet negatív értékeket kiküldeni?
Van egy integer tömböm amiben negatív és pozitív értékek is vannak ha ezt elküldöm soros porton a PC-nek akkor a hiperterminálon a negatív értékek nem megfelelően jelennek meg. Általában ilyen 200+ decimális értékre változnak át.
(#) thomas3 válasza Adam329 hozzászólására (») Okt 24, 2012 /
 
Karakterként kell kiküldeni ugyebár a számokat is. Ha számokat akarsz kiküldeni és nem szeretnél saját fv-t írni az átkonvertálásra akkor ajánlom az itoa, utoa és társait. (stdlib.h-ban találod őket.)
(#) Adam329 hozzászólása Okt 24, 2012 /
 
Írtam egy kis tesztprogramot. Nem küld ki semmit a soros porton keresztül. Hogyan kell az itoa-t használni?

  1. int main(void)
  2. {
  3.         UART_Config();
  4.        
  5.         int data[8]={0,-1,-2,-3,-4,-5,-6,-7};
  6.         char *buffer[8];
  7.        
  8.         for (int i=0; i<8; ++i)
  9.         {
  10.                 itoa(data[i],buffer[i],2);
  11.         }      
  12.                        
  13.         for (int i=0; i<8; ++i)
  14.         {
  15.                 while (!(UCSR0A & (1 << UDRE0)));
  16.                 UDR0=data[i];
  17.         }                                                              
  18. }
(#) sikolymester válasza Adam329 hozzászólására (») Okt 24, 2012 /
 
Szerintem leptesd vegig a szimulatorban a programod. Meg fogsz lepodni, hogy mit programoztal le.
Hogy az itoa-t hogy kell hasznalni, azt az avrlibc oldalan tudod megnezni.
(#) girhes.main hozzászólása Okt 24, 2012 /
 
Sziasztok!
Lenne egy kis problémám!
  1. #define F_CPU 1000000UL
  2. #define USART_BAUDRATE 9600
  3. #define UBRR_ERTEK ((F_CPU / (USART_BAUDRATE * 16UL)) - 1)
  4.  
  5. #include <avr/io.h>
  6. #include <avr/interrupt.h>
  7. #include <util/delay.h>
  8. #include <avr/eeprom.h>
  9.  
  10. volatile int megszakitas = 0;
  11.  
  12. void KonfigUART()
  13. {
  14.         DDRB = (1<<PINB0);
  15.         PORTB = 0x00;
  16.         UBRRL = UBRR_ERTEK;
  17.         UBRRH = (UBRR_ERTEK>>8);
  18.         UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1);
  19.         UCSRB |= (1 << RXEN) | (1 << TXEN);  
  20. }
  21.  
  22. char UARTAdatFogad()
  23. {
  24.    while(!(UCSRA & (1<<RXC)))
  25.    {
  26.    }
  27.    return UDR;
  28. }
  29.  
  30. void UARTAdatKuld(char data)
  31. {
  32.    while(!(UCSRA & (1<<UDRE)))  
  33.    {
  34.      
  35.    }
  36.    UDR=data;
  37. }
  38. ISR (INT0_vect)
  39. {
  40.     GICR &= ~(1<<INT0);  
  41.     megszakitas  = 1;        
  42. }
  43. int main(void)
  44. {  
  45.         PORTD &= ~(1<<PD2);
  46.     PORTD |= (1<<PD2);  
  47.     GICR |= (1<<INT0);    
  48.     MCUCR |= (1<<ISC01);    
  49.         KonfigUART();  
  50.         sei();
  51.    while(1)
  52.    {
  53.         if((GICR & (1<<INT0)) == 0) {
  54.     _delay_ms(250);
  55.     GIFR |= (1<<INTF0);      
  56.     GICR |= (1<<INT0);        
  57.     }
  58.         if ( megszakitas == 1 )  
  59.     {
  60.     megszakitas  = 0;      
  61.     UARTAdatKuld('!');
  62.         _delay_ms(400);
  63.     }
  64.     UARTAdatKuld('_');
  65.         UARTAdatKuld('T');
  66.         UARTAdatKuld('\r');
  67.         _delay_ms(1000);
  68.         }          
  69.  }

Adott ez a program. A feladat az lenne, hogy ha megnyomom a gombot(D2 port - atmega16), akkor lefut a megszakítás és küld egy felkiáltójelet. Na most! A probléma ott van, hogy lefut, csak nem a felkiáltójelet küldi el, hanem az alulvonás jelet, nem is foglalkozik a megszakítás == 1 feltétellel.
Mi lehet a probléma?

Köszönöm szépen előre is!

Tamás
A hozzászólás módosítva: Okt 24, 2012
(#) thomas3 válasza Adam329 hozzászólására (») Okt 24, 2012 /
 
Itt egy működő fv. (atmega168)
  1. void IntToUART(uint8_t number){
  2.        
  3.         uint8_t stringBuff[10]; //ideiglenes buffer
  4.        
  5.         itoa(number,stringBuff,10); //10-es számrendszerbeli számot kell konvertálnia
  6.        
  7.         int i;
  8.         for(i=0;i<10;i++){
  9.                 if (stringBuff[i]!='\0'){ // a string végi \n-t már nem fogja kiküldeni.
  10.                         sendToUart(stringBuff[i]); //send to UART the buff[i] string
  11.                 }
  12.                 else{
  13.                         break;
  14.                 }
  15.         }
  16. }
  17. void sendToUart(uint8_t data){
  18.  
  19.         while ( !( UCSR0A & (1<<UDRE0)));
  20.  
  21.         UDR0 = data;
  22.        
  23. }


IntToUART bemenő paraméterének megadsz egy számot és azt kiküldi a soros porton.
(#) blackdog válasza girhes.main hozzászólására (») Okt 24, 2012 /
 
Biztos, hogy foglalkozik a megszakitas == 1 feltétellel ami sosem teljesül.
Először tedd rendbe az órajeled:
  1. #define[b] F_CPU 1000000UL [/b]
  2. #define USART_BAUDRATE 9600
  3. #define UBRR_ERTEK ((F_CPU / (USART_BAUDRATE * [b]16UL[/b])) - 1)

Most 1 Mhz az órajel vagy 16?
A megszakításba miért van benne ez?
  1. GICR &= ~(1<<INT0);

A hozzászólás módosítva: Okt 24, 2012
(#) girhes.main válasza blackdog hozzászólására (») Okt 24, 2012 /
 
1MHz az órajel! Köszönöm az észrevételed!
A pergés miatt van benne a megszakításban, hogyha megnyomom a gombot, akkor azt csak egyszer észlelje, ne háromszor, vagy többször.

  1. #define[b] F_CPU 1000000UL [/b]
  2. #define USART_BAUDRATE 9600
  3. #define UBRR_ERTEK ((F_CPU / (USART_BAUDRATE * [b]1UL[/b])) - 1)


Így rendben van?
(#) blackdog válasza girhes.main hozzászólására (») Okt 24, 2012 /
 
Értem. Ha 1MHz az órajel akkor 1UL igen.
Én eddig nem használtam az USART-ot belső órajelről nem tudom ezt mennyire szereti.
(#) girhes.main válasza blackdog hozzászólására (») Okt 24, 2012 /
 
Csak azt nem értem, hogy ha végrehajtja a feltétel alatt lévő utasítást, akkor azt ami pont nekem kellene, azt miért nem?
(#) blackdog válasza girhes.main hozzászólására (») Okt 24, 2012 /
 
  1. 64.
  2.  UARTAdatKuld('_');
  3.  UARTAdatKuld('T');
  4.  UARTAdatKuld('\r');
  5.  _delay_ms(1000);

Ez nincs feltételhez kötve. Gyakorlatilag 1ms-ként lefut. Nem tudom, hogy hol nézed, hogy mi jön be az RS232 porton, de ez elnyomhatja. Ez miért nincs feltételhez kötve?
(#) girhes.main válasza blackdog hozzászólására (») Okt 24, 2012 /
 
Betettem az else ágba, és ugyan azt csinálja! Ha megnyomom a gombot, akkor figyelmen kívül hagyja a feltételt... :/
(#) blackdog válasza girhes.main hozzászólására (») Okt 24, 2012 /
 
BOCSI! Nem figyeltem!
Az alábbi sor jó volt így:
  1. #define UBRR_ERTEK ((F_CPU / (USART_BAUDRATE * 16UL)) - 1)
(#) girhes.main válasza blackdog hozzászólására (») Okt 24, 2012 /
 
Igen, azt már visszaírtam, csak elfejtettem mondani
(#) blackdog válasza girhes.main hozzászólására (») Okt 24, 2012 /
 
Lehet, hülye ötlet és én sem látom feltétlen értelmét, de mi van, ha a megszakításba előbb értéket adsz és csak utána tiltod le a megszakítást?

Ha else ágba tetted a lenti sorokat az majdnem olyan mintha ne csináltál volna semmit.
Ezen sorok nélkül mit csinál?
A hozzászólás módosítva: Okt 24, 2012
(#) girhes.main válasza blackdog hozzászólására (») Okt 24, 2012 /
 
Kipróbáltam, semmi változás...
(#) blackdog válasza girhes.main hozzászólására (») Okt 24, 2012 /
 
Atmega16-ot vagy atmega168-at használsz? Mert itt pont mások a regsziszter elnevezések.
Fordításkor nincs Warning?
A hozzászólás módosítva: Okt 24, 2012
(#) girhes.main válasza blackdog hozzászólására (») Okt 24, 2012 /
 
(#) blackdog válasza girhes.main hozzászólására (») Okt 24, 2012 /
 
Mivel én sem vagyok AVR master csak kezdőként játszadozom vele én így járnék el:
USART félre teszem és egy vagy két led kapcsolgatásával tesztelem amit csinálok.
USART marad és minden számomra lényeges eseményre küldök egy karaktert. Feltéve, hogy az USART jól működik.
A Főprogramba semmit sem tennék csak a pergés mentesítést és a szükséges feltétel figyelését. Jobb ötletem most nincs. Fáradt is vagyok és érdekel is, hogy mi lesz a megoldás.
(#) girhes.main válasza blackdog hozzászólására (») Okt 24, 2012 /
 
Rendben, megcsinálom! Holnap(vagy még ma) értesítlek, ha van valami fejlemény
(#) icserny válasza Adam329 hozzászólására (») Okt 24, 2012 /
 
Idézet:
„USART-on keresztül, hogy lehet negatív értékeket kiküldeni?”
Ha x < 0, akkor küldj ki egy "-" karaktert, utána pedig x helyett a -x értéket alakítsd számjegyekké!
(#) girhes.main válasza girhes.main hozzászólására (») Okt 24, 2012 /
 
Annyira sikerült rájönnöm, hogy mikor megnyomom a gombot, akkor simán újraindul a mikrovezérlő, mindenféle megszakítás nélkül. DE MIÉRT????

Valaki esetleg?
(#) Sick-Bastard válasza Sick-Bastard hozzászólására (») Okt 24, 2012 /
 
Nem tudom, hogy mit csináltam, de úgy néz ki, hogy megoldottam...
Már megy az írás és az olvasás is az MCP23S17-el.
(#) blackdog válasza girhes.main hozzászólására (») Okt 25, 2012 /
 
A KonfigUART()-ba betetted ezt a sort: PORTB = 0x00;Elé meg DDRB = (1< RESET láb fel van húzva tápra 1k-10k ellenállással?


>>
(#) Reggie válasza girhes.main hozzászólására (») Okt 25, 2012 /
 
Olvasd ki az MCUCSR-bol, hogy miert indult ujra.
A megszakitas valtozo tipusat ird at uint8_t-re, mert ez igy hibas. (bar pillanatnyilag nem feltetlen okoz gondot).
Az IC reset laba fel van huzva nehany kOhmos ellenallassal? Ha nincs, akkor esetleg elofordulhat, hogy a gomb megnyomasakor felszed valami zavarjelet.
Esetleg az is lehet gond, hogy tul kicsi felhuzoellenallast hasznalsz a nyomgombnal es megrantja a tapot.
A hozzászólás módosítva: Okt 25, 2012
(#) girhes.main válasza Reggie hozzászólására (») Okt 25, 2012 /
 
Szia!

Azt nem tudom, hogy kell kiolvasni mcucsr-rből, annyira pro nem vagyok (vagy csak még nem jártam utána);
IC reset lábát felhúztam egy 4,7K-s ellenállással VCC-re.
Nyomógombnál pedig 10K az ellenállás értéke.
(#) girhes.main válasza blackdog hozzászólására (») Okt 25, 2012 /
 
Igen, fel van húzva!
(#) Reggie válasza girhes.main hozzászólására (») Okt 25, 2012 /
 
Az MCUCSR egy sima 8 bites regiszter, aminek az also 5 bitje hatarozza meg, hogy mi miatt tortent reset. Miutan kiolvastad(pl egy segedvaltozoba), az also 5 bit erteket ki lehet torolni, igy garantalva, hogy a kovetkezo resetnel csak a kivalto ok legyen benne(no meg, hogy biztosan tudjad, tortent-e reset). A torles a szokasos egyesek beirasaval tortenik.
Az also 5 bit jelentese:
0. bit bekapcsolasi reset
1. bit kulso reset
2. bit brown out reset(azaz tapfesz ingadozas)
3. bit watchdog reset
4. bit JTAG reset
Következő: »»   490 / 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