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   319 / 840
(#) dB_Thunder válasza Reggie hozzászólására (») Ápr 2, 2011 /
 
Más bitet nem piszkáltam csak az órajelet tettem WD. Osc. 128kHz......-re.
Hiába tettem fel a (Topi-féle doper) programozóra a SLOW_CLK jumpert akkor sem akarta az igazat. Aztán megtaláltam a megoldást ! Firmwaret cseréltem a programozón, ERRE és máris ment!
Mostmár tovább fejleszthetem a progit...
(#) kiborg válasza IMi hozzászólására (») Ápr 3, 2011 /
 
Köszi.OK! Működik.

Viszont következő kérdésem: eddig Assemlyben programoztam JTAG-on keresztül. Meg van szokva, hogy akár lépésenként debugolok( egy lépéses üzemmód). Ez nekem rendkívül hiányzik C-ben. Majdnem azt csinálja, amit kell, de mégsem. Néha egyesével lép, néha többet, néha meg átvált folyamatos módra. Szóval kiszámíthatatlan számomra.Ja AVR Studio-ban programozok.

ÜDv Kiborg
(#) Reggie válasza kiborg hozzászólására (») Ápr 3, 2011 /
 
Ha -O0 -val forditasz, akkor minden gond nelkul megy a lepesenkenti debuggolas c-ben. Ha mas optimalizaciot hasznalsz, akkor is siman lehet debuggolni, csak erteni kell, hogy mit optimalizalt a fordito. Viszonylag hamar bele lehet jonni.
(#) kiborg válasza Reggie hozzászólására (») Ápr 3, 2011 /
 
Aha. Ezt jó tudni.Köszi.
Eddig -Os-el optimalizáltam (ez volt a default) Ment is és a kód 454 byte, most kipróbáltam a -O0 optimalizálást, 3706 byte a progi. Azért nem mindegy. Egy arany középút?
-O0 és -O3 között mi a különbség és mi az a -Os ?
Üdv Kiborg
(#) Reggie válasza kiborg hozzászólására (») Ápr 3, 2011 /
 
-O0 egyaltalan nem optimalizal nagy es lassu ezert ezt csak legfeljebb a fejlesztes alatt celszeru hasznalni, mert jol debuggolhato,
-Os meretre optimalizal,
-O3 pedig sebessegre.
Ha kivancsi vagy arra, hogy ez konkretan miben merul ki, akkor az avr-gcc manualja-ban megtalalhato, hogy melyik konkretan milyen optimalizaciokat engedelyez vagy eppen tilt le. Ezeket akar egyesevel te is tudod allitani.
(#) matrix64 hozzászólása Ápr 5, 2011 /
 
Üdv !
Nem tudom ki hogy van vele,de szerintem az AVR Studio 5 egy programozói malőr .Most a méretéről ne is beszéljünk,meg a járulékosan feltelepített dolgokról..de pl. az assembly-ben írt régebbi projektek le sem futnak
(#) lobo67 válasza kiborg hozzászólására (») Ápr 5, 2011 /
 
Először is a _delay_xx egy-egy macro. Ha többször meghívod, mindíg sok helyet foglal.
Ha paraméterként konstans szerepel, akkor fordítási időben kiértékeli a precompiler, és egy olyan ciklust generál, amiben nincs változó, azaz kevés helyet foglal.
Én úgy csináltam, hogy írtam egy függvényt:

  1. void kesleltet_ms(uint8_t i)
  2. {
  3.     for(; i>0; i--)
  4.        _delay_ms(1);
  5. }


Így sokkal kisebb a kód, egyetlen hátránya, hogy nem annyira halál pontos az időzítés, mert a függvényhívások overhead-je rájön, de ez csak pár uS.
(#) kiborg hozzászólása Ápr 5, 2011 /
 
Köszi mindenkinek.
Újabb nem értem probléma.
Gtk kolléga lcd driverét szeretném használni.
Sikerült lefordítanom hiba nélkül, no problem, include OK.
Viszont én Mega16-on szeretném használni, annak is az A portján. Át is írtam haeder-ben a C portokat A-ra, A DB7-DB4 a megfelelő helyekre megy, és az E és R/S is. C-ből nem sikerül életre keltenem sehogy sem. Mit állítsak még át? (a main.c-ben van egy hivathozás a iom8-ra, átírva iom16-ra) config átállítva mega16-ra. Mi hiányzik még, hogy működjön.
ASM-ben él a kijelző, no problem vele.
Üdv Kiborg
(#) kiborg válasza kiborg hozzászólására (») Ápr 5, 2011 /
 
Üdv! Ne kérdezzétek, hogy hogyan, de a probléma megoldódott.
(#) robotech hozzászólása Ápr 6, 2011 /
 
Üdv Mindenkinek!
Én PIC-es vagyok, AVR-el még nem foglalkoztam, most is csak egy kész HEX-et égetnék be, ill. egy egyszerű áramkört dobnék össze, de valami nem kerek:

Az áramkörben ATMEGA8 van, SPDIP-es, egy MAX232, és egy SDkártya. A kapcsolás szerint (csak kicsibe van meg, de mellékelem) 3.3V-os stabilizátor van a körbe, amiről a kapcsolás készítője még írja is, hogy ááá éppen csak megy vele a MAX232 (de akkor miért nem MAX3232-t tett bele?). Az SD kártyának nagyon jó a 3.3V, de az ATMEGA8 az adatlapja alapján 4.5-5.5V-al megy, ellenben a készítő végig ATMEGA8-at emleget, nem pedig ATMEGA8L-t.

A következő lenne a kérdésem ezzel kapcsolatban:
Az ATMEGA8 hex fileját gond nélkül fel lehet tölteni ATMEGA8L-be is, és el is indul? (mint pl: a PIC16F1827 hexe minden gond nélkül lefut PIC16LF1827 alatt is...)
Köszi a választ előre is.

schematic.JPG
    
(#) edison14 válasza robotech hozzászólására (») Ápr 6, 2011 /
 
Az ATMEGA8 és L típus teljesen ugyan az tehát nyugodtan beégetheted a HEX-et működni fog vele.
(#) kiborg válasza robotech hozzászólására (») Ápr 6, 2011 /
 
Szia!

Tudtommal L-es verziók tényleg mennek hivatalosan 3,3Von 8Mhzig vagy 16MHz 5V, míg a sima CSAK 5V minden órajelen. Azóta bevezették az A jelölést ATMEGA8A ami mindent tud. (3,3V 16MHz). Esetedben nincs külső kavics, így belső oszci fut, tehát max 8MHz, így mehet 3,3Vről az L-es. Progi minden további nélkül letölthető, a két proci 5V-on csereszabatos egymással. (vagy bármilyen környezetben helyettesíthető az A típussal.)Lehet hogy azért emleget ATMEGA8-at, mert az L-t lusta odatenni, vagy mittudom én...
Hogy miért nem MAX3232-t használt, az passz, lehet az volt a fiókban ?

Üdv Kiborg
(#) mario1111 hozzászólása Ápr 6, 2011 /
 
Üdv!

Egy atmega 16-ossal harcolok és egy érdekes hibába futottam bele. 8 AD csatornát használok egymás után felváltva. Eddig 8 biten használtam, de most 10-en szeretném. Balra-jobbra igazítás rendben, de ha megpróbálom használni az ADCL értéket, akkor meghülyül és minden mérésre ugyanazt az értéket adja, mintha nem választana másik csatornát. Ha eepromba iratom az ADCL-t és utána visszaolvasom és azt adom hozzá akkor jó. Ha közvetlenül, akkor minden méréskor ugyanazt az eredményt adja(ezt máshol iratom ki eepromba onnan tudom).

Ezzel működik:

  1. unsigned int Beolvas8bitADC(unsigned char csatorna)
  2.  
  3. {
  4.  
  5.         unsigned int tiz_bit=0;
  6.         ADMUX = (ADMUX & 0b11110000) | csatorna;
  7.  
  8.         ADCSRA |= (1 << ADSC); // ADC konverzio elinditasa
  9.  
  10.         while (ADCSRA & (1 << ADSC))
  11.                 ; // varas az atalakitasra
  12.  
  13.         ADCSRA |= (1 << ADSC); // konverzió elindítás
  14.  
  15.         while (ADCSRA & (1 << ADSC))
  16.                 ; // varas az atalakitasra
  17.  
  18.  
  19.         eeprom_write_byte((uint8_t*) 50, ADCH);
  20.         eeprom_write_byte((uint8_t*) 51, ADCL);
  21.  
  22.         tiz_bit=ADCH<<8;
  23.        
  24.         tiz_bit+=eeprom_read_byte((uint8_t*) 51);      
  25.  
  26.         return (tiz_bit);
  27.  
  28.  
  29.  
  30. }


Ezzel nem:
  1. unsigned int Beolvas8bitADC(unsigned char csatorna)
  2.  
  3. {
  4.  
  5.         unsigned int tiz_bit=0;
  6.         ADMUX = (ADMUX & 0b11110000) | csatorna;
  7.  
  8.         ADCSRA |= (1 << ADSC); // ADC konverzio elinditasa
  9.  
  10.         while (ADCSRA & (1 << ADSC))
  11.                 ; // varas az atalakitasra
  12.  
  13.         ADCSRA |= (1 << ADSC); // konverzió elindítás
  14.  
  15.         while (ADCSRA & (1 << ADSC))
  16.                 ; // varas az atalakitasra
  17.  
  18.  
  19.         eeprom_write_byte((uint8_t*) 50, ADCH);
  20. //      eeprom_write_byte((uint8_t*) 51, ADCL);
  21.  
  22.         tiz_bit=ADCH<<8;
  23.        
  24.         tiz_bit+=ADCL; 
  25.  
  26.         return (tiz_bit);
  27.  
  28.  
  29.  
  30. }


Ha van valami ötletetek ne tartsátok vissza

Márió
(#) sikolymester válasza mario1111 hozzászólására (») Ápr 6, 2011 /
 
Minek indítod a konverziót kétszer?

Adatlap szerint:
If the result is left adjusted and no more than 8-bit precision is required, it is sufficient to read
ADCH. Otherwise, ADCL must be read first, then ADCH, to ensure that the content of the Data
Registers belongs to the same conversion. Once ADCL is read, ADC access to Data Registers
is blocked. This means that if ADCL has been read, and a conversion completes before ADCH is
read, neither register is updated and the result from the conversion is lost. When ADCH is read,
ADC access to the ADCH and ADCL Registers is re-enabled.

Tehát mindig először az ADCL-t olvasd ki, majd utána az ADCH-t. Kivéve, hogyha balra shiftelted az ADC-t (tehát 8 MSB az ADCH-ban van), mert ekkor elég csak az ADCH-t kiolvasni.

Illetve jó tanács: Azt hiszem nem lehet csak úgy kiolvasgatni az ADCL és ADCH -t többször egymás után (ebben ugyan nem vagyok biztos, csak mintha személyes tapasztalat lenne). Hanem szépen beolvasod őket egy-egy TempADCH_ui8, illetve TempADCL_ui8 -ba. Ezután már megvan az érték, és ezzel addig játszol amíg akarsz, az eredeti regisztereket többet nem piszkálod, csak a következő konverzió után.
(#) mario1111 válasza sikolymester hozzászólására (») Ápr 6, 2011 /
 
Kösz! Működik.

Márió
(#) Axel hozzászólása Ápr 6, 2011 /
 
Inkább ide írom ezt a kérdést és nem a "robotika kezdőknek" topikban folytatom. Sajnos még mindig nem jó az uart az atmega8-ason. 1200-as baudrate-t állítottam be amivel számításaim szerint 0% hibával kellene működnie a kommunikációnak még 12MHz-es kvraccal is. A fuse biteket is beállítottam, a kondik a kristályon 22pF-osak. Természetesen a terminálprogramot is 1200-ra állítottam be.
Ez lenne a kód, kérem ha van ideje valakinek fussa már át! Hátha van benne olyan hiba amit csak én nem veszek észre.
  1. #include <avr/io.h>
  2. #include <inttypes.h>
  3. #define F_CPU 12000000UL
  4. uart_1200(void)
  5.    {
  6.    #define BAUD 1200
  7.    #include <util/setbaud.h>
  8.    UBRRH = UBRRH_VALUE;
  9.    UBRRL = UBRRL_VALUE;
  10.    #if USE_2X
  11.    UCSRA |= (1 << U2X);
  12.    #else
  13.    UCSRA &= ~(1 << U2X);
  14.    #endif
  15.    }
  16.    
  17. void set_uart(void){
  18. UCSRB|=(1<<RXEN)|(1<<TXEN);
  19. UCSRC|=(1 << URSEL)|(1 << UCSZ0)|(1 << UCSZ1);}
  20.  
  21. void send_data(char data){
  22. while(!(UCSRA & (1<<UDRE))){;};
  23. UDR=data;}
  24.  
  25. char receive_data(){
  26. while(!(UCSRA & (1<<RXC))){;};
  27. return UDR;
  28. }
  29.  
  30. void main(){
  31. char data;
  32. set_uart();
  33. while(1){
  34. data=receive_data();
  35. send_data('F');
  36. send_data('O');
  37. send_data('G');
  38. send_data('A');
  39. send_data('D');
  40. send_data('V');
  41. send_data('A');
  42. send_data(data);}
  43. }
(#) sikolymester válasza Axel hozzászólására (») Ápr 7, 2011 /
 
Érdekes a függvényen belüli #define-od, illetve #include -od. Nem azt mondom, hogy nem kellene, hogy működjön, de erősen javaslom, hogy ne használj ilyet.

Ami az UARTot illeti. Így hirtelen azt tanácsolom, hogy használd a
Peter Fleury Uart library-jét. Ez nekem működött Atmega8-cal.
(#) sikolymester válasza Reggie hozzászólására (») Ápr 7, 2011 /
 
Idézet:
„-O0 egyaltalan nem optimalizal nagy es lassu ezert ezt csak legfeljebb a fejlesztes alatt celszeru hasznalni, mert jol debuggolhato,”


Az -O0 optimalizáció használatáról maga az AVRGCC tanácsol el, mivel sok funkciót hibásan fordít így le. Ne felejtsük el, hogy a GCC eredetileg Neumann gépekre fordít, a Harvard architektúra sok mindent csak egy kis trükközéssel tud megcsinálni. Pont emiatt nem érdemes használni a 0-as optimalizációt, mert a kód hibás lehet.
(#) Fizikus válasza Axel hozzászólására (») Ápr 7, 2011 /
 
Lehet hogy az 1200 tul lassu. Az ATmega8-as adatlapja is 2400-as baudrate-tol felfele irja az UART hibakat. Nem szamoltam utana hogy 12MHz-es kvarc mellett mekkora lehet a minimalis UART sebesseg ha az osszes frekvenciaosztot a maximumra allitod.
Probald meg 2400-as vagy a sztandard 9600-as sebesseggel, ezek hibaja is kb 0.2%, ami joval az ajanlott 2% alatt van.
(#) huba válasza Fizikus hozzászólására (») Ápr 7, 2011 /
 
12Mhz-n a legkisebb frekvencia Baud érték 4800. Itt az UBBR 115. 9600-on 77 Az avrcalc szerint. Mindkét esetben a hiba 0.16%
(#) lobo67 válasza sikolymester hozzászólására (») Ápr 7, 2011 /
 
Én még nem találkoztam ilyen hibával, debugolni viszont más beállítással nem túl jó.
Azt viszont nemrég derítettem ki, hogy van olyan #pragma (ne kérdezzétek mi az, nem emlékszem) amivel csak egy kódrészlet (pl egy függvény) optimalizálását külön lehet állítgatni. Így csak az a kódrészlet lesz nagy, és lassú.
(#) Axel hozzászólása Ápr 7, 2011 /
 
Sajnos nem működik sehogy sem, minden esetre köszönöm a segítséget! Lehet, hogy rossz a proci uart modulja majd kipróbálom egy másikkal...
(#) zoox hozzászólása Ápr 7, 2011 /
 
Sziasztok!
Lenne 1 kérdésem ,most próbálkozom először atmellal szenvedni és sajna csak szenvedés van? Szóval az lenne a kérdésem hogy kezembe akadt 2 db atmel AT89c52 uc és nem tudom élrtre kelteni,ill szeretném törölni de a programozó erase errort ir ki(programozó FlashPro 1600 ipari progizó).Eddig pic-eltem és ott ha teljesen töröltem 1 lezárt uc-t akkor ujból tudtam használni és nem tudom hogy ez igy működik-e atmel-éknél.Légyszi segitsetek Élég láma vagyok atmel ügyileg Köszi
(#) sikolymester válasza lobo67 hozzászólására (») Ápr 7, 2011 /
 
A #pragma preprocessor direktívákkal csakugyan lehet ilyen és ehhez hasonló dolgokat finomhangolni. Érdemes utána olvasni a GCC helpben.

De a -O0 optimalizációról még ebben a fórumban is eltanácsolnak. A fórum tetején látható 6 pont közül a 4.-ben,
(#) Reggie válasza sikolymester hozzászólására (») Ápr 7, 2011 /
 
Tevedsz. Az optimalizacio hianyatol nem fog semmi sem hibasan futni*(ez csak egy varosi legenda), csak a teljesitmenyt rontja nagyon, es az avr-gcc is az -O0 -t javasolja a debuggolashoz. Az avr-lib is ezt javasolja, megtalalod a "Why does the PC randomly jump around when single-stepping through my program in avr-gdb?" cim alatt. Egyedul annyit fuznek hozza, hogy -O0 eseten lehet, hogy nem jon elo az a hiba, igy amig lehet optimalizacio mellett celszeru debuggolni.

* (az idozitesekre ez nyilvan nem vonatkozik, de ez is a teljesitmenyromlas miatt van. A program futasa nem lesz hibas)
(#) BBenyó hozzászólása Ápr 7, 2011 /
 
Sziasztok!
AT91SAM7X256-ot próbálok programozni C-ben. http://www.yagarto.de/images/at91sam7x-ek.jpg

A dev boardon lévő i/o pinek valamelyikén kell kivezetnem egy szinkron jelet ami 500 microsecenként lenne egy minimum 5 microseces jel. SPI-t USART-ot, órajelet sikerült megcsinálni a doksija alapján, de ez nem jön össze. Várom a hasznos tanácsokat!!

Előre is köszi!

Benyó
(#) Reggie válasza BBenyó hozzászólására (») Ápr 7, 2011 /
 
Mekkora orajel, pwm vagy timer segitsegevel akarod?
(#) BBenyó válasza Reggie hozzászólására (») Ápr 8, 2011 /
 
500 microsecenként kéne, tehát 2 kHz-es órajel kell. pwm-et próbáltam, de nem történt semmi.. oszcilloszkóppal rámértem és semmi ... pedig ezt is példaprogi és a doksi alapján configoltam.


static const Pin sync_pin[1] = {1 << 21, AT91C_BASE_PIOB, AT91C_ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT};
.
.
.

PWMC_ConfigureClocks(2000,0,BOARD_MCK);

PWMC_ConfigureChannel(1,clk_config,0,0);

PWMC_SetPeriod(1,2000);

PWMC_SetDutyCycle(1,50); //itt az 50 csak tipp .. nem tudom, hogy %-ot kell megadni, vagy időtartamot erre nem találtam utalást

PWMC_EnableChannel(1);>>
(#) BBenyó válasza Reggie hozzászólására (») Ápr 8, 2011 /
 
static const Pin sync_pin[1] = {1 << 21, AT91C_BASE_PIOB, AT91C_ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT};

itt a 21 helyett 19-el kell shiftelni, de így sem ment, mi lehet még a hiba??>>
(#) Reggie válasza BBenyó hozzászólására (») Ápr 8, 2011 /
 
Jo kerdes, szerintem probald meg kozvetlen a regisztereket hasznalni es ugy bekonfiguralni a PWM modult. Nem tudom, hogy nezted-e mar a forrasat a gyari fuggvenyeknek, en AVR32-nel lattam oket, szerintem jobb elfelejteni.
Következő: »»   319 / 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