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   376 / 840
(#) Robi98 válasza sgt hozzászólására (») Nov 7, 2011 /
 
Köszönöm!
Nem igazán értem a különbséget a hardveres és a szoftveres PWM között.Már sikolymester is írta, hogy a hardveres PWM-nél nem kell nullázni a timert, viszont az előző kódnál meg kellett.
(#) Reggie válasza Gery hozzászólására (») Nov 7, 2011 /
 
Valoban nem csinalja erdekes. Es az az oka, hogy a CMR es cmr unionban van. Amig nem jovok ra, hogy hogyan lehet csinalni, addig azt javaslom, hogy futasidoben adjal a struktura(k)nak erteket(peldaul az init hivasa elott), ne deklaraciokor, a fordito ugyis kioptimalizalja.
(#) sgt válasza Robi98 hozzászólására (») Nov 7, 2011 /
 
Valami ilyesminek kellene lennie. Sajnos nem tudom kipróbálni, mert a legutóbbi manőveremnél tönkre vágtam az IC eme részét, és azóta lusta voltam menni az msc-hez.

  1. #define F_CPU 1000000UL
  2.  
  3. #include <avr/io.h>
  4. #include <util/delay.h>
  5.  
  6. void init(void)
  7. {
  8. DDRB = 0xff;
  9. DDRD |= (1<<PD7);
  10.  
  11. ADCSRA = (1<<ADEN)
  12.    | (1<<ADPS2)
  13.    | (1<<ADPS1)
  14.    | (1<<ADPS0);
  15.  
  16. ADMUX = (1<<ADLAR);
  17.  
  18. TCCR2 |= (0<<WGM21)
  19.    | (1<<WGM20)
  20.    | (1<<COM21)
  21.    | (0<<COM20)
  22.    | (0<<CS22)
  23.    | (0<<CS21)
  24.    | (1<<CS20);
  25.    
  26. TCNT2 = 255;
  27. OCR2 = 50;
  28. }
  29.  
  30. int main(void)
  31. {
  32. init();
  33.  
  34. for(;;)
  35. {
  36. ADCSRA |= (1<<ADSC);
  37. while(ADCSRA & (1<<ADSC));
  38.  
  39. TCNT2 = 0;
  40. OCR2 = ADCH;
  41. TCNT2 = 255;
  42.  
  43. _delay_ms(20);
  44. }
  45. }
(#) sikolymester válasza sgt hozzászólására (») Nov 7, 2011 /
 
  1. TCNT2 = 0;
  2. OCR2 = ADCH;
  3. TCNT2 = 255;


A TCNT2 babrálását nyugodtan ki lehet hagyni.

Így teljesen megfelelő:
  1. for(;;)
  2. {
  3. ADCSRA |= (1<<ADSC);
  4. while(ADCSRA & (1<<ADSC));
  5.  
  6.  
  7. OCR2 = ADCH;
  8.  
  9.  
  10. _delay_ms(20);
  11. }


Félreértés van szerintem azzal, hogy az OCR2 regiszter melyik pillanatban íródik be a helyére ténylegesen. Ez vagy a számlálás alján, vagy tetején történik. Értsd: amikor a TCNT2 == 0, vagy TCNT2 == 255 (8 bites működés esetén). De nincsen gond, mert ha beírsz mondjuk 100 at az OCR2 helyére és a TCNT2 éppen 110 nél jár, akkor majd szépen befrissül az OCR2 helyére a 100 értéke, amikor a TCNT2 elérte vagy a 0-t vagy a 255-t.

Szóval ideális esetben egy hardveres pwm-nél nem piszkálod a TCNTx számlálót.

Robi98: szoftveres pwm, akkor van, amikor az atmega8-n a mellékelt képen jelölt lábak egyikén csinálsz pwm-t. Remélem ez így érthető most.
(#) Gery válasza Reggie hozzászólására (») Nov 7, 2011 /
 
Akkor nem csak nálam van ez a probléma. Köszönöm, hogy foglalkozol a problémámmal.

Mellékelek egy összevágott képet, hogy mit alkottam ez alapján. Ha beírom ezt:
avr32_pwm_cmr_tpwm_cmr;
akkor elfogadja a .CMR-t. De ha ezt betöltöm nem történik semmi. Vajon mi lehet a probléma?

Üdv.:Gergő

pwm.jpg
    
(#) Robi98 válasza sikolymester hozzászólására (») Nov 7, 2011 /
 
Köszönöm, most már megértettem ezt az egészet.
Tehát nem kell semmit sem csinálni a TCNTx-el, mert a potméter értékét mindig automatikusan beolvassa.
(#) sikolymester válasza Robi98 hozzászólására (») Nov 7, 2011 /
 
Úgy van, akár olyan kódot is lehetne írni, ahol a mainben üresen áll a szokásos while(1) végtelen ciklus, mert teszem azt az ADC folyamatos üzemre van állítva és az ADC ready interruptban cseréled le az OCRx regisztert.

Xmegánál még fokozni is lehet. Ha jól tudom, akkor a dma modulljával megoldható, hogy az ADC értékét átirányítod az OCRx helyére. Ekkor még interrupt sem kell.
(#) Reggie válasza Gery hozzászólására (») Nov 8, 2011 /
 
Szerintem az a baj, hogy a PWM-hez tartozo labnak nem allitottad be, hogy a periferia hasznalja. Ezt a
  1. gpio_enable_module_pin(AVR32_PWM_x_y_PIN, AVR32_PWM_x_y_FUNCTION);

hivassal lehet.
Itt az x azt jelenti, hogy hanyadik PWM kivezetes, az y pedig azt, hogy melyik periferia csoport(A/B/C/D). Az ehhez kapcsolodo lab es periferia kiosztasi tablazatot az adatlap 7. oldalan talalod meg. Peldaul, ha a PA13-mas labra szeretned kirakni, akkor mivel a B periferia oszlopban van a PWM - PWM[2] kivezetes, igy az x a szogletes zarojelben levo szam es y=0, ha A periferia, y=1 ha B periferia, es igy tovabb, tehat ebben az esetben
  1. gpio_enable_module_pin(AVR32_PWM_2_1_PIN, AVR32_PWM_2_1_FUNCTION);
hivast kell beleirnod.
(#) Reggie válasza Gery hozzászólására (») Nov 8, 2011 /
 
Esetleg a teljes main.c-t mellekeld, mert a screenshot sosem teljes es igy nehez a hibat megtalalni. Lehet hogy a kep elejen jol allitod be a gpio_enable_module_pin hivassal, viszont ha utana meghivod a gpio_set_gpio_pin-t es akkor biztos, hogy mar nem periferia uzemmodban van a lab. Az AVR8 es AVR32 kozott az a kulonbseg, hogy mig az elobbinel a periferia hasznalata eseten is be kell allitani a lab iranyat, AVR32-nel ezt nem szabad megtenni, ha kivalasztod a periferiat, akkor mar minden mast intez hardverbol.
(#) Gery válasza Reggie hozzászólására (») Nov 8, 2011 /
 
A lábakat elvileg jól állítom be, a pwm jel előállítására szolgál 1 láb, továbbá egy másik ami a forgás irányt adja meg. Vagy ha így csinálom meg akkor a forgás irányt nem gpio-ként kell megvalósítani?

Mellékelek egy word dokumentumot amelyben jobb oldalt sárgával láthatóak, hogy milyen funkciót használok. Továbbá a főprogramomat, és egy plusz headert ami a #define-okat tartalmazza.
(#) Robi98 válasza sikolymester hozzászólására (») Nov 8, 2011 /
 
És ez a kód amit kijavítottam miért nem jó?
Mindent jól adtam meg benne.
Sőt azt a részt amikor egy függvény beolvassa az ADC értékét és visszaadja az ADCH-ét; valamint ezt átadja valaminek(jelenleg az OCR1A-nak) álltalában szokott működni.Úgy hogy halvány lila gőzöm sincs,hogy mi lehet a hiba.
  1. #define F_CPU 1000000UL
  2.  
  3. #include<avr/io.h>
  4. #include<util/delay.h>
  5.  
  6. uint8_t ADConverter(unsigned char csatorna){
  7. ADMUX=csatorna;//csatornaválasztás
  8. ADCSRA|=(1<<ADSC);//egyszeri mérés elindítása
  9. while(ADCSRA&(ADSC));//várás az átalakításra
  10. ADCSRA|=(1<<ADSC);//ugyan ezek még egyszer
  11. while(ADCSRA&(ADSC));
  12. return(ADCH);//ADCH értékének visszaadása
  13. }
  14.  
  15. int main(void){//főprogram kezdete
  16.  
  17. DDRB|=(1<<PB3);//PB3 kimenet
  18. ADMUX=(1<<REFS0)|(1<<ADLAR);//VCCreferencia fesz és balrarendezett mérés
  19. ADCSRA=(1<<ADEN)|(1<<ADPS0)|(1<<ADPS1);//ADC enged. és 8-as előosztás
  20. TCCR2|=(1<<CS20);//1-es timer előosztás
  21. TCCR2=(1<<WGM20)|(1<<COM21);//nem invertált gyors PWM
  22.  
  23. while(1){
  24.  
  25. OCR2=ADConverter(1);//az ADC mérés eredményét átadjuk a komparátornak
  26.  
  27. _delay_ms(20);
  28. }
  29.  
  30. return(0);
  31. }
(#) sgt válasza Robi98 hozzászólására (») Nov 8, 2011 /
 
TCNT2-be mindenféleképpen kell valamilyen nullától különböző érték, mert azzal kapcsolod be, illetve az is befolyásolja, hogy mekkora a pulzus szélesség felbontása. Teszem azt beállítod 120-ra a TCNT2-t, akkor a 0% és 100%-os kitöltési tényezőt 121 részre bontod fel, ahol 0 a 0% és 120 a 100%-os kitöltés. Ezért célszerű jelen esetben neked 255-öt megadni, mert akkor az ADCH teljes tartományában változni fog a kitöltési tényező.
(#) Robi98 válasza sgt hozzászólására (») Nov 8, 2011 /
 
Köszönöm! Most már értem.
Tehát csak annyi az egész, hogy a végtelen ciklus elé odaírom a TCNT2=255-öt.
[OFF]Örülök, hogy mindig van valaki aki érthetően elmagyarázza a dolgokat.
(#) kala1982a hozzászólása Nov 8, 2011 /
 
Sziasztok 2313-assal az alábbi kapcsolást meg tudom csinálni ugye?

Amelyik lábnak a kimenete, nem magas szintű akkor azt a testre húzza a mikrovezérlő?

Bővebben: Link
(#) Reggie válasza Gery hozzászólására (») Nov 8, 2011 /
 
  1. gpio_enable_module(PWM_GPIO_MAP, sizeof(PWM_GPIO_MAP)/sizeof(PWM_GPIO_MAP[0]));

helyett szerintem
  1. gpio_enable_module(PWM_GPIO_MAP[0][0], PWM_GPIO_MAP[0][1]);

kellene. Az a sizeof-os kifejezes szerintem eleve nem ertelmes.
(#) kovacsj hozzászólása Nov 8, 2011 /
 
Sziasztok!

Ma már álltam jobban is, de a türelmem végére kezdek érni.
Ha felhívom a GSM modult, akkor az rx_buffer-t nem tudom kiíratni a terminálra. Mindaddig írja szépen a végtelen ciklusban a tartalmat, de amint elkezd kicsörögni, mintha megfagyna az egész. Tudom, hogy én vagyok a hibás, mert ma már volt olyan, hogy nem fagyott, de most így estére már kezdek belefáradni.
Atmega128 a kontroller.
A fontosabb részletek:

  1. #define RX_INDEX 256
  2. volatile unsigned static char  rx_buffer[RX_INDEX];
  3. volatile unsigned static char  rx_wr = 0;
  4.  
  5.  
  6. ISR(USART1_RX_vect) {
  7. unsigned static char  data;
  8. data = UDR1;
  9. rx_buffer[rx_wr++] = data;
  10.  
  11. if (rx_wr > (RX_INDEX-2)) {
  12. rx_wr = 0;
  13. }
  14.  
  15. if (data == '\r') {
  16.  
  17. rx_wr = 0;
  18.  
  19. }
  20.  
  21. }
  22.  
  23. void USART1_putchar(unsigned char data) {
  24. while (!(UCSR1A &(1<<UDRE1)));
  25. UDR1 = data;
  26. }
  27.  
  28. void USART0_putchar(unsigned char data) {
  29. while (!(UCSR0A &(1<<UDRE0)));
  30. UDR0 = data;
  31. }
  32.  
  33. void USART1_puts(unsigned char *str)
  34. {
  35.  
  36.     for( ;*str != '\0'; )
  37.     {
  38.         USART1_putchar( *str++ );
  39.     }
  40. }
  41.  
  42. void USART0_puts(unsigned char *str)
  43. {
  44.  
  45.     for( ;*str != '\0'; )
  46.     {
  47.         USART0_putchar( *str++ );
  48.     }
  49. }
  50.  
  51. int main(void) {
  52. //Inicializálások. Jól működnek, mert látom a terminálon.
  53.  
  54. while(1) {
  55.  
  56. USART0_puts((unsigned char*) rx_buffer);
  57. USART0_puts((unsigned char*) newline);
  58. _delay_ms(1000); //Ez nincs mindig benne.
  59. }
  60. }


Minden segítséget előre is nagyon szépen köszönök!
(#) kovacsj válasza kovacsj hozzászólására (») Nov 8, 2011 /
 
Rájöttem.
Az rx_buffer végére nem tettem '\0' karaktert.
  1. ISR(USART1_RX_vect) {
  2. unsigned static char  data;
  3.  
  4. data = UDR1;
  5. rx_buffer[rx_wr++] = data;
  6.  
  7. if (rx_wr > (RX_INDEX-2)) {
  8. rx_buffer[rx_wr] = '\0';
  9. rx_wr = 0;
  10. }
  11.  
  12. if (data == '\r') {
  13. rx_buffer[rx_wr] = '\0';
  14. rx_wr = 0;
  15.  
  16. }
  17.  }


Így már működik. Jó. hogy írtam ide. Ezért alaposabban átnéztem és rájöttem.
(#) Gery válasza Reggie hozzászólására (») Nov 8, 2011 /
 
Amit írtál nekem nem fordul le (kép). De SPI-nél is így fordítottam és az tökéletesen működik, meg az example-ban is így írja.

De vajon mi lehet a baj ami miatt nem mozdul meg a motor? Az ezen az oldalon lévő mintapélda alapján jónak kell lennie, nem? Amúgy ami különbséget látok a 8bites és e között hogy itt vannak "pwm regiszterek" és timer regisztert külön nem is állítgat benne. Ez normális?

Névtelen.jpg
    
(#) Reggie válasza Gery hozzászólására (») Nov 8, 2011 /
 
Latom, mar megvan mi a kulonbseg. En a gpio_enable_module_pin()-t hasznaltam, te meg a gpio_enable_module()-t. Viszont amit feltoltottel forraskodot, ott a channel= -1 de a jo a channel=1 vagy 0 lenne.

Az AVR32-ben a timer es a pwm ket kulon modul es fuggetlen egymastol.
Szerintem generaljal egy minta projectet az AVR Studioval, mint ahogy az elejen javasoltam.
(#) norbigal hozzászólása Nov 8, 2011 /
 
AVR Studio 4-ben akartam lefuttatni egy progit, de a következő hibaüzenettel állt elő: Cannot find include file: avr/io.h

Azt tudom, hogy az #include "avr/io.h" utasítással van baja, de miért?
Nem találja a file-t de hogy bírom elérhetővé tenni neki? Mit kellene telepítenem és honnan lehet beszerezni?
(#) kovacsj válasza norbigal hozzászólására (») Nov 8, 2011 /
 
Lehet, hogy
  1. #include <avr/io.h>

kell neki?

Winavr fel van telepítve?
(#) sgt válasza kala1982a hozzászólására (») Nov 8, 2011 / 1
 
Bővebben: Link 52. oldal. Table 20. Le van írva minden amire neked szükséged van (az ne zavarjon majd, hogy atmega16-é, de ugyanaz mint a 2313.
(#) norbigal válasza kovacsj hozzászólására (») Nov 8, 2011 /
 
Igen feltelepítettem a WIN AVR-t. De úgy írjaki h nem találja a file-t :| Nemtudom mi lehet a gond, bár még C-ben nem programoztam csak assembly-vel szórakoztam LED-ekkel. de ott nem volt semmi baja.
Vagy valamit rosszul csinálok?!?! A programot amit írok az AVR STUDIO-ba kell írni nem?!?! Már nem tudok mire gondolni..... Bár a WINAVR-rel települt egy AVR Insight is, és esetleg abba kellene írni a programot?
Erről gőzöm nincs. Én úgy gondoltam volna hogy csak megírom AVR studioba, bulid, és connect majd kiírás, de akkor nem így kell C-ben?!?!?
(#) sgt válasza norbigal hozzászólására (») Nov 8, 2011 /
 
Másold be mit szeretnél ha lefordulna .

Igen az AVR Studio-ban kell írni a programot. Amikor új projektet csinálsz akkor ott kell kiválasztani a GCC-t (bika fej vagy valami hasonló a logoja), és oda írkálhatsz C-ben progikat.
(#) sgt hozzászólása Nov 8, 2011 /
 
Nekem is lenne két broadcast kérdésem. Mindkettő az AVR Studio 5-ről lenne.

1. Hogyan lehet beállítani, hogy ne állandóan az -O0 optimalizáció legyen? Nagyon idegesít hogy semmi program is 2-3 kB, ha nem veszem észre, hogy nem állítottam át.

2. Hogyan lehet programozni úgy az eszközt, hogy nem nyomok meg 3 gombot, hanem csak egyet (mint az AVR Studio 4.18-ban)?
(#) norbigal válasza sgt hozzászólására (») Nov 8, 2011 /
 
Egy futófény amit nem én írtam hanem egyik tanárom, és programelemzéssel próbálom megérteni az alamokat, de rájöttem mi a hiba: nem a bikára nyomtam látszik h még az életben nem írtam C-ben AVR programot
De ebből a fájlból hogy csinálok HEX fájlt? A Compile gomb után semmi gondja de mikor F7-tel építeném akkor meg olyat ír ki hogy 'elsoc.helf' : file not found ahol ugye elsoc a fájl neve lenne.

Akkor itt a build előtt még kellene vmit nyomni??
(#) sgt válasza norbigal hozzászólására (») Nov 8, 2011 /
 
Kandós vagy?

Hex fájlt automatikusan generál, amikor build-dal lefordítod a programot. A hely ahol eléred az meg asszem a Dokumentumok/AVRStudio/Debug és asszem iderakja az összes hex fájlt.

Úgy csinálsz progit, hogy új projektnél kiválasztod a megfelelő eszközt. Létrehozod majd megírod a progit. Majd ha úgy gondolod hogy ki lehet probálni, akkor nyomsz egy build-ot. Van lehetőség szimulálni is ha nincs eszközöd. Eszköz programozásnál nagyon figyelni kell, arra hogy megfelelő hex fájlt égesd a mikrokontrollerbe, mert ha új projektet indítasz akkor is az előző hex-t akarja beleégetni.
(#) norbigal válasza sgt hozzászólására (») Nov 8, 2011 /
 
Ezt nem tudom hogy bűvészkedted ki de igen. Ergó de a T-Bird-ön programozok (Atmega 128) Bár ezt csak a programozás gyakorlása végett vettem meg, mert szimpatikusabbak a kevesebb lábú chip-ek, amikből demultiplexerrel is ki lehet hozni ugyanazt mint egy nagyobbból (lábak terén persze).
Ahogy nézem te Schuszter kezében vagy már (adatlapodból gondolom)

Azt tudom, hogy a hex fájlt mindig át kell állítani ha más progit akarok beégetni. De nekem azt írja h nem bír létre hozni .hex fájlt mert nem létezik a .elf fájl.... Nem értem mi kínnya lehet. De mára sztem hagyom is mert már unom a sok nyavajgását. Hnap újult erővel elemzem a problémát.
(#) sgt válasza norbigal hozzászólására (») Nov 8, 2011 /
 
Csak tipp volt . Nagyon jó választás, mert online is tudsz debbugolni, ha eljutsz arra a szintre.

Először is melyik verziót tetted fel? 4.18-hoz tartozik 3 patch. Winavr-ból pedig a legújabb 2010.01.10-i kiadású. Ezeket telepítsd fel. Aztán próbáld meg újra. Mennie kellene.

Nem az F4-en vagyok, hanem Kohutnál az F1-en. Lehet hogy végül az F4-re kellett volna mennem, de most már mindegy.
(#) zombee válasza norbigal hozzászólására (») Nov 9, 2011 /
 
csak tipp, hogy a projekted útvonalában szóköz(pl. Documents and Settings) van.
Ez totálkár a WinAVR GCC-ben...
Következő: »»   376 / 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