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   402 / 840
(#) szdani hozzászólása Jan 25, 2012 /
 
Ezt írja ki az avr studio4:
make: *** No rule to make target `..//D/dani/AVR/Lcd_driver_1v4/main.c', needed by `main.o'. Stop.

mi a probléma?
(#) sikolymester válasza szdani hozzászólására (») Jan 25, 2012 /
 
Ha studio 4.19 , akkor be kell allitani manualisan a winavr t forditonak a project settingsben. make.exe es avr-gcc.exe kell oda.
(#) szdani válasza sikolymester hozzászólására (») Jan 25, 2012 /
 
Megnéztem, az jó. Azért köszönöm
(#) Axel hozzászólása Jan 25, 2012 /
 
Sziasztok!

Adott a következő probléma. Egy Atmega8-on fut egy program melyben van egy RTC és egy DS1621 hőmérő. Az RTC-ből és a hőmérőből is időzítve olvas a program úgy, hogy a szenzort ~10, az RTC-t ~1 másodpercenként olvassa és frissíti is a kijelzőt. Csak egy timert használok illetve annak megszakításvektorát. A gond az ,hogy e mellet 3 nyomógombot is kell kezelnem amit nem tudom ,hogy lenne a legjobb megoldani. A pergésmentesítés nem gond, hardveresen lett megoldva. Ha a nyomógombkezelést interrupt-al oldom meg akkor egyrészt fennáll annak veszélye, hogy egyszerre történik megszakítási kérelem. Ez nyilván nagyon kis eséllyel esik latba. Ami viszont valódi gond, hogy a DS 1621 sajna eléggé lassú átlagosan 500 ms egy mérés. Ez idő alatt a proci nem érzékelhet gombnyomást vagy ha mégis akkor meg a mérés szakad meg. Ilyenkor néha előfordul, hogy nem történik semmi ha megnyomok egy gombot. Az pedig számomra elfogadhatatlan ,hogy kétszer is meg kelljen nyomni egy gombot, mert nem éppen a minőség és megbízhatóság benyomását kelti. Szóval összegezve a gond az, hogy a háttérben futó feladatok miatt még a polling módszerrel sem garantálható az azonnali lenyomás érzékelés. Ti mit tanácsolnátok hogyan oldható meg ez a probléma legegyszerűbben?
(#) zombee válasza Axel hozzászólására (») Jan 26, 2012 /
 
Ha a nyomógomb interruptot használ, akkor az interruptok tiltása alatt is megmarad az interrupt kérelem(mivel az interrupt flag beállítódik), így amikor engedélyezed a sei()-vel pl. hőmérés vagy RTC-átvitel végén, akkor az le fog futni. Igaz, így nem azonnal, de mondj akár egy okostelefont ahol nem fordul elő hogy egy gombnyomás hatása 500ms után érződik!

Ha kevés az INT láb akkor diódával közösíted az INT-re is és az interrupt pollingolhat, de más perifériák is tudnak külső interruptot csinálni, például az analóg komparátor, és a Timer1 is ha az Input Capture az ICP(1) lábra van állítva!

A másik, hogy ha a hőmérő átviteléhez szoftveres(_delay_ms()) késleltetés helyett hardvereset használsz, akkor azt megszakíthatod interrupttal ha az elég rövid. Például elindítod valamelyik számlálót és kb. 1ms-re állítod be, majd ha oda érkezel hogy _delay_ms() kell az helyett feljegyzed a számláló értékét és vársz amíg eléri az adott késleltetést:
  1. _delay_ms(50);
  2. //helyett:
  3. uint8_t temp=TCNT0;
  4. while(TCNT0-temp<50);
  5. //vagy:
  6. TCNT0=0;
  7. while(TCNT0<50);


Esetleg az utolsónál a timer előosztót(prescaler) is törölheted, most nem jut eszembe hogy mivel, de lehet!
(#) Axel válasza zombee hozzászólására (») Jan 26, 2012 /
 
Szia zombee!

Köszi a tippet! Ez az interrupt flag nagyon jó ötletnek tűnik, hirtelen eszembe sem jutott volna! Ezért éri meg ide járni . A kis késés nem is gond csak biztosan hajtódjék végre az utasítás. Amúgy a delay az olyan nálam, hogy a mérés indítása után while ciklusban olvasom ki a "conversion done" bit állapotát a DS1621-ből ha kész akkor kilép a ciklusból, és fut a program tovább, így garantáltan csak annyi a holtidő ameddig a kiolvasás tart.
(#) zombee válasza zombee hozzászólására (») Jan 26, 2012 / 1
 
Egy másik megoldás hogy diódát(1n4148)+ellenállást(~100 Ohm) kötsz a nyomógomb és a portláb közé, majd a portlábra egy kis kondenzátort. Lehetőleg legyen kicsi(10-100nF), és a felhúzó ellenállást az AVR-be nem kapcsolhatod be. A kondit mindig az AVR tölti fel a polling után. Ha így csinálod akkor a nyomógombnak nem kell interruptot generálnia, és a kondi a polling eljövetelekor emlékezni fog arra hogy lenyomták. A dióda pedig megakadályozza hogy a gomb felengedésekor a kóboráramok feltöltsék a kondit. Az AVR portlábainak nagy az impedanciája(DDRx és a PORTx kikapcsolva), a kondi értékétől függően meg fogja őrizni az állapotot!
(#) Istvanpisti válasza Axel hozzászólására (») Jan 26, 2012 /
 
Szia Axel !

Én a következő módon csinálom:
A timer interruptom 10ms-onként hívódik meg. Itt egy változót növelek, és ha elérte a 100-at (1sec), akkor egy volatile változót 1-be állítok. Minden timer int-ben a billentyűzet nyomást figyelem és változóba mentem.

A főprogram while ciklusában meghívom egy fv.-t, amiben megnézem, hogy a timer int. beállította-e a változómat 1-be. Ha igen, akkor lekérdezem a hőmérőt, újraindítom a mérést, lenullázom a volatile változót, és ha kell kiírom a kijelzőre amit akarok. Nem használom - legalábbis itt - a delay fv-t.

  1. volatile BYTE sec = 0;
  2. volatile BYTE min = 0;
  3. volatile BYTE hour = 0;
  4. volatile BYTE KeyReg, LightTmr;
  5. volatile BYTE light_length;// = 50;
  6. volatile BYTE header_iras = 0;
  7.  
  8. #define BUTTON_PIN PIND
  9. #define BUTTON_PORT PORTD
  10. #define BUTTON_MASK0b11110000
  11. #define BUTTON_DOWN 0b00100000
  12. #define BUTTON_UP0b10000000
  13. #define BUTTON_OK 0b01000000
  14. #define BUTTON_ESC 0b00010000
  15. #define MAX_BUTTON 1000
  16.  
  17. int button =0;
  18.  
  19. void put_header(void)
  20. {
  21.     char c1;
  22.     if(header_iras)
  23. {
  24.       header_iras=0;
  25.       read_meas(&temp); // a hőmérő lekérdezése
  26. //             kiírás, vagy amit akarsz
  27. start_meas();
  28. }
  29.  
  30. }
  31.  
  32. int main (void)
  33. {
  34.         // inicializálások
  35. while(1)
  36. {
  37. put_header();
  38.                 button++;
  39.         _delay_us(200);
  40.          if(button == MAX_BUTTON)
  41.         {
  42.        if(KeyReg & BUTTON_UP)
  43.        {
  44.                            //mit kell csinálni ekkor
  45.                         }
  46.                         if(KeyReg & BUTTON_DOWN)
  47.        {
  48.                            //mit kell csinálni ekkor
  49.                         }
  50.                         button=0;
  51.                  }
  52.          }
  53. }
  54.  
  55. ISR(TIMER2_COMP_vect)
  56. {
  57. static BYTE szam;
  58. BYTE n,k;
  59.  
  60. szam++;
  61. if(!(szam%100))
  62. {
  63. sec++;
  64.  
  65. header_iras=1;
  66. if(sec == 60)
  67. {
  68. sec=0;
  69. min++;
  70. if(min == 60)
  71. {
  72. min=0;
  73. hour++;
  74. if(hour == 24) hour=0;
  75. }
  76. }
  77.                 if(LightTmr) LightTmr--; else DDRB&=~(1 << PB4);  //háttérvilágítás kikapcsolása
  78. szam=0;
  79.  
  80. }
  81.         k = ~BUTTON_PIN & BUTTON_MASK;
  82. n = (k ^ KeyReg) & k;
  83. KeyReg = k;
  84. if (n)
  85. {
  86. LightTmr = light_length;
  87. DDRB|=(1<<PB4);
  88. }
  89.  
  90. }
(#) Istvanpisti válasza Istvanpisti hozzászólására (») Jan 26, 2012 /
 
Próbáltam még formázni a kódot, de kifutottam az időből.
(#) Axel válasza Istvanpisti hozzászólására (») Jan 26, 2012 /
 
Köszi a tippet neked is!
(#) karika200 hozzászólása Jan 26, 2012 /
 
Sziasztok!

Építettem egy STK200-as programozót, hogy az itt leírtak alapján felprogramozzak egy ATmega8-ast az avrdoperemhez. Programozásra az avrdude nevű szoftvert használom és ehhez kérnék egy kis segítséget. (Bármilyen más nyílt forrású, Linuxon/BSD-n futtatható programozóra vevő vagyok)

Van egy furcsaság: felírtam a linkelt leírásban található programot a flashbe, szépen fel is ment, verify-nál sem volt gond. Viszont visszaolvasva kevesebb byteot kapok...

  1. karika200@karika200-sx:~$ du -b prog.hex
  2. 16044prog.hex
  3. karika200@karika200-sx:~$ du -b avr_isp.hex
  4. 18999avr_isp.hex


Jól látszik, hogy a visszaolvasott prog.hex 16044 Byte az eredeti, beírt program pedig 18999. Ez miből adódhat?

Másik kérdésem pedig a fuse bitek beállítására vonatkozik. Azt látom, hogy hogyan lehet az alsó és felső biteket lekérdezni, illetve felírni az AVR-be avrdude-al, de hogyan nézne ki a linkelt leírásban szereplő beállítások hex fileja, amit aztán felírok az MCU-ba?

Köszönöm, karika200
(#) tursaba hozzászólása Jan 26, 2012 /
 
Sziasztok !
Szeretném megkérdezni, hogy Ponyprog-ban (4.07) ki lehet-e kapcsolni a verify funkciót ?
Ha igen, hogyan ?
Ha program options-ban nem pipálom ki és program módban töltöm a flash-t, akkor is megcsinálja.
Ha write program(flash)-t használom, akkor is elindul a verify.
Köszönöm : tursaba
(#) Axel hozzászólása Jan 28, 2012 /
 
Szevasztok!
Atmega8-ban tényleg nincsen PCINT? Az adatlapból is ez derül ki meg olvastam máshol is. Csak a két dedikált megszakításláb használható ilyesmire?
Köszi!
(#) TavIR-AVR válasza Axel hozzászólására (») Jan 28, 2012 /
 
M8: 2db külső int: int0/int1 (trükkel a külső timerszámláló)
Mx8: PCINT minden lábon: M48/88/168/328 és a P ill PA sorozatok.
(#) zombee válasza Axel hozzászólására (») Jan 28, 2012 /
 
Meg még van más is, igaz, kicsit trükközni kell de csak nagyon kicsit.
Egyik az ICP(1) láb. a timer1-nél találod az Input Capture egységet, ott engedélyezheted az interruptot.
Másik lehetőség külső interruptra az analóg komparátor. Az egyik bemenetet 2.5V-ra teszed, a másikkal operálsz.
A Timerek bemenetei(T0,T1,T2) szintén, csak úgy kell beállítani hogy az OCRxY regiszterbe 1-et írsz,
az Output Compare interruptban pedig lenullázod a TCNTx-et és kész...
(#) Lúd-fi hozzászólása Jan 28, 2012 /
 
Üdvözlök mindenkit!

Egy szerintem érdekes kérdésem van. Adott egy AVR és egy I2C óra (de tulajdonképpen bármilyen eszköz lehet). Egy ismerősöm tanácsára a kommunikációt nem ACK-ra várva oldottam meg, hanem a TWSR regisztert figyelve, így a programom sosem várakozik. Tulajdonképpen ez a legfontosabb szempont. A progi működik rendesen, nem fagyott le az elmúlt teszt 24 óra alatt. Majd hibát szimuláltam: az SDL/SCL lábat megszakítottam, vagy az óra tápot elvettem. Eredmény: a főprogramom fut szépen tovább (ez azért várható volt), de az I2C kezelő progi nem. Egyszerűen nem tudom újra resetelni az órát. Próbáltam a TWSR-t is kiolvasni, de semmi értelmes nem jött ki. Persze értem, hogy mondjuk egy adatfolyam, vagy bármilyen működés közben történő kommunikációs vonal szakadás nem feltételezhető, de nem értem, hogy miért nem indul újra pl. egy START parancsra.
(#) zombee válasza Lúd-fi hozzászólására (») Jan 28, 2012 /
 
A TWSR-t figyelve mindig a leggyorsabb, de csak hibamentes környezetben. Érdemes timeout-ot is beprogramozni mellé és akkor nem fagy le a programod.
(#) Axel válasza zombee hozzászólására (») Jan 28, 2012 /
 
Az esetleg jó lenne ha a 3 gombot még pluszban közösítve kötném az egyik külső megszakítás lábra és az Interrupt-ban megvizsgálnám melyik is van lenyomva?
(#) Lúd-fi válasza zombee hozzászólására (») Jan 28, 2012 /
 
Nem láttam erre való utalást. A timeout-ra nekem lenne szükségem, hogy probléma esetén x idő múlva kilépjek, vagy az I2C-nek, hasonlóan az USB kötelező válaszához?
(#) Lúd-fi válasza Lúd-fi hozzászólására (») Jan 28, 2012 /
 
Pontosítok: tehát az a kérdés, hogy mondjuk pl. a START és az SLA+W között eltelhet akármennyi idő? Mert a progim úgy van megírva, hogy amikor meghívom, akkor megnézi, hogyan áll a státus regiszter és az alapján lép. Ha még nem megfelelő visszamegy a főprogiba és majd megint bepróbálkozik. DE minden meghíváskor csak egy dolgot csinál. Kommunikációs hiba esetén mindent kezd(ene) elölről.

  1. int I2CRead(int I2Caddress, int I2Cregister)
  2.  
  3. {
  4. if(I2Cstatus == 0)// START
  5. {
  6. I2Cstatus = 1;
  7. I2C_START;
  8. }
  9. else
  10. {
  11. if(TWSR == 0x08)// ADDRESS + W
  12. {
  13. I2Cstatus = 1;
  14. TWDR = I2Caddress;
  15. I2C_EN;
  16. }
  17. else if(TWSR == 0x18)// REGISTER
  18. {
  19. I2Cstatus = 1;
  20. TWDR = I2Cregister;
  21. I2C_EN;
  22. }
  23. else if(TWSR == 0x28)// RESTART
  24. {
  25. I2Cstatus = 1;
  26. I2C_START;
  27. }
  28. else if(TWSR == 0x10)// ADDRESS + R
  29. {
  30. I2Cstatus = 1;
  31. TWDR = I2Caddress + 1;
  32. I2C_EN;
  33. }
  34. else if(TWSR == 0x40)
  35. {
  36. I2Cstatus = 1;
  37. I2C_EN;
  38. }
  39. else if(TWSR == 0x58)// REC DATA
  40. {
  41. I2Cstatus = 0;
  42. I2C_STOP;
  43. return TWDR;
  44. }
  45. else// Hiba üzenetek jöhetnek
  46. {
  47. I2Cstatus = 0;
  48. I2CClockStatus = 0;
  49. }
  50. }
  51. }
(#) TavIR-AVR válasza Axel hozzászólására (») Jan 28, 2012 /
 
(#) Lúd-fi válasza Lúd-fi hozzászólására (») Jan 28, 2012 /
 
Megválaszoltam magamnak: igen. Bocsi, nem tudom kitörölni a többi hsz-t.
(#) zombee válasza Axel hozzászólására (») Jan 28, 2012 /
 
Igen, természetesen! Diódák vezessenek a közös pontra és azzal kész is.
(#) mzozo95 hozzászólása Jan 28, 2012 /
 
Sziasztok!

lenne egy egyszerű kérdésem, az attiny2313-20pu mekkora áramot adhat le a kimenetén?

A pdf-ben képtelen voltam megtalálni..

Előre is köszönöm a választ,
Zoltán
(#) TavIR-AVR válasza mzozo95 hozzászólására (») Jan 28, 2012 / 1
 
Ökölszabály:
20-30mA/láb, 150mA/port, 200mA/táphozzávezető láb.

A legszigorúbbat kell venni: Azaz 8 láb*20 mA >>150mA!
(#) Axel válasza TavIR-AVR hozzászólására (») Jan 29, 2012 /
 
Köszi!
(#) Axel válasza TavIR-AVR hozzászólására (») Jan 29, 2012 /
 
Csak még mindig az aggaszt, hogy a megszakítás éppen egy I2C irási vagy olvasási műveletet szakít félbe ami valamiféle inkonzisztenciát, vagy lefagyást eredményezne. Az szerintem mégsem járja, hogy csak úgy megszakítok egy ilyen művelet. Elképzelhető, hogy Atmega88-al kell megoldani a dolgot. De amennyire tudom ott is csak két megszakításforrás van csak éppen több pin is kiválthatja beállítástól függően. (ATtiny 24-nél legalábbis így van)
(#) TavIR-AVR válasza Axel hozzászólására (») Jan 29, 2012 /
 
???

PCINT: egy port váltja ki (közösített). és egy belső regiszter meg is mondja, hogy a 8 lábból melyik!

A megszakításban maradj rövid! Az nem, okoz gondot. Az i2c nem jó példa, mert ott a master órajele (SCL) szinkronizálja az adatfolyamot....

ha egy INT megakassza/lefagyassza a programiot - ott a chip /program a kuka.


M8 esetén int beesik, majd lekérem a portok állapotát. Jelzőbit bebillent és kilép INTből. kb. 15-20 órajel... (15-20usec! 1MHz sebesség esetén...)
Kiértékelés meg pl. főprogramban történik....
(#) trudnai válasza mzozo95 hozzászólására (») Jan 29, 2012 / 1
 
Nem ezt keresed? 196. oldalon talaltam ezt, ez mutatja, hogy pl ha 10mA-t szeretnel leemelni a port labarol akkor olyan 4.7V kornyekere esik le a feszultseg, 20mA eseten mar kevesebb, mint 4.5V stb. Tehat minel nagyobb aramot probalsz meg levenni annal kisebb lesz a feszultseg a labon.

UI: Meg van egy ilyen tablazat is, ami azt javasolja, hogy 20mA egy labon, osszesen 200mA a chipen. Az a 181. oldaltol van...
(#) possim hozzászólása Jan 30, 2012 /
 
Sziasztok!
Szeretnék tanácsot kérni tőletek. Most próbálok meg ismerkedni a uP-kel. Van egy AT89s52-esem ISP programozóval. C-ben szeretném programozni a procit, de azt hogy C-től HEX-ig hogy jutok el azt nem tudom.
Letöltöttem az AVR-studiót, de akármit csinálok, a legegyszerűbb programot is hibát ír ki. Valami javaslatot szeretnék kérni, hogy mit használjak és hogy hogy kezdjem el.
Következő: »»   402 / 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