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   680 / 840
(#) yoman917 válasza Zsolt2 hozzászólására (») Júl 13, 2015 /
 
ASCII karakterek. Igazából az okozza a legnagyobb gondot, hogy hogyan kell összefűzni a beérkező bájtokat egy tömbbe. A beérkező adatokat megszakításban kezelem, így még az strcat sem tud szóba jönni, mert a globális változókat nem szereti
(#) Zsolt2 válasza yoman917 hozzászólására (») Júl 13, 2015 /
 
Definealsz egy globalis valtozot, amit nullaval inicializalsz. A bejovo karakter megszakitasban a szamlalo index-ertekere beirod az aktualisan bejovo karaktert es noveled a szamlalot.
  1. volatile unsigned int cnt;
  2. volatile char uart_rx[100];
  3. ...
  4. ISR(USART_RXC_vect)
  5. {
  6.  uart_rx[cnt] = UDR;
  7.  //uart_rx[cnt+1] = '\0';
  8.  cnt++;
  9. }
  10. ...
  11. void main ()
  12. {
  13.   ...
  14.   while (1)
  15.   {
  16.     ...
  17.     //bejovo adatok feldolgozasa
  18.    cnt = 0;
  19.     ...
  20.   }
  21. }

Ha akarod hasznalni a standard string muveleteket, akkor a megszakitasban a kovetkezo karakternek meg be kell irni '\0'-t (kikommentelt sor).
A hozzászólás módosítva: Júl 13, 2015
(#) yoman917 válasza Zsolt2 hozzászólására (») Júl 13, 2015 1 /
 
Köszönöm a segítséget. A problémám a fenti kódsorral, hogy én eddig így hivatkozok a létező táblázatomra: tablazat[1]=23456, itt pedig a hivatkozás egy adatbájtot ad vissza (pl uart_rx[1]='1'). Ezt a problémát hogyan lehetne leküzdeni?
(#) Zsolt2 válasza yoman917 hozzászólására (») Júl 13, 2015 / 1
 
Vissza kell alakitani oket binaris adatta. A megszakitasban figyeled, hogy mikor jon a vesszo es akkor befejezed a mentest es atalakitod a szamot.
  1. ISR(USART_RXC_vect)
  2. {
  3.  uart_rx[cnt] = UDR;
  4.  if (uart_rx[cnt] = ',')
  5.  {
  6.    uart_rx[cnt] = '\0';
  7.    tablazat[x] = atoi (uart_rx);
  8.    cnt = 0;
  9.   }
  10.   else
  11.    cnt++;
  12. }
(#) yoman917 válasza Zsolt2 hozzászólására (») Júl 13, 2015 /
 
Remélem működni fog, mert elég ígéretesnek tűnik, köszönöm a segítséget!
(#) rasty hozzászólása Júl 13, 2015 /
 
Sziasztok!
Most kezdtem kísérletezni az avr bemeneteivel és azt vettel észre, hogy az avr azt is érzékeli, ha hozzáérek a bemeneti lábhoz.
A kérdésem, hogy hogyan lehetne ezt az érzékenységet csökkenteni?
(#) csatti2 válasza rasty hozzászólására (») Júl 13, 2015 /
 
Fújd be műanyag spray-el...
Ne nyúlkálj hozzá...
Húzd le/fel a lábat ellenállással...
stb.
(#) rasty válasza csatti2 hozzászólására (») Júl 13, 2015 /
 
Mekkora fel/le húzó ellenállást javasolsz?
(#) csatti2 válasza rasty hozzászólására (») Júl 13, 2015 /
 
Nem tudom mit kötsz rá. Lehet elég ha bekapcsolod a beépített felhúzó ellenállást (mondjuk az elég nagy, a kezed lehet becsaphatja).

De a legjobb megoldás ha a végén befújod plastik 70-el vagy hasonlóval.
A hozzászólás módosítva: Júl 13, 2015
(#) rasty válasza csatti2 hozzászólására (») Júl 13, 2015 /
 
Köszi.
(#) kapu48 válasza rasty hozzászólására (») Júl 13, 2015 /
 
Legjobb, ha nem nyúlkálsz hozzá!
Mert műszálas göncben a statikus feltöltődésed több 100V is lehet!
És meghal az AVR-ed!
(#) Droot hozzászólása Júl 14, 2015 /
 
Sziasztok!

Adott egy portom, legyen mondjuk PORTB. A PB0-t bemenetként használom, a többit mind kimenetként, és egy tömbben tárolom a 8 bites adatokat amiből értéket kap.
Úgy szeretném a PORTB bitjeit módosítani, hogy a PB0 ne változzon.
Tegyük fel a 0b01001100 bitsorozatot szeretném beletenni. Hogyan kell kimaszkolni, hogy a PB0 ne legyen nulla, hanem azt ne változtassa?
(#) killbill válasza Droot hozzászólására (») Júl 14, 2015 /
 
Igy megtartja a PORTB legalso bitjenek erteket. (uj_ertek-ben az also bit nulla kelle legyen!!!)
PORTB = (PORTB & 1) | uj_ertek;

Ha uj_ertek also bitje lehet 1 is, akkor:
PORTB = (PORTB & 1) | (uj_ertek & ~1);

De ha csak azt akarod, hogy a PB0 mindig egyben legyen, akkor sokkal egyszerubb mar a tombben egybe tenni azt a bitet, es akkor nem kell semmit maszkolni. Vagy egyszeruen hozzaorolni egyet: PORTB = uj_ertek | 1;
(#) Droot válasza killbill hozzászólására (») Júl 14, 2015 /
 
Köszi! Akkor jól gondoltam!
Kijelző multiplexeléshez kell igazából!
Maszkolgatni muszáj lesz.
(#) Max26 hozzászólása Júl 16, 2015 /
 
Sziasztok! Mi lehet a hiba ebben a kódban?
  1. .global dly_100us
  2. .func dly_100us
  3. dly_100us:
  4.         ldi     r24, lo8(F_CPU / 100000)        /* Loop counter */
  5. 1:      sbiw    r30, 1          /* 10 clocks per loop */
  6.         sbiw    r30, 1
  7.         sbiw    r30, 1
  8.         nop
  9.         dec     r24
  10.         brne    1b
  11.         ret
  12. .endfunc


A fordító AVR Studio 4 alatt ezt a hibaüzenetet adja és a 4.sorra hivatkozik.

../pfatfs/usi.S: Assembler messages:
../pfatfs/usi.S:49: Error: `)' required
../pfatfs/usi.S:49: Error: garbage at end of line
Build failed with 1 errors and 0 warnings...
A hozzászólás módosítva: Júl 16, 2015
(#) killbill válasza Max26 hozzászólására (») Júl 16, 2015 /
 
Ha tenyleg a negyedik sorra irja ezt (es nem a 49.-re), akkor ird egybe a lo8(F_CPU/10000) reszt.
(#) csabeszq hozzászólása Júl 17, 2015 /
 
Lenne egy kérdésem.

Szóval van egy elfuserált szerkezet, ami elektromágnest kapcsolgat, kimaradt belőle a védődióda, miközben 1.5A folyik rajta. Értelemszerűen amikor kikapcsolja magát, akkor az őt kapcsoló Atmega16 bizonyos valószínűséggel kiakad.

Ami számomra érdekes, hogy leválasztott tápfeszültségnél, optocsatolón keresztül is csinálja. Van 5 db IC, de kizárólag azt üti ki, amelyikkel kapcsolom.

Fizikailag hogyan jön át egy nagy méretű induktív rúgás az opto-n és miért csak azt az IC-t találja el, ami őt kapcsolja?
(#) Massawa válasza csabeszq hozzászólására (») Júl 17, 2015 /
 
A tápon meg a levegöböl.
Neked meg kellene szüntetned, hogy egy mechanikus kapcsolo szakitsa meg a tekercs áramát. Ez az alap.
(#) Kovidivi válasza Kovidivi hozzászólására (») Júl 20, 2015 /
 
Sziasztok!
Volt a probléma az órakvarccal, hogy gyorsabban számol alvó módban a Timer2. Köszönöm a kondezátoros tippeket, de szoftveres volt a hiba... Valószínűleg elfelejtettem Build-ot nyomni feltöltés előtt, és a hibás program ment fel mindig. Nem tudom, hogy tudott alvó módban gyorsabban túlcsordulni a Timer2, nem alvóban pedig olyan sebességgel, ahogy kell, de a lényeg, hogy most már rendesen pörögnek a másodpercek, kondenzátor nélkül. Azt hiszem, a Timer2 pontosan órakvarcra van felkészítve, vagy csak szerencsém volt.
Szép napot.
(#) csabeszq válasza Kovidivi hozzászólására (») Júl 20, 2015 /
 
A kvarc kristály megléte még nem elég. A fuse biteket beállítottad?

Ha nem, akkor RC oszcillátorról megy, ami simán gyorsulhat alvó módban.
(#) Kovidivi válasza csabeszq hozzászólására (») Júl 20, 2015 /
 
Az AVR alapból a belső RC-ről megy, 8MHz-en, Fuse bit-ek beállítva, a Timer2 bemenetére van rakva a 32768Hz-es órakvarc.
(#) kenikl hozzászólása Júl 20, 2015 /
 
Sziasztok,

A következő kódot szeretném módosítani úgy, hogy a timer ne 2mp-enként ébressze fel az AVR-t hanem mondjuk fél óránként vagy egy óránként.
Szobanövény szérazság érzékelő
Adatlapból rájöttem, hogy a következő részt kellene módosítani, úgy hogy a CS10-CS13-ig kell módosítani:
  1. //Timer1 init - Ez az ébresztő "óra"
  2.     TCCR1 = (1<<CS13)
  3.           | (1<<CS12)
  4.           | (1<<CS11)
  5.           | (0<<CS10);    //8192
  6.     GTCCR = 0x00;

Viszont ha a CS10-et is egyesre állítom akkor a szorzó 16384 lesz, de akkor is maximum csak megduplázni tudom az ébresztőórát tehát kb 4mp-re.
Mit kellene még állítanom, hogy még feljebb tornázhassam az ébresztések közti időt?

A kód egy részét már módosítottam, úgy hogy a led ne villogjon, hanem csak kapcsoljon be ha száraz és kapcsoljon ki ha nedves:
  1. OutputDisable();
  2.  
  3.         if(szaraz)
  4.         {  
  5.           LED_ON();//bekapcsoljuk ha száraz
  6.         }
  7.         else
  8.         {
  9.           LED_OFF() ;
  10.         }
  11.         sleep_mode();    //Hajrá, menjünk aludni
  12.     }
  13.    
  14. }

Talán nem a legelegánsabb megoldás, és egy profi szemszögéből barbárnak tűnik a programozási részem, de ez az első ilyen próbálkozásom és beégetve működik.

Köszönöm a segítséget
(#) csatti2 válasza kenikl hozzászólására (») Júl 20, 2015 /
 
Esetleg átállhatsz a 128kHz-es RC forrásra (ezt osztod 8-al, akkor már csak 16kHz). Ekkor valamivel több, mint két percenként ébresztene, ez a maximum amit ebből a chipből külső órajel nélkül kihozható. A gond viszont a program többi részével lehet, át kell gondolni, hogy mit és hogyan kell módosítani, hogy ilyen lassú órajel mellett is működjön.

Egy másik lehetőség a low level interrupt használata. Az INT0-ás pint kell használnod erre a célra (a cikkben rossz a pin kiosztás, nézd meg az IC adatlapját). Teszel rá egy kondit (egy soros ellenállás sem árthat, ha nagyobb értékű a kondi). Kiemenetnek állítod. Feltöltöd azzal, hogy egybe írod. Átkapcsolod bemenetnek. Kikapcsolod a felhúzó ellenállást. Bekapcsolod a megszakítást. Elaltatod. Egy bizonyos idő elteltével (nem lesz nagyon akkurátus, sok mindentől függ majd) a kondi kisül és felébreszti a mikrokontrollert.
(#) kenikl válasza csatti2 hozzászólására (») Júl 20, 2015 /
 
Hmm, akkor szerintem marad a "B" terv. Mégpedig az, hogy ez az áramkör marad így és megy majd az elemről ahogy a cikkben van. Az öntöző rendszer többi része pedig külön lesz megalkotva.

Köszi a segítséget.
(#) Max26 hozzászólása Júl 21, 2015 /
 
AVR Studio 4.X IDE alatt ezeket a hibákat kapom. Próbáltam másik IDE-vel (Eclipse), azzal is hasonló hibák jelennek meg:

AVR Studio ezt írja hibaüzenetnek:
../pfatfs/usi.S:49: Error: `)' required
../pfatfs/usi.S:49: Error: garbage at end of line

Eclipse ezt:
../pfatfs/usi.S:49: Error: `)' required
../pfatfs/usi.S:49: Error: garbage at end of line
make: *** [src/pfatfs/usi.o] Error 1 avr_sdloggers C/C++ Problem

Erre a sorra panaszkodik mindkét IDE:
ldi r24, lo8(F_CPU / 100000) /* Loop counter */

  1. .global dly_100us
  2.     .func dly_100us
  3.     dly_100us:
  4.             ldi     r24, lo8(F_CPU / 100000)     /* Loop counter */
  5.     1:      sbiw  r30, 1        /* 10 clocks per loop */
  6.             sbiw    r30, 1
  7.             sbiw    r30, 1
  8.             nop
  9.             dec     r24
  10.             brne    1b
  11.             ret
  12.     .endfunc


Ha Eclipse alatt egy írom be a kódot:
ldi r24, lo8F_CPU / 100000 /* Loop counter */

akkor csak ezt a két hibát adja:

../pfatfs/usi.S:49: Error: garbage at end of line
make: *** [src/pfatfs/usi.o] Error 1 avr_sdloggers C/C++ Problem

Hogyan adhatnám meg a fordítónak helyesen azt a sort?
(#) killbill válasza Max26 hozzászólására (») Júl 21, 2015 /
 
Az a megoldas nem jo, amit mar egyszer megadtam? Nezd vissza! Ezt mar egyszer kerrdezted es valaszoltam is ra.
(#) Max26 válasza killbill hozzászólására (») Júl 21, 2015 /
 
Az a megoldás sem jó.
(#) killbill válasza Max26 hozzászólására (») Júl 21, 2015 /
 
Honnan veszed, hogy a 4. sorban van a hiba? Az assembler azt irja ki, hogy a usi.S file 49. soraban van a hiba. A hibauzenet pedig azt jelenti, hogy valami szemet, nem odaillo dolog van a sor vegen. De nagyon egyszeru, mert ha kikommentezed a 4. sort, es elmulik a hibauzenet, akkor tenyleg abban van a hiba.
(#) killbill válasza killbill hozzászólására (») Júl 21, 2015 /
 
Ok, mar ertem,hogy miert nem a 4. sor... Mert a valosagban a 49. de ide csak ezt a reszt masolod be. Az F_CPU makro definialva van?
(#) Max26 válasza killbill hozzászólására (») Júl 21, 2015 /
 
Igen, az F_CPU definiálva van a projektben, ide is beleírtam hátha, de a hiba nem hárult el. Az usi.S teljes tartalma:

  1. ;---------------------------------------------------------------------------;
  2. ; USI control functions
  3. ;---------------------------------------------------------------------------;
  4. ; Hardware dependent macros to be modified
  5. #define F_CPU 16000000UL
  6.  
  7. #define DDR_CS  _SFR_IO_ADDR(DDRB), 2   // MMC CS pin (DDR, PORT)
  8. #define PORT_CS _SFR_IO_ADDR(PORTB), 2
  9.  
  10. #define DDR_CK  _SFR_IO_ADDR(DDRB), 5   // MMC SCLK pin (DDR, PORT)
  11. #define PORT_CK _SFR_IO_ADDR(PORTB), 5
  12.  
  13. #define DDR_DI  _SFR_IO_ADDR(DDRB), 3   // MMC DI pin (DDR, PORT)
  14. #define PORT_DI _SFR_IO_ADDR(PORTB), 3
  15.  
  16. #define PIN_DO  _SFR_IO_ADDR(PINB), 4   // MMC DO pin (PIN, PORT)
  17. #define PORT_DO _SFR_IO_ADDR(PORTB), 4
  18.  
  19.  
  20. ;---------------------------------------------------------------------------;
  21. .nolist
  22. #include <avr/io.h>     // Include device specific definitions.
  23. .list
  24.  
  25.  
  26. ;---------------------------------------------------------------------------;
  27. ; Initialize USI
  28. ;
  29. ; void init_spi (void);
  30.  
  31. .global init_spi
  32. .func init_spi
  33. init_spi:
  34.         sbi     DDR_CS          ; CS: output
  35.         sbi     DDR_DI          ; DI: output
  36.         sbi     DDR_CK          ; SCLK: output
  37.         sbi     PORT_DO         ; DO: pull-up
  38.         ret
  39. .endfunc
  40.  
  41.  
  42. ;---------------------------------------------------------------------------;
  43. ; Delay 100 microseconds
  44. ;
  45. ; void dly_us (UINT n);
  46.  
  47. .global dly_100us
  48. .func dly_100us
  49. dly_100us:
  50.         ldi     r24, lo8 (F_CPU/100000) /* Loop counter */
  51. 1:      sbiw    r30, 1          /* 10 clocks per loop */
  52.         sbiw    r30, 1
  53.         sbiw    r30, 1
  54.         nop
  55.         dec     r24
  56.         brne    1b
  57.         ret
  58. .endfunc
  59.  
  60.  
  61. ;---------------------------------------------------------------------------;
  62. ; Select MMC
  63. ;
  64. ; void  (void);
  65.  
  66. .global
  67. .func
  68. :
  69.         rcall   de
  70.         cbi     PORT_CS
  71.         rjmp    rcv_spi
  72. .endfunc
  73.  
  74.  
  75.  
  76. ;---------------------------------------------------------------------------;
  77. ; De MMC
  78. ;
  79. ; void de (void);
  80.  
  81. .global de
  82. .func de
  83. de:
  84.         sbi     PORT_CS
  85.         ; Goto next function
  86. .endfunc
  87.  
  88.  
  89.  
  90. ;---------------------------------------------------------------------------;
  91. ; Receive a byte (28 clks)
  92. ;
  93. ; BYTE rcv_spi (void);
  94.  
  95. .global rcv_spi
  96. .func rcv_spi
  97. rcv_spi:
  98.         ldi     r24, 0xFF       ; Send 0xFF to receive data
  99.         ; Goto next function
  100. .endfunc
  101.  
  102.  
  103. ;---------------------------------------------------------------------------;
  104. ; Transmit a byte (27 clks)
  105. ;
  106. ; void xmit_spi (BYTE);
  107.  
  108.  
  109. .global xmit_spi
  110. .func xmit_spi
  111. xmit_spi:
  112.         ldi     r25, 8
  113. 1:      sbrc    r24, 7          ; DI = Bit to sent
  114.         sbi     PORT_DI         ;
  115.         sbrs    r24, 7          ;
  116.         cbi     PORT_DI         ; /
  117.         lsl     r24             ; Get DO  MMC
  118.         sbic    PIN_DO          ;
  119.         inc     r24             ; /
  120.         sbi     PORT_CK         ; A positive pulse to SCLK
  121.         cbi     PORT_CK         ; /
  122.         dec     r25             ; Repeat 8 times
  123.         brne    1b              ; /
  124.         ret
  125. .endfunc
Következő: »»   680 / 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