menü navigáció
INT alapszabálya: Maradj rövid! Amíg egy INTben vagy benne, addig másik INT nem eshet be -> adat és funkcióvesztés. A Bascom mintákban is írom (ahol nem felejtettem el:) hogy NEM szabad hosszan várakozni INT-ben...
Más a példa/modellezés, és más a való életbeli alkalmazás. A várakozásmentes kezelés az lesz a TIMER alapú
Más a példa/modellezés, és más a való életbeli alkalmazás. A várakozásmentes kezelés az lesz a TIMER alapú
Nekem ezzel a rutinnal működöt a bil-mátrix kezelés:
http://avr.tavir.hu/modules.php?name=Fo ... opic&t=512
http://avr.tavir.hu/modules.php?name=Fo ... opic&t=512
Kapu köszi a példát, átnézem majd mindenképpen alaposabban. Most megint nekiállok mert eddig nem tudtam vele foglalkozni.
Egy korábbira, az AND-es If feltételre: igaz hogy egy változó egyszerre nem lehet két külön dolog, viszont az azt vizsgálta hogy csak akkor fusson le ha egyik sem, tehát sem "" sem ?.
Egy korábbira, az AND-es If feltételre: igaz hogy egy változó egyszerre nem lehet két külön dolog, viszont az azt vizsgálta hogy csak akkor fusson le ha egyik sem, tehát sem "" sem ?.
Elkészült a "remekmű":
A bill.t továbbra is interrupt alapon kezelem, csak lecsökkentettem a debouncetime-ot 10 ms-re. Megváltoztattam a interrupt végén lévő GIFR=64 -et Gifr.intf0 = 1-re, nem tudom hogy van-e különbség mert elvileg itt is ugyan az a bit állítja az INT0-t mint a 2313-ba. Mindenesetre ez a két változás jelentős javulást hozott 256 lenyomásból kb. 2 volt kérdőjel/duplán lefutott int. A probléma oka biztos hogy az volt hogy az interrupt többször futott le. A fenti ciklus elején az AND feltétel mindenképpen szükséges különben feleslegesen fut le folyamatosan az ellenőrzés (üresre sem kell és kérdőjelre sem). Ezzel a megoldással minden úgy működik ahogy szeretném. Így az újraírás/átgondolás végén azt gondolom hogy a sietség miatt a program más részéből átvett, majd loop-os feldolgozásra alakított rutin vitt el a rossz útra. A kettő teljesen más logikát igényel. Köszönöm a hasznos hozzászólásokat/mintakódokat. Ebből a 20 sorból is tanultam valamit.
Kód: Egész kijelölése
Keychar = ""
Index = 1
Do
If Keychar <> "" And Keychar <> "?" Then 'ellenőrizzük hogy se nem üres se nem ? a feldolgozásra váró karakter
If Keychar = "A" Then Exit Do ' Ha "A" akkor kilépünk a szerkesztésből
If Keychar = "R" Then 'Ha "R" akkor...
Ido_bajt(index) = Val(ido_szoveg) 'Átalakítjuk szöveggé majd eltesszük a tömbbe az adott értéket
Incr Index 'Növeljük az index változót
Keychar = "" 'Ürítjük a gomb olvasás tárolóját
If Index = 5 Then Index = 1 ' Ha túlmegy az index visszaállítjuk az első értékre (menü vége -> eleje)
End If
If Len(ido_szoveg) < 2 Then 'Amíg kisebb mint 2 addig összerakjuk a két darabot
Ido_szoveg = Ido_szoveg + Keychar
Else
Ido_szoveg = Keychar ' Ha nagyobb akkor új szám jön
End If
Hely_index = Index + 1 ' kiszámítjuk az indexből a locate-hez szükséges X koordinátát
Hely_index = Hely_index * 3 '3 karakterenként kerülnek kíírásra az értékek
Locate 2 , Hely_index : Lcd Ido_szoveg 'kiirjuk a megfelelő helyre az adott értéket
If Len(ido_szoveg) = 2 Then Locate 2 , Hely_index 'a második karakter után a kurzort visszaállítjuk az első karakter alá
Keychar = "" ' Ürítjük a tárolót
End If
Loop
Cursor Off
Cls
Wait 2
doncarlos
Ha a GIFR regiszterbe 64-et írunk, az INT0 btet tudjuk törölni, megakadályozva a prellegés miatt, nem kívánt további megszakítás kiváltását.
Ugyanezen célból a 2313-nál az EIFR regiszter kell kezelni, ott ez a regiszter gyűjti az INTx biteket.
A regiszterbe 1-et írva (teljesen feleslegesen) nincs hatással, ott nincs működő bit, lásd az alábbi ábrát.
A GIFR regiszter megadott bitjét a hardver állítja 1-be, ezzel megszakítást vált ki, ha az engedélyezett. Az adott bitet pedig úgy tudjuk törölni, és ezzel a többszörös megszakítást elkerülni, hogy a bitbe mi írunk 1-et. Így a GIFR=64 értékadás törli az INT0 bitet.
Ha a GIFR regiszterbe 64-et írunk, az INT0 btet tudjuk törölni, megakadályozva a prellegés miatt, nem kívánt további megszakítás kiváltását.
Ugyanezen célból a 2313-nál az EIFR regiszter kell kezelni, ott ez a regiszter gyűjti az INTx biteket.
A regiszterbe 1-et írva (teljesen feleslegesen) nincs hatással, ott nincs működő bit, lásd az alábbi ábrát.
A GIFR regiszter megadott bitjét a hardver állítja 1-be, ezzel megszakítást vált ki, ha az engedélyezett. Az adott bitet pedig úgy tudjuk törölni, és ezzel a többszörös megszakítást elkerülni, hogy a bitbe mi írunk 1-et. Így a GIFR=64 értékadás törli az INT0 bitet.
Szia!
Lehet, félreolvastam, de:
Szerintem pont fordítva van.
Ha bejött egy INT, akkor a hozzá tartozó bit 1-be billen és a uC elmegy egy JMP-al a megfelelő fix címre. Ha RETI-t talál, akkor nullázza a bitet (és visszamegy), így elérve, hogy jöhessen a köv. megszakítás. Ameddig ez a bit 1-ben van másodikat nem fogad el. Ha az INT rutinban kinullázod a jelzőbitet (1-et írsz oda), akkor engedélyezed, hogy bejöhessen még egyszer (vagy más INT).
Az igaz, hogy gyűjti az INT biteket, ha egyikkel végzett sorban veszi a következőket, végrehajtás után nullázza ezeket.
Mivel a balfék AVR-ekben nincs prioritásos INT, így sorban hajtódnak
végre, ha nagyon kell valami gyors válasz, akkor érdemes bizergálni a jelzőbiteket (pl. real-time kell billegtetni valamit vagy időt mérni, de megy a soros INT-es kommunikáció, akkor a soros INT-ben kilövöd a soros INT bitet, így a Timer INT be tud futni megszakítva a soros INT-et).
JAni
Lehet, félreolvastam, de:
Szerintem pont fordítva van.
Ha bejött egy INT, akkor a hozzá tartozó bit 1-be billen és a uC elmegy egy JMP-al a megfelelő fix címre. Ha RETI-t talál, akkor nullázza a bitet (és visszamegy), így elérve, hogy jöhessen a köv. megszakítás. Ameddig ez a bit 1-ben van másodikat nem fogad el. Ha az INT rutinban kinullázod a jelzőbitet (1-et írsz oda), akkor engedélyezed, hogy bejöhessen még egyszer (vagy más INT).
Az igaz, hogy gyűjti az INT biteket, ha egyikkel végzett sorban veszi a következőket, végrehajtás után nullázza ezeket.
Mivel a balfék AVR-ekben nincs prioritásos INT, így sorban hajtódnak
végre, ha nagyon kell valami gyors válasz, akkor érdemes bizergálni a jelzőbiteket (pl. real-time kell billegtetni valamit vagy időt mérni, de megy a soros INT-es kommunikáció, akkor a soros INT-ben kilövöd a soros INT bitet, így a Timer INT be tud futni megszakítva a soros INT-et).
JAni
JAni!
Ugyanarról beszélünk, csak másképp!
Éppen fordítva gondolkodj. Először a hardveresemény, például INT0 bemenet jelszint változása, 1-be állítja a megfelelő bitet a GIFR regiszterben, és ez az "1"-es vált ki megszakítást, feltéve, hogy a globális megszakítás is engedélyezve volt.
Másfelől: a RETI nem nullázza a bitet, a RETI utasítás a veremkezelésnél játszik szerepet, és ismét engedélyezi a globális megszakítást. Ha azonban a megszakítás rutin végrehajtása alatt újabb megszakításkérés esne be ugyanabból a forrásból, itt az INT0 bemenet miatt, mert prelleg a billentyűzet, a felhasználónak kell a "fals" megszakításkérést törölni a bittörléssel.
Nézd meg a Bascom lecke adott példaprogramját.
http://avr.tavir.hu/images/contents/i2c ... ch-int.bas
Ha többszörös megszakításkérésről van szó, A RETI hatásár ismét engedélyezett globális megszakítás engedélyezés után a "balfék" AVR tudni fogja hogy más forrás IT kérését is le kell kezelnie.
Az egyes IT források a megfelelő IT biteket állítgatják, közben egy újabb IT kérés a megszakítás folyamatát nem tudja megszakítani, hiába engedélyezett, mert közben a globális megszakítás tiltva van. És hát minden lehetséges megszakítás kérést egyedileg engedélyezni kell, ha ez a terv!
És amit még hozzá lehet fűzni:
Minden megszakításforráshoz külön IT vektor tartozik, ezért van a hivatkozott Bascom programban a On Int0 Pcfint hivatkozás. Így ha az INT bemenethez rendelt megszakítás rutin végrehajtódik végre, az "magától" törölni fogja a GIFR regiszter INT0 bitjét. Ezért a bittörléssel nem kell nekünk foglalkozni, speciális esetektől eltekintve, például a "debounce" ideje alatti prell IT kérésének törlése.
Ugyanarról beszélünk, csak másképp!
Ha bejött egy INT?Lehet, félreolvastam, de:
Szerintem pont fordítva van.
Ha bejött egy INT, akkor a hozzá tartozó bit 1-be billen és a uC elmegy egy JMP-al a megfelelő fix címre. Ha RETI-t talál, akkor nullázza a bitet (és visszamegy), így elérve, hogy jöhessen a köv. megszakítás. Ameddig ez a bit 1-ben van másodikat nem fogad el. Ha az INT rutinban kinullázod a jelzőbitet (1-et írsz oda), akkor engedélyezed, hogy bejöhessen még egyszer (vagy más INT).
Az igaz, hogy gyűjti az INT biteket, ha egyikkel végzett sorban veszi a következőket, végrehajtás után nullázza ezeket.
Éppen fordítva gondolkodj. Először a hardveresemény, például INT0 bemenet jelszint változása, 1-be állítja a megfelelő bitet a GIFR regiszterben, és ez az "1"-es vált ki megszakítást, feltéve, hogy a globális megszakítás is engedélyezve volt.
Másfelől: a RETI nem nullázza a bitet, a RETI utasítás a veremkezelésnél játszik szerepet, és ismét engedélyezi a globális megszakítást. Ha azonban a megszakítás rutin végrehajtása alatt újabb megszakításkérés esne be ugyanabból a forrásból, itt az INT0 bemenet miatt, mert prelleg a billentyűzet, a felhasználónak kell a "fals" megszakításkérést törölni a bittörléssel.
Nézd meg a Bascom lecke adott példaprogramját.
http://avr.tavir.hu/images/contents/i2c ... ch-int.bas
Ha többszörös megszakításkérésről van szó, A RETI hatásár ismét engedélyezett globális megszakítás engedélyezés után a "balfék" AVR tudni fogja hogy más forrás IT kérését is le kell kezelnie.
Az egyes IT források a megfelelő IT biteket állítgatják, közben egy újabb IT kérés a megszakítás folyamatát nem tudja megszakítani, hiába engedélyezett, mert közben a globális megszakítás tiltva van. És hát minden lehetséges megszakítás kérést egyedileg engedélyezni kell, ha ez a terv!
És amit még hozzá lehet fűzni:
Minden megszakításforráshoz külön IT vektor tartozik, ezért van a hivatkozott Bascom programban a On Int0 Pcfint hivatkozás. Így ha az INT bemenethez rendelt megszakítás rutin végrehajtódik végre, az "magától" törölni fogja a GIFR regiszter INT0 bitjét. Ezért a bittörléssel nem kell nekünk foglalkozni, speciális esetektől eltekintve, például a "debounce" ideje alatti prell IT kérésének törlése.
Szia!
Így jár, aki többféle proccal boldogítja magát.
Az kiment a fejemből, hogy INT-nél ez a pupák a GlobalisINT bitet tiltja, tehát azt kell bizergálni, ha akarok megszakított futó INTet kezelni. A RETI elméletileg törli a hozzátartozó INT-flag-et, legalább is így logikus, no meg ezt írja a leírás (a flag törlődik, ha az INT rutin végrehajtódott...az meg csak akkor van, ha RETI-t talál).
Na, szóval ez van, ezt kell szeretni, nem vitték túlzásba az INT kezelés tudományát, az tutti.
JAni
Így jár, aki többféle proccal boldogítja magát.
Az kiment a fejemből, hogy INT-nél ez a pupák a GlobalisINT bitet tiltja, tehát azt kell bizergálni, ha akarok megszakított futó INTet kezelni. A RETI elméletileg törli a hozzátartozó INT-flag-et, legalább is így logikus, no meg ezt írja a leírás (a flag törlődik, ha az INT rutin végrehajtódott...az meg csak akkor van, ha RETI-t talál).
Na, szóval ez van, ezt kell szeretni, nem vitték túlzásba az INT kezelés tudományát, az tutti.
JAni
Szia!
Azért az AVR-nél az IT kezelés mégis csak jól ki van találva... !
A PIC16Fxx mikrovezérlőknél (megjegyzés: én örök PIC szerelmes voltam, leszek) tényleg "vacak" a helyzet. Bármely engedélyezett megszakítás az egyetlen, 4-es című IT rutint indítja. Ott a felhasználónak kell kitalálna, ki kérte a megszakítást, melyik bitet kell törölni, mi törlődik magától stb.
Az AVR persze más, igaz ö a fiatalabb ...
Azért az AVR-nél az IT kezelés mégis csak jól ki van találva... !
A PIC16Fxx mikrovezérlőknél (megjegyzés: én örök PIC szerelmes voltam, leszek) tényleg "vacak" a helyzet. Bármely engedélyezett megszakítás az egyetlen, 4-es című IT rutint indítja. Ott a felhasználónak kell kitalálna, ki kérte a megszakítást, melyik bitet kell törölni, mi törlődik magától stb.
Az AVR persze más, igaz ö a fiatalabb ...
PIC nincs a közelemben, anno mikor azt mondta egy barátom, hogy 1 stack van benne, egy életre elfelejtettem, de ezt, amit írtál azért nem gondoltam volna. Igaz, a PIC32-ről csodákat regélnek, gondolom csak fejlődnek ők is...
Hiába újabb az AVR, 30 éve az MCS51 őstipusban is azért normálisabb megszakítás volt (2 szint legalább), nem beszélve a mostani klónokról (16 szint), de most azért meglepődtem, hogy az INT még a PSW-t sem menti automatikusan.
De azért szeretjük ám. Csak lenne kicsit gyorsabb, meg a SW INT azért nagyon jó lenne...
De mi van akkor, ha futó INTben kinullázom az összes INT-flag-et és 1-be rakom a globális INT bitet?
JAni
Hiába újabb az AVR, 30 éve az MCS51 őstipusban is azért normálisabb megszakítás volt (2 szint legalább), nem beszélve a mostani klónokról (16 szint), de most azért meglepődtem, hogy az INT még a PSW-t sem menti automatikusan.
De azért szeretjük ám. Csak lenne kicsit gyorsabb, meg a SW INT azért nagyon jó lenne...
De mi van akkor, ha futó INTben kinullázom az összes INT-flag-et és 1-be rakom a globális INT bitet?
JAni