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   378 / 840
(#) sikolymester válasza Reggie hozzászólására (») Nov 10, 2011 /
 
Természetesen.
Csupán követtem Gery hozzászólásait és úgy tűnt, hogy gyakran nagyon mellé nyúl. Gondoltam figyelmeztetem, hogy megspóroljam neki a kiégett IC cseréjét. Így felsorakoztattam a laikusan hangzó érveimet, hogy véletlen se kösse rá direktbe.

Amennyiben eszébe sem jutott, akkor elnézést kérek tőle, hogy feltételeztem róla.
(#) Reggie válasza sikolymester hozzászólására (») Nov 10, 2011 /
 
Helyesen tetted, en nem tudom levetkozni a naivsagomat ezen a teren. Legalabb figyel valaki helyettem is.
(#) Krisszes válasza röntgen hozzászólására (») Nov 10, 2011 /
 
Azt hiszem, hogy értem. Nekem az jutott eszembe, hogy mind kettőre csinálnék IT-t és amelyik előbb érkezik be az tiltja a másikat... szerintetek melyik lenne a könnyebb? (Egy rövid kis indoklással)
(#) Gery válasza sikolymester hozzászólására (») Nov 10, 2011 /
 
Nem, a motor hardvere rendben van, ennyit még én is tudok. Viszont ami érdekes, hogy most szkóppal mérem a lábakat, és ha gpio_set_gpio_pin(AVR32_PIN_PA07)-et beírom neki nem történik semmi. Ennek a parancsnak a a gpio.c szerint :

void gpio_set_gpio_pin(unsigned int pin)
{
volatile avr32_gpio_port_t *gpio_port = &GPIO.port[pin >> 5];

gpio_port->ovrs = 1 << (pin & 0x1F); // Value to be driven on the I/O line: 1.
gpio_port->oders = 1 << (pin & 0x1F); // The GPIO output driver is enabled for that pin.
gpio_port->gpers = 1 << (pin & 0x1F); // The GPIO module controls that pin.
}

magas szintűre kéne emelnie a lábat bárminemű extra beállítás igénye nélkül, nem?
Vagy valamit kifelejtek, esetleg a hardverre lenne probléma?>
(#) Gery válasza Gery hozzászólására (») Nov 10, 2011 /
 
Nos a panelon lesz valami elkötve mert egy másik mikrokontrolleren működik a gpio parancs legalábbis.
(#) Krisszes válasza Krisszes hozzászólására (») Nov 10, 2011 /
 
Úgy néz ki, hogy megy a szekér...
viszont lenne egy olyan kérdésem, hogy beérkezik az INT4 megszakítás, rutin lefut, eddig jó. Miért ugrik újra a vektor tábla következő sorára és nem vissza a main függvénybe?
(#) kiborg válasza Krisszes hozzászólására (») Nov 10, 2011 /
 
Az aktuális megszakítás reti-vel van lezárva?
Nálam akkor csinált ilyet, ha csak ret-et tettem, vagy elhagytam a lezárást.

Amúgy meg szerintem ez a cikk határozottan sokat fog segíteni:Inkrementális szögadó illesztése mikrokontrollerhez
(#) Krisszes válasza kiborg hozzászólására (») Nov 10, 2011 /
 
köszi a cikket, tényleg jó. A lezárás RETI-s.
arra gondoltam hogy a main túl rövid, hogy nincs benne semmi, és igen... pár NOP-pal el is tünt a jelenség.
(#) H2opok hozzászólása Nov 11, 2011 /
 
Üdv
Lenne egy lehetőség smd Pic és Atmega kontroller programozó adapterek legyártására egy nyákgyártó cégnél. Egy kedves ismerősöm már megtervezte a nyákokat. Mivel főleg Pic-el dolgozunk,így legtöbb ezekhez a típusokhoz van, kb. 11db. Egy Atmega8 van csak. Mellékletben ennek a nyákterve,amit szeretnénk ha valaki hozzáértő átnézne,nehogy hibásan gyártassuk le.
Viszont Ha lenne más tipusra is igény, és valaki megcsinálja a nyáktervet, azt hozzá tesszük a többihez. Vasárnapig kellene, mert hétfőn már gyártás.
Előre is köszi

atmega8.lay
    
(#) Krisszes válasza kiborg hozzászólására (») Nov 11, 2011 /
 
Szia! Lenne egy olyan kérdésem, hogy amikor a megszakítás érkezik mondjuk felfutó élre, abban az időpillanatban a port állapotát, hogyan mintavételezhetem?
(#) Topi válasza Krisszes hozzászólására (») Nov 11, 2011 /
 
Az interrupt az élváltozás után már jó pár órajel ciklusnyi idővel később érkezik be, tehát ott a hagyományos PINx olvasással már beolvashatod a portot.

Ha rotary A-n van az interrupt, akkor beeséskor megnézed hogy a B magas vagy alacsony. Ennek megfelelően tudod hogy előre / hátra tekerték el.
(#) Krisszes válasza Topi hozzászólására (») Nov 11, 2011 /
 
Azzal a furcsa jelenséggel álok szemben, hogyha az encoder-t eltekerem (egy kattanás) akkor ha a programot F11-gyel léptetem, akkor egy lépés után a PINE regiszterben egyből megjelenik a két bit változás (4,5). Nagy ritkán van az, hogy csak külön külön. Valahogy ezt folyamatosan kéne figyelni... De hogyan???
(#) kiborg válasza Krisszes hozzászólására (») Nov 11, 2011 /
 
Mekkora az enkódered felbontása? Az egy "kattanás" biztos, hogy csak 1 csatorna megváltozását okozza? Azt sem tartom kizártnak, hogy ha egy "kattanásnyit" forgatod, addigra többször is állapotot vált az enkóder mindkét csatornája, ezért van hogy mindkét bit jelzi az interruptot.Ha F11-el léptetsz, akkor sehogy nem tudod így figyelni, megírod mindkét interruptot és mindkettőbe raksz egy egy nop ot, breakpointtal, ahol először áll meg az hajtódik először végre mozgáskor ha reti után ugrik a másik megszakításra, enélkül, hogy mozdítottál volna az enkóderen, biztos lehetsz abban, hogy mindkét csatorna okozott interruptot.
Kiborg
(#) Krisszes válasza kiborg hozzászólására (») Nov 11, 2011 /
 
Az enkóder kettő "kattanásra" produkál egy teljes periódust és a két csatorna is párhuzamosan fut 90° eltolással.
(#) kovacsj hozzászólása Nov 11, 2011 /
 
Sziasztok!

Nincs valakinek ötlete, hogy a kódrészlet ellenére miért kerül bele az OK az rx_bufferbe?

  1. ISR(USART1_RX_vect) {
  2. unsigned char  data;
  3.  
  4.  
  5. data = UDR1;
  6. if ((data != 'O') || (data != 'K')) {
  7. rx_buffer[rx_wr++] = data;
  8. }


És elvileg a NO CARRIER-t is így kellene látnom: N CARRIER.
Köszönöm előre is!
(#) Topi válasza kovacsj hozzászólására (») Nov 11, 2011 / 1
 
Bool algebra alapok.

Negáltak vagy-olása, és és-elése probléma. Avagy negáltak összeadása ellenben a negáltak szorzásával.

data != O ÉS data != K.

Bővebben: Link
(#) kovacsj válasza Topi hozzászólására (») Nov 11, 2011 /
 
De a data minden megszakításkor változik. Vagy nem?

Igazából az SMS beolvasásával nem boldogulok.
Az AT+CMGR=X -re visszajön a +CMGR: "REC READ","+36703146459","","2011/11/11 16:10:09+04"

de a tartalom nem, vagy nem mindig látszik az rx_bufferben.
Ezzel töltöm a tömböt:
  1. ISR(USART1_RX_vect) {
  2. unsigned char  data;
  3.  
  4.  
  5. data = UDR1;
  6. if ((data != 'O') || (data != 'K')) {
  7. rx_buffer[rx_wr++] = data;
  8. }
  9.  
  10. if (rx_wr > (RX_INDEX-2)) {
  11. rx_buffer[rx_wr] = '\0';
  12. rx_wr = 0;
  13. }
  14.  
  15. if ((data == '\n')) {
  16.  
  17. rx_buffer[rx_wr] = '\0';
  18. rx_wr = 0;
  19.  
  20.  
  21. }
  22.  
  23. }


Előre is nagyon köszönöm, ha valaki megvilágosít!
(#) Topi válasza kovacsj hozzászólására (») Nov 11, 2011 / 1
 
Hmm.. Gondold végig lassan

Beérkezik az 'O', azaz data = 'O'.
Elágazásod:
if(('O'!='O') || ('O' != 'K')) -> Ez esetben az IF igaz lesz az O != K miatt.

Beérkezik a 'K', azaz a data = 'K'
Elágazásod:
if(('K' != 'O') || ('K' != 'K')) -> Ez esetben az IF ismét igaz lesz, de most a K != O miatt.
(#) kovacsj válasza Topi hozzászólására (») Nov 11, 2011 /
 
Tényleg! Fáradt vagyok, éjszakás voltam.
Nagyon szépen köszönöm!
(#) kovacsj válasza kovacsj hozzászólására (») Nov 11, 2011 /
 
A legnagyobb problémám azonban a következő:
Az aláhúzással elválasztott karakterek a buffer első négy eleme.
Csillaggal van lezárva.

  1. +_C_M_T*                                                                        
  2. +CMTI: "SM",3                                                                  
  3.                                                                                
  4. +_C_M_G*                                                                        
  5. +CMGR: "REC UNREAD","+36703146459","","2011/11/11 19:32:47+04"                  
  6.                                                                                
  7. _                                                                              
  8.  __4*

És amint látszik, az SMS tartalma az 1234 helyett üres,\n(vagy \r?),üres,üres,4 lett.
Ez vajon mitől lehet?
A kód amivel töltöm, lejjebb található. A feltételt már kijavítottam.

Előre is nagyon szépen köszönöm!
(#) kovacsj válasza kovacsj hozzászólására (») Nov 11, 2011 /
 
Szerintem az SMS végére is kellene egy '\0', de azt nem tudom, hogyan illesszem oda. Kibővítettem a kiírást egy karakterrel és az látszik, hogy innen már jó is lenne.

  1. +_C_M_T_I*                                                                      
  2. _                                                                              
  3.  __4_5*                                                                        
  4. _                                                                              
  5.  __4_5*  
  6.  
  7.  
  8. USART0_putchar(rx_buffer[0]);
  9. USART0_puts((unsigned char*) space);
  10. USART0_putchar(rx_buffer[1]);
  11. USART0_puts((unsigned char*) space);
  12. USART0_putchar(rx_buffer[2]);
  13. USART0_puts((unsigned char*) space);
  14. USART0_putchar(rx_buffer[3]);
  15. USART0_puts((unsigned char*) space);
  16. USART0_putchar(rx_buffer[4]);
  17. USART0_putchar('*');
  18. USART0_puts((unsigned char*) newline);


A space a _ a newline pedig az új sor.
Ha jól látom, az első elem sortörés lehet. De vajon mitől?
+CMGR: "REC UNREAD","+36703146459","","2011/11/11 19:32:47+04" Ez után van egy 0x0A karakter, az a '\n', és erre én egy '\0'-t íratok be. Az meg ott is van a második sor első elemében, ugye? a __4_5* előtt. Nekem tehát vagy nem a '\n'-re kellene nulláznom, vagy pedig ezzel az egy esettel (SMS) kellene kivételt tennem. Jól gondolom?

Előre is nagyon köszönöm!
(#) kovacsj válasza kovacsj hozzászólására (») Nov 11, 2011 /
 
Megoldódni látszik ez a probléma is, egy feltétel beillesztésével, ami azt mondja, hogy csak akkor cserélje le a '\n'-t '\0'-ra, ha a számláló kisebb mint 50.

  1. if ((data == '\n') && (rx_wr<50)) {
  2.  
  3. rx_buffer[rx_wr] = '\0';
  4. rx_wr = 0;
  5.  
  6.  
  7. }


60 fölött kezdődik ugyanis az SMS tartalma.
(#) kovacsj válasza kovacsj hozzászólására (») Nov 11, 2011 /
 
Lehet, hogy nem tökéletes, mert csak egy SMS-t kezel jól. Utána újra kell indítani.
Szerintem nincs az SMS végén '\0'. Honnan lehetne ezekről többet tudni?


Köszönöm előre is!
(#) kovacsj válasza kovacsj hozzászólására (») Nov 11, 2011 /
 
Lehet, hogy nem valami elegáns megoldás, de úgy működik, ha egy *-ot írok a végére, majd ennek hatására is beteszem a '\0'-t.
  1. if ((data == '*') && (rx_wr>60)) {
  2.  
  3. rx_buffer[rx_wr] = '\0';
  4. rx_wr = 0;
  5.  
  6.  
  7. }


Ez megoldotta, nem kell újraindítgatni. Tákolmány?
(#) UbiLinux válasza kovacsj hozzászólására (») Nov 12, 2011 /
 
Alapvetően az a baj, hogy a buffer kérdezgetésekor nem tudod, hogy az egész sms már megérkezett és ott van a bufferedben vagy még fognak jönni karakterek.
Én ezt úgy oldom meg, hogy egy timer interruptot is használok erre a feladatra. A dolog úgy működik, hogy az uart vevő rutin az érkező karaktert beírja a bufferbe ÉS egy számlálót beállít úgy 10 msec körüli értékre. Aztán az IT-nek ezzel vége is, mást nem is csinál.
Viszont a timer IT - ha úgy találja, hogy ez a számláló nem nulla - akkor elkezdi csökkenteni. Ha közben újabb karakter érkezett az uart-ba, akkor az uart rutin számlálót megint beállítja a 10 msec körüli értékre, hiába csökkentette a timer.
Ha viszont nem érkezik 10 msec alatt újabb karakter, akkor a számláló le tud nullázódni. Mikor a nullázódás megtörténik, a vevőbufferbe írok egy stringzáró nullát és egy jelzőbiten jelzem a főprogramnak, hogy a bufferben érvényes tartalom van.
A mechanizmus azért elegáns, mert a két interrupt elintéz mindent, a főprogram akárhol is bóklászhat közben, majd a jelzőflag értesíti róla, hogy teendője van. A jelzőflag lekérdezését meg ráérek akár másodpercenként is elvégezni.
(#) UbiLinux válasza UbiLinux hozzászólására (») Nov 12, 2011 /
 
  1. SIGNAL(TIMER1_COMPA_vect)// output compare match A
  2.  
  3. {
  4.  
  5. if (RxTimOvr != 0xff)
  6.  
  7. {
  8.  
  9. if (RxTimOvr != 0)
  10.  
  11. {
  12.  
  13. if (--RxTimOvr == 0)
  14.  
  15. {
  16.  
  17. RxTimOvr = 0xff;// Rx timeover nem kell
  18.  
  19. Received = RxPtr;// Vett string hossza
  20.  
  21. RxBuf[RxPtr] = 0;// Vett stringet lezárni
  22.  
  23. RxPtr = 0;// Felkészülni a következő vételre
  24.  
  25. }
  26.  
  27. }
  28.  
  29. }
  30.  
  31. if (LINETMR)
  32.  
  33. LINETMR--;
  34.  
  35. if (DLYTMR)
  36.  
  37. DLYTMR--;
  38.  
  39. if (GSMTMR)
  40.  
  41. GSMTMR--;
  42.  
  43. if (DIALTMR)
  44.  
  45. DIALTMR--;
  46.  
  47. }
  48.  
  49.  
  50.  
  51. SIGNAL(SIG_UART_RECV)// Receive Interrupt
  52.  
  53. {
  54.  
  55. RxBuf[RxPtr++] = UDR;// Store received byte in buffer
  56.  
  57. RxTimOvr = RxReady;// Countback countert felhúzni
  58.  
  59. if (RxPtr==RxBufLen)
  60.  
  61. RxPtr--;
  62.  
  63. }

A kód abból a szempontból nagyon csúnya, hogy írásakor még nem ismertem a konvenciókat, tehát ezt a stílust ne kövesd. C-ben a változókat csupa kis betűvel illik írnia, a konstansokat meg csupa nagy betűvel.
A timer it végén direkt benne hagytam négy másik számláló kezelését, hogy látsszon, hogy ugyanaz az it kezeli a program több, avételtől független számlálóját is.
(#) kovacsj válasza UbiLinux hozzászólására (») Nov 12, 2011 /
 
Köszönöm szépen! De ha én megmondom az SMS-sel, hogy hol a vége (*) akkor az is jó, nem? Végül is működik. És legalább tudom, hogy a GSM modulnak küldöm, nem a feleségemnek. (De szép is lenne az asszonyt is így irányítani! Valaki erre nem tud megoldást? )
(#) Krisszes hozzászólása Nov 12, 2011 /
 
Sziasztok!

Azt szeretném kérdezni, hogy van arra mód, hogy prioritást módosítsak az megszakítások között?

(mondjuk két egyenlőt csinálhassak?)
(#) röntgen válasza Krisszes hozzászólására (») Nov 12, 2011 /
 
Annak mi értelme?
(#) UbiLinux válasza kovacsj hozzászólására (») Nov 12, 2011 /
 
Persze, hogy jó lehet, de honnan tudod meg, hogy vége az modem által küldött üzenetnek? Ha szerencsétlen pillanatban kezded el vizsgálni a buffert, azt látod, hogy bejött a fejrész, pl. az, hogy +CMGR: "REC UNREAD", stb.stb és még öt karakter, ami a tulajdonképpeni özenet. Honnan tudod, hogy nem hat, tíz vagy további negyvenhét karakter következik még? Mi biztosítja, hogy az olvasásod nem egy elkapkodott beleolvasás egy még be nem fejezett üzenet elejébe?
Nálam a program csak akkor foglalkozik a program a bufferrel, ha 10 ms várakozás után sem jön újabb karakter. Ekkor garantáltan vége az üzenetnek, lehet olvasni.
Következő: »»   378 / 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