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   484 / 840
(#) Reggie válasza prody hozzászólására (») Szept 24, 2012 /
 
Ez igy elegge tag. Pl. ezt szoktak ilyenre hasznalni.
(#) sikolymester válasza prody hozzászólására (») Szept 24, 2012 /
 
(#) prody válasza Reggie hozzászólására (») Szept 24, 2012 /
 
Hát igen ez azért eléggé nem lowcost
Képfeldolgozás alatt arra gondoltam, hogy elég ha mondjuk 0,3 másodpercenként kiértékel egy képet. Mivel még ilyet nem csináétam nem tudom hogy pl. egy ARM11 elég-e erre a feladatra? pl ez: http://www.arm9board.net/sel/prddetail.aspx?id=348&pid=200
(#) Auf válasza sikolymester hozzászólására (») Szept 24, 2012 /
 
Nekem már van Pi-m, de még a fiókban van. Csak megnézés fázison esett át. Ez nagyon off...
(#) Reggie válasza prody hozzászólására (») Szept 24, 2012 /
 
Hat attol fugg, mit szeretnel kiertekelni. Egy jobb kepfelismero program (rendszam es auto pozicijanak erzekelese) egy kozepes Pentium 3 konfigon fut el. Az Atmel termekei kozul a SAM9-es ARM-ok viszik a linuxot. Viszi az AT32AP is, viszont ez a termekvonal megszunik, mert csak a sajat ARM-jaiknak csinalt konkurenciat.
Esetleg ha jobban erdekel az FPGA, akkor vehetsz Spartan6-os fejlesztopanelt. Egy XC6SLX45-os FPGA-ba belefer egy softcore proci (LEON3), amin fut a linux es meg szabadon marad az FPGA fele. Egy ilyen panel kb. 180 euro+tapegyseg.
A hozzászólás módosítva: Szept 24, 2012
(#) prody válasza Reggie hozzászólására (») Szept 25, 2012 /
 
FPGA-t annyira nem szeretem, tudom gyorsabb meg rengeteg előnye van, csak egész egyszerűen nekem nem szimpatikus, illetve nincs is akkora tapasztalatom benne, hogy nyugodtan neki merjek vágni.
A szavaidból azt veszem ki, hogy az általam linkelt konfiguráció már tökéletesen elég arra a célra amire nekem szükségem van, árban is korrektebbnek tűnik.
Még sosem használtam LINUX-ot futtató magot, szóval ezért is tettem fel a kérdést. De mivel tudom, jól, hogy ebben van a jövő, szeretném odahaza kisebb feladatokra is használni.
Első körben egy egyszerű valamilyen szenzor parkot telepítek a szobába és annak a kiértékelt eredményeit küldeném egy webes felületre mondjuk. A lényeg hogy ezzel foglalkozzak kicsit. Későbbiekben az lenne a cél, hogy képfeldolgozásra kiértékelésre használjam.
(#) csabeszq válasza balux33 hozzászólására (») Szept 25, 2012 /
 
Hát, nekem az AVR fordító csinál érdekes dolgokat.

uint8_t portbit=2;
PORTB |= _BV(portbit);

hivatkozást ahogy láttam 16 biten fordította. Pedig sem a PORTB sem a portbit nem 16 bites.
A hozzászólás módosítva: Szept 25, 2012
(#) Reggie válasza prody hozzászólására (») Szept 26, 2012 /
 
Esetleg megprobalhatsz kinabol rendelni valami olcso cortex a8/9/10/11 alapu SoC-cal felszerelt androidos modult. Vagy a vegen marad a raspberry, ha van fel eved varni a megerkezesre
(#) zombee válasza csabeszq hozzászólására (») Szept 26, 2012 /
 
Az AVR utasításkészlete (azaz 1 elemi utasítás) 16 bites(2 bájt). Mi is itt a kérdés?
Ja igen: ha változót definiálsz, azt az SRAM-ba teszi, pontosabban a STACK-re.
Ez 2 vagy 3 utasítás. Ha közvetlen utána írod a PORTB-re, 1 utasításba belefér(optimalizál).
(#) csabeszq válasza zombee hozzászólására (») Szept 26, 2012 /
 
AVR-libc FAQ:

Why does the compiler compile an 8-bit operation that uses bitwise operators into a 16-bit operation in assembly?

Bitwise operations in Standard C will automatically promote their operands to an int, which is (by default) 16 bits in avr-gcc.

To work around this use typecasts on the operands, including literals, to declare that the values are to be 8 bit operands.

This may be especially important when clearing a bit:

var &= ~mask; /* wrong way! */

The bitwise "not" operator (~) will also promote the value in mask to an int. To keep it an 8-bit value, typecast before the "not" operator:

var &= (unsigned char)~mask;

(#) Reggie válasza csabeszq hozzászólására (») Szept 26, 2012 /
 
Ha a -mint8 kapcsolot megadod az avr-gcc-nek, akkor 8 bit az alapertelmezett.
(#) csabeszq válasza Reggie hozzászólására (») Szept 26, 2012 /
 
Hát, ezt kihagynám. Az intnek azért legyen rendes mérete. Inkább kasztolgatok.
(#) Reggie válasza csabeszq hozzászólására (») Szept 27, 2012 /
 
Mondjuk ez nekem 8 bitesnek fordul le. Siman sbi 0x18,2 lesz a produkalt kod. (-O2 mellett)
(#) csabeszq válasza Reggie hozzászólására (») Szept 28, 2012 /
 
> sbi 0x18,2

Hát, akkor valamit nagyon elírtál. Próbáld a kettőt változóba rakni, úgy hogy véletlenül se optimalizálja ki.

for(i=0; i< 7; i++)
PORTB |= _BV(i);

Én -Os-t használok, 4.3 vagy 4.4 alól. Állítólag a 4.7-től már a hiba javítva van. Mindenesetre nekem mindig 16 bites, a kasztolás sem segített.

(#) zombee válasza csabeszq hozzászólására (») Szept 28, 2012 /
 
És ha ezt tennéd ki?
  1. PORTB |= 1<<i;
(#) Reggie válasza csabeszq hozzászólására (») Szept 28, 2012 /
 
Valtozoba raktam, es ugy csinalta. Nem irtam el rajta semmit. -Os es -O2 is ugyan ezt az eredmenyt adja. A verzio 4.7.0, de minek hasznalna az ember regit, ha az hibas...
A hozzászólás módosítva: Szept 28, 2012
(#) csabeszq válasza Reggie hozzászólására (») Szept 29, 2012 /
 
Ha változó lett volna, nem pedig konstans, akkor nem sbi 0x18,2-t fordított volna.

(#) Reggie válasza csabeszq hozzászólására (») Szept 29, 2012 /
 
Mondom, hogy valtozoban volt, raadasul a main fuggvenyen kivul deklaralva. Egyszeruen kioptimalizalta. Vedd figyelembe, hogy masodik alkalommal kicsit mas kodot irtal le.
A hozzászólás módosítva: Szept 29, 2012
(#) Reggie válasza csabeszq hozzászólására (») Szept 29, 2012 /
 
Megneztem a for ciklussal is. Ott is optimalizalta, egyedul egy movw maradt benne a kezdoertek betolteskor, de az aritmetikai muveleteket, stb. mar 8 biten vegzi. A movw es a mov ugyan ugy 1 orajel alatt lemegy...
A hozzászólás módosítva: Szept 29, 2012
(#) csabeszq válasza Reggie hozzászólására (») Szept 29, 2012 /
 
Oké, pongyola voltam. A nem jel (hullám) nem jött át megfelelően, azt javítsátok.

  1. #define F_CPU 16000000UL
  2. #include <avr/io.h>
  3.  
  4. void set_bits(uint8_t bit, uint8_t value) {
  5.   if( value )
  6.     PORTD |= _BV(bit);
  7.   else
  8.     PORTD &= ~_BV(bit);
  9. }
  10.  
  11. int main(void) {
  12.   set_bits(7,1);
  13. }


A remekmű fordítás után:

  1. void set_bits(uint8_t bit, uint8_t value) {
  2.   a6:   38 2f           mov     r19, r24
  3.   if( value )
  4.   a8:   66 23           and     r22, r22
  5.   aa:   59 f0           breq    .+22            ; 0xc2 <set_bits+0x1c>
  6.     PORTD |= _BV(bit);
  7.   ac:   2b b1           in      r18, 0x0b       ; 11
  8.   ae:   81 e0           ldi     r24, 0x01       ; 1
  9.   b0:   90 e0           ldi     r25, 0x00       ; 0
  10.   b2:   02 c0           rjmp    .+4             ; 0xb8 <set_bits+0x12>
  11.   b4:   88 0f           add     r24, r24
  12.   b6:   99 1f           adc     r25, r25
  13.   b8:   3a 95           dec     r19
  14.   ba:   e2 f7           brpl    .-8             ; 0xb4 <set_bits+0xe>
  15.   bc:   28 2b           or      r18, r24
  16.   be:   2b b9           out     0x0b, r18       ; 11
  17.   c0:   08 95           ret
  18.   else
  19.     PORTD &= ~_BV(bit);
  20.   c2:   2b b1           in      r18, 0x0b       ; 11
  21.   c4:   81 e0           ldi     r24, 0x01       ; 1
  22.   c6:   90 e0           ldi     r25, 0x00       ; 0
  23.   c8:   02 c0           rjmp    .+4             ; 0xce <set_bits+0x28>
  24.   ca:   88 0f           add     r24, r24
  25.   cc:   99 1f           adc     r25, r25
  26.   ce:   3a 95           dec     r19
  27.   d0:   e2 f7           brpl    .-8             ; 0xca <set_bits+0x24>
  28.   d2:   80 95           com     r24
  29.   d4:   82 23           and     r24, r18
  30.   d6:   8b b9           out     0x0b, r24       ; 11
  31.   d8:   08 95           ret
A hozzászólás módosítva: Szept 29, 2012
(#) Reggie válasza csabeszq hozzászólására (») Szept 30, 2012 /
 
Fura. Nalam ez:
  1. #include <avr/io.h>
  2.  
  3. uint8_t portbit;
  4.  
  5. void main(){
  6.   for(portbit=0;portbit<6;portbit++) PORTB|=~_BV(portbit);
  7. }

Igy fordul le:
  1. 000000b4 <main>:
  2.   b4:   10 92 00 01     sts     0x0100, r1
  3.   b8:   81 e0           ldi     r24, 0x01       ; 1
  4.   ba:   90 e0           ldi     r25, 0x00       ; 0
  5.   bc:   0d c0           rjmp    .+26            ; 0xd8 <main+0x24>
  6.   be:   58 b3           in      r21, 0x18       ; 24
  7.   c0:   9c 01           movw    r18, r24
  8.   c2:   04 2e           mov     r0, r20
  9.   c4:   01 c0           rjmp    .+2             ; 0xc8 <main+0x14>
  10.   c6:   22 0f           add     r18, r18
  11.   c8:   0a 94           dec     r0
  12.   ca:   ea f7           brpl    .-6             ; 0xc6 <main+0x12>
  13.   cc:   20 95           com     r18
  14.   ce:   25 2b           or      r18, r21
  15.   d0:   28 bb           out     0x18, r18       ; 24
  16.   d2:   4f 5f           subi    r20, 0xFF       ; 255
  17.   d4:   40 93 00 01     sts     0x0100, r20
  18.   d8:   40 91 00 01     lds     r20, 0x0100
  19.   dc:   46 30           cpi     r20, 0x06       ; 6
  20.   de:   78 f3           brcs    .-34            ; 0xbe <main+0xa>
  21.   e0:   08 95           ret


Szerintem terjel at a 4.7.0-ra.
(#) Adam329 hozzászólása Okt 1, 2012 /
 
Hello!

Azt szeretném megtudni, hogy az ADC mintavételezési sebességébe bele kell-e kalkulálna azt, hogy 13 ciklust vesz igénybe egy konverzió?
Ha a mikrovezérlő 8MHz órajellel működik és az ADPS biteket úgy állítottam be, hogy 64-el ossza el, akkor az ADC mintavételezés frekvenciája 125kHz. Ezt még el kell osztanom 13-mal vagy nem?
(#) Reggie válasza Adam329 hozzászólására (») Okt 1, 2012 /
 
Az a 125kHz az ADC orajele es nem a mintavetelezes frekvenciaja. Az ADC-nek 13 ADC orajelbe kerul, mig csinal egy konverziot. Azaz el kell osztani 13-mal.
(#) Adam329 hozzászólása Okt 1, 2012 /
 
Köszönöm!

Free running módhoz tudtok jó leírást?
Egy FFT algoritmushoz szeretnék megtölteni egy N hosszúságú tömböt mintákkal.
Jelenleg így csinálom:

  1. for(int i=0; i<N; ++i)
  2. {
  3.    ADCSRA |= (1<<ADSC);                
  4.    while (ADCSRA & (1<<ADSC))
  5.    real[i] =ADCW-512;                  
  6.    imag[i]=0;                                          
  7. }


Úgy gondolom hatékonyabb lenne ha csak akkor vételezne újabb N számú mintát ha már az előzőn lefutott az FFT.
(#) Reggie válasza Adam329 hozzászólására (») Okt 1, 2012 /
 
Szerintem inkabb hasznaljak ket puffert, es amig az egyiket az ADC megszakitasaval toltod, addig a masikat tudod szamolni. Csak arra kell ugyelni, hogy ne gyujtsel gyorsabban adatot, mint feldolgozod vagy szemaforokkal szinkronizald a ket muveletet. Nem tudom milyen mennyisegu adatot szeretnel igy feldolgozni, de igazabol erre mar inkabb az AVR32 valo, mert rendelkezik DSP utasitasokkal es peldaul a szorzas+akkumulacio egy utasitassal megvan.
A hozzászólás módosítva: Okt 1, 2012
(#) zombee válasza Adam329 hozzászólására (») Okt 1, 2012 /
 
Interruptot rendelsz hozzá ami letárolja a mért értéket, majd újra elindítja a konverziót.
A hardveres free-running lényegében annyi hogy az ADC kiolvasásakor új ciklust indít, semmi komoly.
Ezt Te magad is megoldhatod, így nem kell free-running módba kapcsolni.
Ha így teszel akkor interruptból le is állíthatod: "ha X minta van, nem indít új konverziót"

Nem kell feltétlenül interruptot használni, ha a mintavételezés alatt nem csinál mást a cucc.

Mintavételezés: 20ksps-nél NE állíts be nagyobb mintavételi frekit mert hibás lesz az eredmény!
Tehát 8MHz esetében az előosztó minimum 8000000/13/20000~=30 (tehát 32).
Ha 2 csatornát felváltva használsz...
1: arányosan csökkenteni kell a mintavételi frekit: max. 10ksps 2 csatornánál, 6.6ksps 3 csatornánál...
2: az ADMUX beállítása és új konverzió indítása között legalább 300us-nek el kell telnie!
A hozzászólás módosítva: Okt 1, 2012
(#) Reggie válasza zombee hozzászólására (») Okt 1, 2012 /
 
Az eredmeny mindig hibas, csak kerdes, hogy mekkora merteku a hiba Nyilvan az ADC orajel csokkentesevel csokken a hiba.
(#) Adam329 hozzászólása Okt 1, 2012 /
 
Köszönöm a válaszokat.

ATmega2560-ason írom, egy csatornát használok.
Jelenleg így néz ki. Gombnyomásra indul és áll le a folyamat azért van megszakítás.
Elméletileg nem csinál semmit mintavételezés közben, akkor ez azt jelentené, hogy nem szükséges az ADC megszakításokkal való kezelése?

  1. int main(void)
  2. {
  3.         EICRA |= (1<<ISC00)|(1<<ISC11);                                                        
  4.         EIMSK |= (1<<INT0)|(1<<INT1);                          
  5.         sei();
  6.        
  7.         UART_Config();
  8.         ADC_Config();
  9.        
  10.         int real[N];
  11.         int imag[N];
  12.        
  13.     while(1)
  14.     {
  15.                 while(on==1)
  16.                 {
  17.                         for(int i=0; i<N; ++i)
  18.                         {
  19.                                 ADCSRA |= (1<<ADSC);                   
  20.                                 while (ADCSRA & (1<<ADSC));    
  21.                                 real[i] =ADCW-512;                     
  22.                                 imag[i]=0;                                             
  23.                         }
  24.                        
  25.                         fft(real,imag,M);
  26.                        
  27.                         for (int i = 0; i < N/2; i++)
  28.                         {
  29.                                 real[i] =sqrt((long)real[i] * (long)real[i] + (long)imag[i] * (long)imag[i]);
  30.                         }                              
  31.                        
  32.                         for (int i = 0; i< N/2; ++i)
  33.                         {
  34.                                 while (!(UCSR0A & (1 << UDRE0)));
  35.                                 UDR0 = real[i];
  36.                         }
  37.                 }                        
  38.     }
  39. }


A problémám az, hogy az FFT algoritmus helyes spektrumot ad ha olyan tömbökön futtatom le amiket én töltöttem fel szinusz/négyszög/háromszög hullámoknak megfelelő értékekkel, viszont ha egy függvénygenerátort kötök rá és valós jeleket adok az algoritmusnak, helytelen spektrumot kapok.
Azt tudom, hogy a mintavételezési frekvenciának legalább duplájának kell lennie a mérni kívánt jel frekvenciájánál. A mérést ennek megfelelően végeztem, számításba vettem azt is, hogy az ADC órajelét el kell osztanom 13-mal de így sem jó.
Nem tudom mi lehet a gond.
(#) Reggie válasza Adam329 hozzászólására (») Okt 1, 2012 /
 
A megszakitas akkor celszeru, hogyha a konverzio alatt is szeretnel muveletet vegezni. Ha nem, akkor az "ADC Noise Reduction Sleep" hasznalata a celszeru, mert pontosabb lesz a mintavetelezett jel erteke.

Kulso jelforrasnal eloszor szerintem ne az FFT-t probald, hanem rajzold ki a memoriaban levo jel alakjat, igy lathatod, hogy a mintavetelezessel minden rendben van-e.
Az analog bemenetre mindenkeppen tegyel egy alulatereszto szurot, aminek a vagasi frekvenciaja a mintavetelezesi frekvencia fele. Altalaban ez szokott hibat okozni. Ezen felul a kvantalasi zaj miatt mindig lesz valamennyi hiba, de ez eleg kicsi es elvileg egyenletes eloszlassal jelentkezik a teljes spektrumban.
A hozzászólás módosítva: Okt 1, 2012
(#) Adam329 hozzászólása Okt 2, 2012 /
 
Ablak függvény alkalmazására is gondoltam de azt nem nagyon tudom, hogy kéne megvalósítani.
Következő: »»   484 / 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