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   375 / 840
(#) sgt válasza Ricsi89 hozzászólására (») Nov 3, 2011 /
 
Tehát be kellene vezetni egy segédváltozót, amit vizsgálsz és léptetsz, majd az OCR1A regisztert ezzel teszed egyenlővé.

Vagy kiszámolod, mennyit kell várni, mert ugye a timernek a frekvenciája adott .
(#) sikolymester válasza sikolymester hozzászólására (») Nov 3, 2011 /
 
Egy kis pontosítás.

Nem tudom melyik AVR-t használod, így feltételezem, hogy a méltán kedvelt atmega8-at.

Az adatlapból kiolvasható, hogy az általad használt fast pwm módban az OCR1x regisztert, akkor növeli, amikor a TCNT1 0-nál van.

Ezt tehát érdemes bekalkulálni az egész elképzelésbe.
És ismétlem, hogy rajzolj idődiagrammokat. Ilyen kis fűrészfog alakú valamik lesznek. Ha egymás alá rajzolod, akkor valami olyasmit látsz, amit a mellékelt móricka ábrámon láthatsz.

Hadd hangsúlyozzam ki, hogy direkt ilyen paint gányt rajzoltam. Ha felrajzolod az eredeti programod, akkor kapásból látod, hogy a fényerőváltoztatásod eredetileg olyan gyors volt, hogy a szem nem láthatta. A 3mp-es delayeddel pedig tényleg várhatsz rá órákat.

A programozás mindig egy kis tervezéssel kezdődik. Rajzolgatsz, számolgatsz excelben, majd miután tudod merre hány méter, megvalósítod.
A számolgatás végeredményben itt pl arra kell, hogy a pwm 50 Hz felett legyen, a fényerőváltoztatás pedig pár Hz körül.
(#) nolex hozzászólása Nov 4, 2011 /
 
Sziasztok!

Van egy Thunderbird fejlesztőpanelem és kiegészítő boardja.
A probléma a következő:
Assemblyben akarok beolvasni a billentyűzetről, de valamiért az 'stennek se akarja beolvasni...
Se interruptban, se végtelen ciklusban nem lehet kezelhetően beolvasni vele: az 1 2 3 gombot még beolvassa, de ha a következő sorra akarok ugrani ott már hibázik. Ha JTAG-gel végig lépkedem a sorokat, rendesen beírja... Most ami ide be van másolva, az azt csinálja hogy ha nyomkodom az 1 2 3 gombot akkor a másik digiten is egy időben ugrál a 4 5 6...Eddig sehogy se tudtam mindegyik sort ezzel az algoritmussal beolvasni. Ötlet?
  1. .INCLUDE "m128def.inc"                
  2.  
  3. .DSEG
  4. ;--------------------
  5. ; VÁLTOZÓK
  6. ;--------------------
  7.  
  8. .CSEG
  9. ;--------------------
  10. ; PROGRAMKÓD TERÜLET
  11. ;--------------------
  12.  
  13. ;----------------------------------------
  14. ; DEFINÍCIÓS RÉSZ, HIVATKOZÁSOK
  15. ;----------------------------------------
  16. ;--------------------
  17. .def tmp = r20
  18. .def tmp2 = r21 ;7 szegmens frissítésére használt regiszterek
  19. .def cnt = r22
  20. ;--------------------
  21. .def tmp3 = r23
  22. .def tmp4 = r24
  23. .def allap =r25
  24.  
  25. .def d1 = r16
  26. .def d2 = r17
  27. .def d3 = r18
  28. .def d4 = r19
  29.  
  30. .ORG 0x00
  31. rjmpmain
  32. .ORG OC0addr
  33. rjmp refresh
  34. .ORG OC1Aaddr
  35.  ;rjmp beolv
  36.  
  37.  
  38.                      
  39. .ORG 0x100                    
  40. ;--------------------
  41. ; MACRO
  42. ;--------------------
  43. .macro disp_off
  44. clr tmp
  45. out PORTA,tmp
  46. .endmacro
  47. ;--------------------
  48. ; SUBRUTIN
  49. ;--------------------
  50. delay:
  51. ldi tmp4, 0xff
  52. ldi tmp3,0xFF
  53. l1:dec tmp3
  54. brne l1
  55. ret
  56. ;--------------------
  57. ; PROGRAM
  58. ;--------------------
  59.  
  60. main:
  61. ;--------------------
  62. ; STACK INIT
  63. ;--------------------
  64. ldi tmp, HIGH(RAMEND)
  65. out SPH, tmp
  66. ldi tmp, LOW(RAMEND)
  67. out SPL, tmp
  68.  
  69. ;--------------------
  70. ; INIT
  71. ;--------------------
  72. .macro init
  73. ldi tmp, 0xFF
  74. out ddra, tmp
  75. ldi tmp, (1<<DDC3)|(1<<DDC4)|(1<<DDC5)|(1<<DDC6)
  76. out ddrc,tmp
  77. ;refresh timer interrupt init
  78. ldi tmp,(1<<wgm01)|(1<<CS02)|(1<<CS01)
  79. out tccr0,tmp
  80. ldi tmp, 0x90
  81. out ocr0,tmp
  82. ;incrementing timer interrupt
  83. ldi tmp, (1<<wgm12)|(1<<CS11)|(1<<CS10) ;64 prescale  ctc mode
  84. out tccr1b,tmp
  85. ldi tmp, 0x00
  86. out ocr1ah,tmp
  87. ldi tmp, 0xF0
  88. out ocr1al,tmp
  89. ldi tmp,(1<<OCiE0) |(1<<ocie1a) ;interruptok engedélyezése
  90. out timsk,tmp    
  91.  
  92. sei
  93.  
  94. disp_off
  95. clr d1
  96. clr d2
  97. clr d3
  98. clr d4
  99. .endmacro
  100.  
  101.  
  102. ;MEGSZAKÍTÁSOK, INTERFACE, IDOZÍTOK
  103.  
  104. ;--------------------
  105. ; PROGRAM
  106. ;--------------------
  107. init
  108. ldi d1,1
  109. loop:
  110.  
  111. ldi tmp3,0x08
  112. out portc,tmp3
  113. in tmp4,pinc
  114. sbrs tmp4,0
  115. ldi d1,1
  116. sbrs tmp4 , 1
  117. ldi d1,2
  118. sbrs tmp4,2
  119. ldi d1,3
  120. cpi tmp4,0b00001111
  121. breq masodiksor
  122. jmp veg
  123. masodiksor:
  124. ldi tmp3,16
  125. out portc,tmp3
  126. in tmp4,pinc
  127. sbrs tmp4,0
  128. ldi d2,4
  129. sbrs tmp4 , 1
  130. ldi d2,5
  131. sbrs tmp4,2
  132. ldi d2,6
  133. veg:
  134. rjmploop
  135.  
  136. refresh:
  137. disp_off
  138. cpi cnt, 0
  139. breq firstdig
  140.  
  141. cpi cnt, 1
  142. breq seconddig
  143.  
  144. cpi cnt, 2
  145. breq thirddig
  146.  
  147. cpi cnt, 3
  148. breq fourthdig
  149.  
  150. default:
  151. inc cnt
  152. cpi cnt, 4
  153. breq nullaz
  154. reti
  155.  
  156. firstdig:
  157. mov tmp,d1
  158. andi tmp,0x0f
  159. mov tmp2,cnt
  160. swap tmp2
  161. or tmp,tmp2
  162. ldi tmp2,(1<<7) ; ORI tmp,0x80
  163. or tmp,tmp2
  164. out porta,tmp
  165. rjmp default
  166.  
  167.  
  168. seconddig:
  169. mov tmp,d2
  170. andi tmp,0x0f
  171. mov tmp2,cnt
  172. swap tmp2
  173. or tmp,tmp2
  174. ldi tmp2,(1<<7) ; ORI tmp,0x80
  175. or tmp,tmp2
  176. out porta,tmp
  177. rjmp default
  178.  
  179.  
  180. thirddig:
  181. mov tmp,d3
  182. andi tmp,0x0f
  183. mov tmp2,cnt
  184. swap tmp2
  185. or tmp,tmp2
  186. ldi tmp2,(1<<7) ; ORI tmp,0x80
  187. or tmp,tmp2
  188. out porta,tmp
  189. rjmp default
  190.  
  191.  
  192. fourthdig:
  193. mov tmp,d4
  194. andi tmp,0x0f
  195. mov tmp2,cnt
  196. swap tmp2
  197. or tmp,tmp2
  198. ldi tmp2,(1<<7) ; ORI tmp,0x80
  199. or tmp,tmp2
  200. out porta,tmp
  201. rjmp default
  202.  
  203. nullaz:
  204. clr cnt
  205. reti
(#) labu01wx hozzászólása Nov 4, 2011 /
 
Sziasztok!

Összeraktam egy RFID olvasót ID-12-vel, ami ABA Track 2 interfészen küldi az adatot az AVR-nek. Az órajel az AVR D2-es lábára érkezik, amivel az INT0 megszakítást váltja ki (egy olvasás alkalmával 106-szor). Az interfészen 5 bites csomagok érkeznek, ezért úgy gondoltam, hogy a 106. megszakítást felesleges lekezelni és így ki is jön a szabványos adatcsomag(pl.: a konzol első sora): 00;kártyakód?ellenőrzőkód00 .
Ha elkezdem feldolgozni a kapott adatot a 106. megszakítás előtt, akkor az első olvasáskor kapott adat jó, de az utánna lévők nem(viszont egyformák).
Szerintem a 106. megszakítás is lefut a tiltás és a 63ms-os várakozás ellenére is(a 330us-os periódusidő sokszorosa), ez debuggolás közben be is bizonyosodott.
Ha kivárom a 106. megszakítást és egyszerűen nem foglalkozom az ehez tartozó bittel, akkor mindin jól működik.
A kérdésem az, hogyan lehet, hogy lefut egy megszakítás, amikor az összes megszakítás le van tiltva?

  1. #define F_CPU 18432000
  2. #define IINT0 0
  3. #define IINT1 1
  4.  
  5. #define false 0
  6. #define true 1
  7.  
  8. #define bit(p,b) ((*p & 1<<b)>>b) //a *p Byte b bitjének értéke
  9.  
  10. #include <avr/io.h>
  11. #include <util/delay.h>
  12. #include <avr/interrupt.h>
  13. #include <avr/portpins.h>
  14. #include <util/atomic.h>
  15. #include <stdlib.h>
  16. #include "BtSpp.h"
  17.  
  18. volatile uint8_t * data;
  19. volatile uint8_t ib,iB, it; //ib: bit index(Byteon belül), iB:Byte index, it: lefutott megszakítások száma
  20.  
  21. #define ClearBuffer() \
  22. do{ \
  23. ib=7; \
  24. iB=0; \
  25. it=0; \
  26. for(uint8_t i=0; i<14; i++) *(data+i)=0; \
  27. }while(0)
  28.  
  29. int main(void)
  30. {
  31.  
  32. BtInit();
  33. EICRA|=1<<ISC01;// | 1<< ISC11 | 1<<ISC10;
  34. EIMSK|=1<<IINT0;//| 1<<IINT1;
  35. sei();
  36. data=(uint8_t *) malloc(14);
  37. ClearBuffer();
  38.     while(true);
  39. }
  40.  
  41.  
  42. ISR(INT0_vect)
  43. {
  44. ATOMIC_BLOCK(ATOMIC_RESTORESTATE) //a blokk futása alatt kikapcsolja a megszakításokat
  45. {
  46. if (!(PIND & 1<<PIN4)) *(data+iB)|=1<<ib; //bit beolvasása
  47. if (ib>0) ib--;
  48. else
  49. {
  50. ib=7;
  51. iB++;
  52. }
  53. it++;
  54. if(it==105) //a kivárt megszakítások száma
  55. {
  56.  
  57. for(uint8_t i=0; i<105; i+=5)
  58. {
  59. while(!(UCSR0A & 1<<UDRE0));
  60. UDR0='0'+ 8*bit((data+(i+3)/8),(7-(i+3)%8))+4*bit((data+(i+2)/8),(7-(i+2)%8))+2*bit((data+(i+1)/8),(7-(i+1)%8))+1*bit((data+i/8),(7-i%8)) ;
  61.  
  62. }
  63. while(!(UCSR0A & 1<<UDRE0));
  64. UDR0='\r';
  65. while(!(UCSR0A & 1<<UDRE0));
  66. UDR0='\n';
  67. _delay_ms(63);
  68. ClearBuffer();
  69. }
  70. }
  71. }

Putty.png
    
(#) sikolymester válasza nolex hozzászólására (») Nov 4, 2011 /
 
Őszintén szólva én nem vagyok az assembly nagy ismerője, így nem tudom mi történik és mi nem.

De a kérdésem azért a következő:
A gombok beolvasásánál gondoltál arra a jelenségre, amit pergésnek hívnak? Nem lehet, hogy ez okozza a gondod? A Jtag léptetésnél nyílvánvalóan nem lenne pergés, mivel egy-egy lépés között eltelhet pár tized másodperc.
(#) nolex válasza sikolymester hozzászólására (») Nov 4, 2011 /
 
Gondoltam a pergésre igen. ezt pl úgy küszöböltem ki, hogy csak minden 300ms-ban olvastatom be a lábakat(addig meg csak elmúlik a tranziens). És így is...
Most olvasom, hogy a portc-vel gondok vannak, ennek kell utána néznem.
Jut eszembe: amikor a jtag-et léptetem, akkor is magát a gombot használom, tehát megnyomom. És Azért sem lehet a pergés jelenségének tulajdonítani, mivel ha nagyon sokszor frissítem az állapotot, kvázi 10ms-onként, akkor is ugyanazt az értéket kellene beolvasnia...
(#) nolex válasza nolex hozzászólására (») Nov 4, 2011 /
 
No, de a JTAG interfész viszoont PortF-re kapcsolódik, tehát ez már nem lehet hiba...
(#) sikolymester válasza labu01wx hozzászólására (») Nov 4, 2011 /
 
Na, azt hiszem megértettem a kódod.

Nos, az észrevételek:

Mindent interruptban csinálsz, ez ne váljon rossz megszokássá.

A ClearBuffert nyugodtan deklarálhatod static inline függvénynek is.

"Szerintem a 106. megszakítás is lefut a tiltás és a 63ms-os várakozás ellenére"
Ezt, hogyan kell érteni? A delay-t végzi éppen, és beugrik megint az INT0 interruptvektorra?
(#) labu01wx válasza sikolymester hozzászólására (») Nov 4, 2011 /
 
Én csak a végeredményt láttam: ib=6, it=1, iB=0, tehát a ClearBuffer() után lefutott még egyszer az INT0. Ebből arra következtettem(feltéve, hogy az órajel után egyből indul az újabb megszakítás), hogy az adatküldésnek le kellett futnia 330us alatt, ami 9600 b/s sebességgel lehetetlen. Ezért szerintem a 106. megszakítás akkor hívódik meg, amikor újból engedélyezem a megszakításokat, addig mintha várakozott volna.
(#) labu01wx hozzászólása Nov 4, 2011 /
 
Megtaláltam a megoldást, az EIFR regiszterben kellett törölni az INT0-hoz tartozó bitet. Nem gondoltam volna, hogy nem csak a globális, de az INT0 interrupt kikapcsolásával is felhúzza a zászlót.
(#) Robi98 válasza sikolymester hozzászólására (») Nov 5, 2011 /
 
Köszönöm a pontosítást.
Kijavítottam a programot, de a LED még mindig csak világít. Most már tényleg nem tudom, hogy mi lehet a hiba.A kódban csak akkor változtatom az OCR1A értékét ha a timer counter regiszter(TCNT1)értéke 0.
Amúgy tényleg az ATmega8-at használom.
  1. while(1){
  2.  
  3. TCNT1=0;
  4.  
  5. OCR1A=255;
  6.  
  7. while(OCR1A!=0){
  8. if(TCNT1==0) OCR1A--;
  9. _delay_ms(100);
  10.  
  11. };
  12.  
  13. while(OCR1A!=255){
  14. if(TCNT1==0) OCR1A++;
  15. _delay_ms(100);
  16. };
  17. _delay_ms(5);
  18. };
  19. return(0);
  20. };
(#) Ricsi89 válasza Robi98 hozzászólására (») Nov 5, 2011 /
 
Egy dolog az, hogy mit akarsz az 1-es timerrel, amikor a 2-es timer a pwm. Másrészt a timer folyamatosan fut, tehát annak az esélye, hogy pont akkor lép a programod az if-es részhez, amikor pont nulla, elég kevés az esély. Az az if-es rész nem kell, hagyd meg a 100ms-os várakozást és lehet, hogy működni is fog.
(#) Robi98 válasza Ricsi89 hozzászólására (») Nov 5, 2011 /
 
De hát ezt nem értem.Ha az OCR1A regisztert csak akkor lehet módosítani amikor a timer értéke 0, akkor csak kell legaláb annyi, hogy TCNT2=0 a módosítás előtt.
Bár kipróbáltam, de így se működött.
  1. OCR1A=255;
  2. TCNT2=0;
  3.  
  4. while(OCR1A!=0){
  5. TCNT2=0;
  6. OCR1A--;
  7. _delay_ms(100);
  8.  
  9. };
  10.  
  11. while(OCR1A!=255){
  12. TCNT2=0;
  13. OCR1A++;
  14. _delay_ms(100);
  15. };
(#) sgt válasza Robi98 hozzászólására (») Nov 5, 2011 /
 
Kevered a két timert... OCR1A a Timer1-é, míg a TCNT2 a Timer2-é.

Ez így fullosan működik, de ATmega16A-ra készült, nem ATmega8-ra.

  1. #define F_CPU 1000000UL
  2.  
  3. #include <avr/io.h>
  4. #include <util/delay.h>
  5.  
  6. void init(void)
  7. {
  8. DDRD |= (1<<PD7);
  9.  
  10. TCCR2 |= (0<<WGM21)
  11.    | (1<<WGM20)
  12.    | (1<<COM21)
  13.    | (0<<COM20)
  14.    | (0<<CS22)
  15.    | (0<<CS21)
  16.    | (1<<CS20);
  17.    
  18. TCNT2 = 255;
  19. OCR2 = 50;
  20.  
  21. }
  22.  
  23. int main(void)
  24. {
  25. init();
  26.  
  27.     while(1)
  28.     {
  29.         while (OCR2 < 255)
  30. {
  31. TCNT2 = 0;
  32. OCR2++;
  33. TCNT2 = 255;
  34. _delay_ms(5);
  35. }
  36.  
  37. while (OCR2 > 1)
  38. {
  39. TCNT2 = 0;
  40. OCR2--;
  41. TCNT2 = 255;
  42. _delay_ms(5);
  43. }
  44.     }
  45. }
(#) Gery hozzászólása Nov 5, 2011 /
 
Sziasztok!

Egy olyan kérdésem volna, hogy PWM szabályozást valósítok meg, és ebben az esetben az Interrupt Registerrel mire való?

Üdv.:Gergő
(#) Robi98 válasza sgt hozzászólására (») Nov 5, 2011 /
 
Köszönöm!
Ez a kód már tényleg működik, csak annyit módosítottam rajta, hogy 100ms késleltetést 8ms késleltetésre állítottam és az OCR2 regiszter kezdőérték 0 legyen.Így már a szemnek is előnyösebb.
Csak azt szeretném megkérdezni, hogy timer1-el miért nem lehet PWM-ezni, ugyanis EBBEN a cikkben a timer1 A és B csatornájával vezérlik a motorokat.
(#) sikolymester válasza Gery hozzászólására (») Nov 5, 2011 /
 
Attól függ.

Van un. hardveres PWM, meg szoftveres PWM.

Előbbinél beállítasz mindent, majd "hátradőlsz" és elintézi magától a dolgokat. Az inicializáláson kívül tehát a füled botját sem kell mozdítani.

A szoftveres tehát mire való? Ha pl. nem elég neked egy AVR által nyújtott 2-3 hardveres PWM. Ekkor szoftverből kell elintézni a dolgokat. Monjduk, ha szeretnél egy 70%os kitöltöttségű jelet, akkor így jársz el: A compare interruptot beállítod a számláló 70%-ra. Amikor belép ebbe az interruptba, akkor kikapcsolod a LED-et. A timer túlcsordulás interruptban pedig visszakapcsolod.
(#) sikolymester válasza Robi98 hozzászólására (») Nov 5, 2011 /
 
Hogy ne lehetne!

Meg is írtam secc-pecc Atmega8-ra.
Biztos, hogy működik, mivel itt villog mellettem.
Mindkét csatornát használja, míg az egyiket lefele, a másikat felfele lépteti. Ugyanez a a hatás lenne elérhető, hogyha az egik invertáló, míg a másik nem invertáló lenne.

Ugyanakkor remekül látszik működése közben, hogy a LED jó gyorsan megközelíti fényereje csúcsát.

  1. #include <avr/io.h>
  2. #include <util/delay.h>
  3.  
  4. #define F_CPU 1000000UL
  5. enum A_Irany
  6. {
  7. A_IRANY_LEFELE,
  8. A_IRANY_FELFELE
  9. };
  10.  
  11.  
  12. void initOutput(void)
  13. {
  14. DDRB |= (1 << PB1) |//OC1A kimenet
  15. (1 << PB2);//OC1B kimenet
  16. }
  17.  
  18. void initPWM(void)
  19. {
  20. TCCR1A |= (1 << WGM10)|//Fast PWM 8bit
  21. (1 << WGM12)|//Fast PWM 8bit
  22. (1 << COM1B1)|//B Non inverting
  23. (1 << COM1A1); //A Non inverting
  24.  
  25. TCCR1B |=(1 << CS10);// No Prescaler
  26.  
  27. OCR1A = 0;//Compare output A
  28. OCR1B = 255;//Compare output B
  29. }
  30.  
  31. int main()
  32. {
  33. uint8_t irany = A_IRANY_FELFELE;
  34. initOutput();
  35. initPWM();
  36. for(;;)
  37. {
  38. _delay_ms(10);
  39. if (OCR1A == 255) irany = A_IRANY_LEFELE;
  40. if (OCR1A == 0) irany = A_IRANY_FELFELE;
  41.  
  42. switch (irany)
  43. {
  44. case A_IRANY_LEFELE:
  45. OCR1A--;
  46. OCR1B++;
  47. break;
  48.  
  49. case A_IRANY_FELFELE:
  50. OCR1A++;
  51. OCR1B--;
  52. break;
  53.  
  54. default:
  55. break;
  56. }
  57. }
  58.  
  59. }

main.c
    
(#) sgt válasza Robi98 hozzászólására (») Nov 5, 2011 /
 
Igazából nem tudom miért írták ezt.

Sajnos készülj fel, hogy lesznek még ilyen hülyeségek, más perfiériáknál is , és ez mikrokontroller független. Mindenféle fajta mikrokontrollernek a perifériájának meg vannak a saját hülyeségei, ami ilyen piti példákban jönnek elő. Majd idővel, amikor többet gyakorolsz, akkor rögtön fognak jönni az ilyenek. Szval fel a fejjel, és csak ügyesen .
(#) sikolymester válasza sgt hozzászólására (») Nov 6, 2011 /
 
Idézet:
„Igazából nem tudom miért írták ezt.”


Most mire gondolsz, amit írtak?
Azt, hogy a Timer1 A,B csatornájával vezérelnek motorokat?
(#) Gery válasza sikolymester hozzászólására (») Nov 6, 2011 /
 
Értem.
Amúgy egy AVR32 UC3B1256-ot programozok. Egyenlőre egy spi kommunikációt valósítottam meg rajta spi.h header file-al. Most néztem egy pwm.h-t de nincs külön leírás a channel_t beállításaihoz és nem tudom hogyan kéne beállítani pl a channel alignment stb. Tudsz esetleg mutatni egy mintaprogramot vagy valamit amiből elindulok?

Üdv.:Gergő
(#) Reggie válasza Gery hozzászólására (») Nov 6, 2011 / 1
 
AVR Studioban: File->New->AVR Example Project
Itt az AT32UC3B0256 listajat bontsd ki es lesz egy ilyen lehetoseg: EVK1101 - DRIVERS - Pulse Width Modulation (PWM) example.
A 32 bites avr-ek headerjei altal mashogy lehet elerni a periferiakat, mint ahogy a 8 bitesnel megszoktad. Itt minden strukturakba(a sorszamozott periferiak/regiszterek, tehat ami egyforma de tobb van, azok tombokbe) van rendezve. A strukturan beluli kis betus elemek az adatlapban megtalalhato regiszterekre mutatnak es mindegyik uint32_t tipusu. Peldaul az avr32_pwm_channel_t tipus ccnt eleme az adatlapban 547. oldalon talalhato CCNTx regisztert kepzi le. A cupd az 548. oldalon talalhato CUPDx regisztert kepzi le, es igy tovabb. A nagy betus elemek szinten regiszterekre mutatnak, de ezek nem uint32_t tipusuak, hanem strukturak. Ezekben a strukturakban a regiszter bitjei vagy bitmezoi vannak lekepezve az elnevezesuk szerint. Peldaul az avr32_pwm_channel_t tipuson belul talalhato CMR elnevezesu struktura (melynek tipusa avr32_pwm_cmr_t) az adatlap 543. oldalan talalhato regisztert kepzi le es a strukturan beluli peldaul cpol az adatlapban is lathato CPOL bitet jelenti. Tehat ha a gyari fuggvenykeszletet hasznalva szeretned a csatornat konfiguralni, akkor deklaralnod kell egy valtozot es azt feltolteni:
  1. avr32_pwm_channel_t pwm_ch; //itt deklaralod
  2. pwm_ch.cprd=50; /*itt megadod, hogy mi legyen a CPRDx regiszter tartalma */
  3. pwm_ch.cmr=4; /* igy megadod, hogy a CMRx regiszter tartalma */
  4. pwm_ch.CMR.cpol=1; /* ha igy csinalod, akkor csak CMRx regiszteren belul a CPOL bitet irod at */
  5. pwm_channel_init(channel_id, &pwm_ch); /* igy inicializalod a pwm csatornat a gyari kodokkal, a csatorna szamat a channel_id tartalmazza, ami a te IC-d eseten 0 vagy 1 lehet */

Termeszetesen, ha az init utan irod at a pwm_ch valamelyik elemet, akkor annak nem lesz hatasa.
Ha a uC valamelyik regiszteret vagy regiszterenek a bitjet el szeretned erni, azt is megteheted. Peldaul a cpol bitet a 0-as csatornan kozvetlenul igy lehet allitani:
  1. AVR32_PWM.channel[0].CMR.cpol=1;
(#) Reggie válasza Gery hozzászólására (») Nov 6, 2011 / 1
 
Tovabba: a strukturak konnyu felterkepezesehez: Irjad be peldaul, hogy AVR32_PWM. es a pont leutese utan tartsd lenyomva a shift billentyut. Ekkor felugrik egy legordulo menu, amiben a struktura elemei vannak felsorolva. A Timer/Counter modulhoz az AVR32_TC tartozik, az SPI-hez az AVR32_SPI, es igy tovabb.
(#) Gery válasza Reggie hozzászólására (») Nov 6, 2011 /
 
Szia!

Teljesen még mindig nem értem sajnos.
Mellékelek egy képet a programom részletéről. Elsőnek a pwm_options_t struktúrát beállítom, azzal elvileg nincs baj. Aztán beállítom a pwm_channel_t és pwm_cmr_t -t. A két bekeretezett rész arra utalna, hogy teljesen mindegy melyik módon írom igaz, ugyanazt jelenti?
A problémám azzal van, hogy a pwm_channel_init() parancs behozása fogja konfigurálni a pwm-et jól gondolom? És ide a pmw_channel_t struktúrát írom be, de azzal önmagában a CMRx regiszter nem konfigurálom. Viszont ha például .CMR.cpol=1 -et vagy bármi mást írok a channel-hez azt nem fordítja le (pl a képen is látható).
/remélem érthető a problémám.../

Üdv.:Gergő

Névtelen.jpg
    
(#) Reggie válasza Gery hozzászólására (») Nov 6, 2011 / 1
 
avr32_pwm_cmr_t -t nem kell kulon csinalnod, mert az megvan az avr32_channel_t -ben is.
Igy kene:
  1. void main(void) {
  2.   ...
  3.   avr32_pwm_channel_t pwm_ch = {
  4.     .cdty=6,
  5.     .cprd=60,
  6.     .cupd=0,
  7.     .CMR.cpol=PWM_POLARITY_LOW
  8.   };
  9.   pwm_init(channel,&pwm_ch);
  10.   ...
  11. };

Szerintem te felreertetted egy kicsit amit mondtam. Ha csinalsz egy static const -kent egy valtozot a csatornanak, akkor az nem fog a regiszterre mutatni. Csak ugyan olyan lesz a strukturaja. Ha te az ott megadott erteket szeretned beleirni a regiszterekbe, akkor kell csinalni egy
  1. AVR32_PWM.channel[channel]=pwm_ch;

ertekadast. A regiszterekre konkretan az AVR32_PWM strujkura mutat, a channel regiszterekre konkretan az AVR32_PWM.channel[] tomb mutat. de a te pwm_ch valtozod es a static const-kent deklaralt PWM_CHANNEL valtozod sem mutat oda. Csak ugyan az a tipusuk igy ertekadasra hasznalhatoak.
(#) Robi98 hozzászólása Nov 7, 2011 /
 
Sziasztok!
Most írtam egy kódot aminek az lenne a feladata, hogy bekéri egy potméter értékét és átadja az OCR1A regiszternek.Tehát amikor tekerem a potmétert a LED fényének is úgy kéne nőni/csökkenni ahogy én azt tekerem.A kódot többször is átellenőriztem, de se a fordító, se én nem találtam benne hibákat.A ved pedig aminek világítani kéne abszolút nem világít.
Itt a kód:
  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<<PB1);//PB1 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. TCCR1B|=(1<<CS10);//1-es timer előosztás
  21. TCCR1A=(1<<WGM10)|(1<<COM1A1);//nem invertált gyors PWM
  22.  
  23. OCR1A=0;//komparátor szintet nullázuk
  24.  
  25. while(1){
  26.  
  27. TCNT1=0;//timert nullázuk
  28.  
  29. OCR1A=ADConverter(1);//az ADC mérés eredményét átadjuk a komparátornak
  30.  
  31. }
  32. _delay_ms(1);
  33. return(0);
  34. }
(#) sgt válasza Robi98 hozzászólására (») Nov 7, 2011 /
 
Látom nem adod fel . Nagyon helyes. Ezzel én is próbálkoztam még tavaly, de nem sok sikerrel.

Hirtelen végig nézve, van benne egy elvi hiba. Te minden ciklusban változtatod késleltetés nélkül, és úgy hogy mindig kikapcsolod a Timert, és mindezt úgy, hogy be sem kapcsolod.
(#) Gery válasza Reggie hozzászólására (») Nov 7, 2011 /
 
Nos lassan talán összeáll a kép. Viszont egy olyan problémám van ami a képen is láthatsz, hogy a ".CMR"-t nem fogadja el a fordító, pedig az src könyvtárba betöltöttem a pwm.h és a pwm.c fájlokat. Vagy azt valami más tartalmazná?

Mert egy spi kommunikációt már megvalósítottam az itt leírtak segítségével, viszont pwm-hez nem találtam jót.
Aztán eszembe jutott az evk1101 example. Ez nagyjából átlátható számomra is, de úgy veszem ki, hogy a Channel Mode Register-t a pwm.channel-ben állítja egy .CMR előtaggal ami nekem nem fordul le.
Szerinted mit kéne tennem? Vagy írjak magamtól ezek a header fájlok nélkül?( Csak azzal az a baj, hogy úgy nem is tudom hogy kéne elkezdenem.)

Üdv.:Gergő
(#) sikolymester válasza Robi98 hozzászólására (») Nov 7, 2011 /
 
Minek mérsz kétszer az ADC modullal?
A TCNT1 értékét minek babrálod hardveres pwm-nél? Ha jól van beállítva a timerben a pwm modul, akkor nincsen dolgod azon kívül, hogy állítasz a komparálási értéken, hogyha úgy kívánod.
(#) Gery válasza Gery hozzászólására (») Nov 7, 2011 /
 
Bocsánat a kép lemaradt.

pwm.jpg
    
Következő: »»   375 / 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