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   601 / 839
(#) zotyaka válasza kapu48 hozzászólására (») Ápr 24, 2014 /
 
Szia!

Az SCL 100KHz-en fut, az F_CPU a külső órajelere van definiálva. 7372800UL.

Az a baj hogy ezt állítottam nagyon alacsonyra és nagyon magasra is mármint az SCL órajelét (100 és 400KHz között) semmi reakció nem történt.

Igazából hibakeresésben gondolkodtam. Mivel bosszant a dolog így hiába váltottam át belső eeprom-ra. A külső eepromot is életre keltem valahogy. Nem létezik hogy ennyire balfék legyek.
(#) kapu48 válasza zotyaka hozzászólására (») Ápr 24, 2014 /
 
Akkor hallgass Killbill-re dobd ki belőle az Vait részt!
Marad ennyi:
  1. void i2c_stop(void)
  2. {
  3.  
  4.     /* send stop condition */
  5.                 uint8_t   counter;
  6.                 counter = 1;
  7.                
  8.         TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
  9.  
  10.  
  11. }/* i2c_stop */


Csak jusson már túl azon az I2C_Stop-on!
(#) zotyaka válasza killbill hozzászólására (») Ápr 24, 2014 /
 
Szia!

A stop-ot kiadtam írás után. Ekkor fogja magát az avr és "lefagy". Hogy valóban nem csinál semmit vagy csak őrülten dolgozik azt nem tudom mert nem reagál. Próbaképp ott hagytam fél órára 1 db byte írását követően. Nos egy írási ciklus pár ms kell legyen. Ha fél óráig nem válaszol valami gond van. Azonban ha ezt követően reset-elem és nem engedem hogy írjon az eepromba akkor az előző írás címéről visszaolvasva a byte-t akkor azt kapom vissza amit beírtam hiába az írást követően "megfagyott".
(#) zotyaka válasza kapu48 hozzászólására (») Ápr 24, 2014 /
 
Ezt már próbáltam korábban.
Túljut a stop-on ebben az esetben viszont maga az írás nem történik meg ilyenkor. Visszaolvasva az "üres" 0xFF értéket kapom.
Viszont ha berakom a stop után a 10ms-os várakozási időt hogy befejeződjön az írási ciklus akkor megint kifekszik az egész ... :S
(#) kapu48 válasza zotyaka hozzászólására (») Ápr 24, 2014 /
 
Akkor lehet ez verem túlcsordulás hiba is!
(#) killbill válasza zotyaka hozzászólására (») Ápr 24, 2014 /
 
Ha attol lefagy az AVR, hogy az I2C buszon kiad egy STOP-ot, akkor ott valami nagy baj van... De mondjuk, ha azt nezem, hogy a STOP kiadasara az EEPROM elkezd irni, mert ugye akkor kezd, es ettol hirtelen megno az aramfelvetele, az esetleg okozhat gondot, mert megrangatja a tapot. 100nF hidegitok EEPROM-on, AVR-en vannak?
(#) killbill válasza killbill hozzászólására (») Ápr 24, 2014 /
 
De a teljes forrasszoveg lattan konnyebben lehetne eldonteni, hogy mi lehet a baj. Azt irod, hogy nem valaszol. Mi nem valaszol es mire?
(#) zotyaka válasza killbill hozzászólására (») Ápr 24, 2014 /
 
A kondik megvannak. Az avr fejlesztőkártyán van, az eeprom meg próbapanelon de kondikat bepakoltam.

A teljes forráskódot nehéz lenne bepakolni. library-k nélkül kb. 6-700 sor a program.

A nem válaszol az azt jelenti hogy az LCD kijelzőn sem megy semmi holott másodpercenként kellene frissíteni-e, nem megy a DS1307-el a kommunikáció mert az óra nem frissül. Tehát olyan mint szó szerint PC közegben lefagy az operációs rendszer.

Az hogy a mikrokontroller dolgozik-e valamin nem nagyon tudom megmondani. Aminek látható jele lenne az áll.
A hozzászólás módosítva: Ápr 24, 2014
(#) killbill válasza zotyaka hozzászólására (») Ápr 24, 2014 /
 
Ertem. Ez esetben nem sokat tudok segiteni, mert a forras ismerete nelkul ki tudja megmondani, hogy mi a baj? Merni kell meg debuggolni. De nem kell rogton debuggerre gondolni, van egy kijelzod, arra ki lehet irni pl. allapotokat, hogy eppen hol tart a program. Esetleg regiszterek allapotat, mit csinal az i2c modul, ilyesmik. Esetleg csinalsz egy teljesen fuggetlen projektet az osszes tobbi dolog nelkul, es csak az EEPROM-ot birizgalod. Interruptok es egyebek nelkul. Nem olyan bonyolult egy i2c eeprom irasa.
(#) zotyaka válasza killbill hozzászólására (») Ápr 24, 2014 /
 
A teljesen független projekt megvolt. Igyekeztem ráakadni a hibára de beletört a bicskám és bosszantó. De tuti én rontok el valamit.
Az állapotokat kiírattam és így jutottam el az írás stop metódusáig ott is a késleltetésnél történő lefagyáshoz.
Próbáltam fórumokon utánanézni de annyira "egyedi" a probléma hogy nem nagyon volt semmi. Csak furcsa hogy a ds1307-et gond nélkül kezeli (írás, olvasás), míg az eepromnál vacakol.
Avr jó, eeprom jó, i2c librarynak jónak kell lennie mert más i2c eszköz megy. Az adatlapot tövéről hegyére átnyálaztam semmi olyat nem látok amit ne tettem volna meg, sőt más hasonló projekteket is megnéztem (legalább atmega32 és 24lcxxx eeprom legyen) és ott megy ugyanabban a felállásban ahogy nekem van. Tehát kezdem azt hinni hogy nem szeret az eeprom
(#) killbill válasza zotyaka hozzászólására (») Ápr 24, 2014 /
 
A fuggetlen projekt is 6..700 sor?
(#) zotyaka válasza killbill hozzászólására (») Ápr 24, 2014 /
 
Jó néhány sort felölel, de ha kiveszem a karakteres lcd-n megjelenő menühöz tartozó kódot akkor lényegesen csökken a méret. Illetve eléggé megnyirbáltam a kódot már így is, óriási rumli van a kódban de remélem el lehet rajta igazodni
Ebben csak az lcd kijelző, a menü, a ds1307 lekérdezése és beállítása illetve az eeprom írás olvasás van.
eeprom library ha szükséges akkor feldobom azt is.

I2C külön projekt
(#) killbill válasza zotyaka hozzászólására (») Ápr 24, 2014 /
 
Az i2c library hasznos lenne, azt is mindjart megmondom, hogy miert. Hanem, ha a 75 es 76 sor koze beteszel egy 20ms delay-t, akkor is lefagy? Mert az iras alatt az EEPROM nem valaszol a cimere, azaz nem ad ACK-t. De nem tudom, hogy az i2c_start() fuggveny ezt hogyan kezeli. Amikor a 75 sorban meghivod az i2cwrite() fuggvenyt, akkor az elindit egy irast, es kozvetlenul utana nem lehet olvasni az EEPROM-ot.
(#) zotyaka válasza killbill hozzászólására (») Ápr 24, 2014 /
 
Itt is van.

I2C Library

Ha jól sejtem mire szeretnél rákérdezni akkor igen lefagy.
(#) kapu48 válasza zotyaka hozzászólására (») Ápr 24, 2014 /
 
Megszakításban nem kezelünk LCD-t!
Túl időigényes!

  1. ISR(INT2_vect)
  2. {
  3. Megszakításban nem lehet újabb megszakítást kérni! Mert felborul a verem kezelés.
  4.         sei();  << Ez pedig itt értelmetlen!
  5.         lcd_update_off=1;
  6.         LCDClear();
  7.         LCDGotoXY(5,0);
  8.         LCDWriteString("MAIN MENU");
  9.         LCDWriteStringXY(0,2,">");
  10.         LCDWriteString(&menu[item][0]);
  11.         LCDGotoXY(1,3);
  12.         LCDWriteString(&menu[item+1][0]);
  13.         mainmenu();
  14.         mainmenuexit=0;
  15.         lcd_update_off=0;
  16. }


És különben is, mi van ha EPPROM írás közben esikbe 1 ilyen kegyetlen hosszú megszakítás!
Szerintem borul az egész!
A hozzászólás módosítva: Ápr 24, 2014
(#) zotyaka válasza kapu48 hozzászólására (») Ápr 24, 2014 /
 
Szóltam hogy tele van szeméttel a kód. Nem is szedtem ki belőle semmit mielőtt posztoltam.
LCD kezelésről nem tudtam hogy ennyire időigényesnek számít megszakításkezelésben.
Az interrupt engedélyezése ne kérdezd hogy maradt ott mert az réges régóta nincs benne a kódban.
Egyébként ez a megszakítás egy gombhoz tartozik tehát eeprom írás közben ez a megszakítás tuti nem esik be.
Természetesen a Timer-hez tartozó beeshet mert az a ds1307-től kérdezi le az időt.
(#) kapu48 válasza zotyaka hozzászólására (») Ápr 24, 2014 /
 
Ha az INT2-öt gombnyomás idézi elő?

Akkor pedig hiányzik belőle a gomb Prelezésének a lekezelés.
Ami miatt biztos, hogy legalább 2* egymás után meghívódik!
(#) killbill válasza zotyaka hozzászólására (») Ápr 24, 2014 /
 
Az eleg furcsa, hogy 20ms varakozas utan, amennyi ido biztosan eleg az EEPROM-nak, akkor is lefagy. Ez nem normalis. Szoval, az i2c_start() fuggveny visszaadja, hogy sikerult-e "megszolitani" az EEPROM-ot vagy nem. Tehat az eeprom_read es eeprom_write valahogy igy kellene kinezzen:
  1. eeprom_read(int addr, void *buf, int len)
  2. {
  3. char *p;
  4.  
  5.    p = (char *)buf;
  6.  
  7.    while(i2c_start(EEPROM_ID+I2C_WRITE));
  8.    i2c_write(addr >> 8);
  9.    i2c_write(addr & 255);
  10.    while(len-- >= 1)
  11.      *p++ = i2c_readAck();
  12.    *p = i2c_readNak();
  13.    i2c_stop();
  14. }

De ennel meg egyszerubb, ha a i2c_start() helyett az i2c_start_wait() fuggvenyt hasznalod, mert az pont erre valo a komment szerint.
(#) zotyaka válasza killbill hozzászólására (») Ápr 24, 2014 /
 
Én is erre jutottam hogy nem normális.
Sajnos a szakdolgozat határideje miatt kénytelen vagyok kidobni a 24lc512-őt a projektből, szó mi szó már ki is dobtam, de május elején ha sikerült leadni a szakdolgozatot akkor ennek az ügynek a végére járok mindenképp.
Ha esetleg érdekel a megoldás majd akkor szívesen kiírom mire jutottam és mi volt a hiba.

Mindkettőtöknek nagyon szépen köszönöm a segítséget!
1-1 virtuális sört megajánlok , én nem iszok így rátok bízom az elfogyasztását.

Később még jelentkezek a probléma megoldásával!
(#) killbill válasza kapu48 hozzászólására (») Ápr 24, 2014 /
 
Idézet:
„Megszakításban nem lehet újabb megszakítást kérni! Mert felborul a verem kezelés.”
Nem borul fel. It egy reszlet az ATmega128 doksijabol:

When an interrupt occurs, the Global Interrupt Enable I-bit is cleared and all interrupts
are disabled. The user software can write logic one to the I-bit to enable nested interrupts.

kb magyarul: Amikor megszakitas tortenik a Global Interrupt Enable I-bit torlodik es minden megszakitas tiltva lesz. A megszakitasi rutin egybe allithatja az I bitet, hogy engedelyezze az egymasba agyazott megszakitasokat.

Attol, hogy az EEPROM iras kozben jon be egy hosszu lefutasu interrupt, attol meg az EEPROM irasnak le kellene futnia rendben. De teljesen egyetertek veled abban, hogy megszakitasi rutin ne csinaljon hosszantarto dolgokat. Vagy ha mindenkeppen csinalnia kell, akkor engedelyezze a tovabbi interruptokat, hogy azok azert tudjanak menni, a foprogram legtobbszor varhat par ms-ot. A tobbi interrupt viszont altalaban nem varhat.
(#) killbill válasza zotyaka hozzászólására (») Ápr 24, 2014 /
 
Koszonom a sört, es varom a megoldast!
(#) killbill válasza killbill hozzászólására (») Ápr 24, 2014 /
 
10. sor helyesen: while(len-- > 1)
(#) Szabi1 válasza Szabi1 hozzászólására (») Ápr 24, 2014 /
 
Na a következő történt: Felprogramoztam egy AVR-t a következő kóddal:
  1. #include <avr/io.h>
  2.  
  3. int main(void) {
  4.   DDRB = 0xFF;
  5.   while(1) {
  6.     PORTB ^= 0xFF;
  7.   }
  8. }

Az egyik B portját rákötöttem a hibás AVR XTAL1 es lábára, adtam neki áramot és a hibás-AVR áramkörjén az egyik LED égett, miközbe induláskor felváltva kéne 5x ki/be a másik leddel a panelon. AVR- O -MAT programot használva próbáltam visszaírni a fuse biteket: de azt mondja hibaként AVR device not responding! Mintha ott se lenne úgy tesz.
(#) knmhb8 hozzászólása Ápr 25, 2014 /
 
Hello! Egy LED felgyulladását szeretném megoldani mikrokapcsolóval ugyanazon porton. Bárhogy is próbáltam nem jött össze... Meg lehet-e oldani, hogy a LED és a nyomógomb ugyanazon a porton legyen?
(#) Massawa válasza knmhb8 hozzászólására (») Ápr 25, 2014 /
 
Irq-val...
(#) kapu48 válasza killbill hozzászólására (») Ápr 25, 2014 /
 
Elméletben lehetséges.
De itt van rá a példa, hogy egy kezdőnek a gyakorlatban nem működik!

Mivel még nem ismeri eléggé a fordító IDE belső (rejtett) működését.

Most mi értelme van 1 gombnyomásra reagáló megszakításban, engedélyezni az újabb megszakítást?
Hacsak nem éppen az a cél, hogy kiakasszuk a programot?

Minden megszakítás rutin az elején elmenti a visszatérési címet + a használni kívánt regisztereket a verembe. Ez lehet akár 20 Byte Verem foglalás.

Most engedélyezzük a gomb prelezését, ezzel újabb megszakítás végrehajtását?
Ami meghívja kb. 3* önmagát: 3*20=60 BYTE + 4db. egymásba ágyazott Subroutine CALL 8 BYTE!
Bírja ezt a verem mérete?

Aztán nem értjük mért akad ki a programunk váratlanul?
Sokszor nem is ott ahol a tényleges hiba van.
(#) kapu48 válasza killbill hozzászólására (») Ápr 25, 2014 /
 
Most Zotyka példája: „ISR(TIMER1_COMPA_vect)”
Van benne vagy 30 szubrutinhívás. Legtöbbje a lassú reagálású LCD rutin!

  1. void LCD_update_time()
  2. {
  3.         if (lcd_update_off==0){
  4.                 unsigned char temp;
  5.                
  6.                 LCDGotoXY(6,3);
  7.                
  8.                 itoa(hours/10,temp,10);
  9.                 LCDWriteString(temp);
  10.                 itoa(hours%10,temp,10);
  11.                 LCDWriteString(temp);
  12.                 LCDWriteString(":");
  13.                
  14.                 itoa(minutes/10,temp,10);
  15.                 LCDWriteString(temp);
  16.                 itoa(minutes%10,temp,10);
  17.                 LCDWriteString(temp);
  18.                 LCDWriteString(":");
  19.                
  20.                 itoa(seconds/10,temp,10);
  21.                 LCDWriteString(temp);
  22.                 itoa(seconds%10,temp,10);
  23.         LCDWriteString(temp);}
  24.  
  25. }
  26.  
  27. void LCD_update_date()
  28. {
  29.         if (lcd_update_off==0){
  30.                 unsigned char temp;
  31.                
  32.                 LCDGotoXY(6,2);
  33.                
  34.                 itoa(year/10,temp,10);
  35.                 LCDWriteString(temp);
  36.                 itoa(year%10,temp,10);
  37.                 LCDWriteString(temp);
  38.                 LCDWriteString("/");
  39.                
  40.                 itoa(month/10,temp,10);
  41.                 LCDWriteString(temp);
  42.                 itoa(month%10,temp,10);
  43.                 LCDWriteString(temp);
  44.                 LCDWriteString("/");
  45.                
  46.                 itoa(day/10,temp,10);
  47.                 LCDWriteString(temp);
  48.                 itoa(day%10,temp,10);
  49.         LCDWriteString(temp);}
  50.  
  51. }
  52.  
  53. ISR(TIMER1_COMPA_vect)
  54. {
  55.         ds1307_getdate(&year, &month, &day, &hours, &minutes, &seconds);
  56.         LCD_update_time();
  57.         LCD_update_date();
  58.        
  59. }


Szerintem a hiba okozója itt megmaradt.
És fog még neki gondot okozni a gyakorlatban
(#) killbill válasza kapu48 hozzászólására (») Ápr 25, 2014 /
 
En gyakorlatban is hasznaltam ilyet, nem csak elmeletben. Es az is igaz, hogy egy kezdonek gondjai lehetnek vele, de egy kezdoknek mindennel gondjai vannak. Azon felul semmi nem igazolta azt, hogy a kerdezonek ezert nem mukodik az i2c iras. Amiert en beleszoltam az az, hogy a kijelentesed nem allja meg a helyet. Okozhat gondot a nested interrupt, de nem feltetlenul okoz. Oriasi kulonbseg. Nem lehet kijelenteni, hogy a cigaretta rakot okoz. Rizikofaktor, az teny.

Mellesleg szerintem eleve semmi ertelme egy gombnyomasra interruptot kerni. Nyomogombokat 10..50ms idokozonkent be lehet olvasni (timer interruptbol vagy maskepp). Ezzel rogton megoldodik a pergesmentesites, valamint konnyen lehet eloallitani a lenyomtak/felengedtek esemenyeket is, automatiukus ismetlest, barmit.

Hogy mennyi fer a stack-be az csak rajtad mulik. Amennyit adsz neki. Ha van 4k RAM es a vegere allitod az sp-t, es hasznalsz 2k RAM-ot masra, akkor marad 2k stack. Abban csak elfer 120 byte, nem? De igazad van, a stack tulcsordulas nagyon meglepo dolgokat tud muvelni, szamolni kell vele. Nem veletlenul szoktam en uzem kozben nezni, hogy egy programban a processzek mennyi stack-et hasznalnak.
(#) killbill válasza kapu48 hozzászólására (») Ápr 25, 2014 / 1
 
Most latom csak, hogy a TIMER1 ISR olvas az i2c buszrol. Na ez, az amitol osszedol minden, nem az LCD iras. Mert ez igen sulyos hiba. Ha barmilyen i2c muvelet kozben bejon ez a TIMER megszakitas es nekiall az i2c buszon kommunikalni, akkor igen nagy baj lesz.
(#) kapu48 válasza killbill hozzászólására (») Ápr 25, 2014 /
 
Ja! Hogy az órája is I2C-van?

Akkor közösen csak, csak megtaláltuk a hiba okát!

Közben még tanultunk is pár dolgot!
A hozzászólás módosítva: Ápr 25, 2014
Következő: »»   601 / 839
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