Fórum témák
» Több friss téma |
Fórum » CCS PIC Compiler
Na örülök, hogy megoldódott.
Az eszközökhöz tartozó header file-okban ezek a definíciók többnyire bitmaszkok. Ezért van az, hogy az argumentumban logikai OR-ral kell összefűzni, és úgy íródnak be valamelyik regiszterbe. Esetleg azt lehetne megnézni, hogy ezek jól vannak-e definiálva. Ha nagyon nem megy, akkor is érdemesebb a #byte direktíva használata, amivel regisztert tudsz változóhoz rendelni. Ez valahogy így néz ki (help alapján):
Így el tudod kerülni az ASM használatát a C kódban. Ezek keverése inkább akkor ajánlott, ha a feladat összetettsége miatt ASM-ben nagyon durva lenne (pl. egy USB driver), viszont kellenek a programba olyan részek, ahol a gépi utasítás szintjén kell mozogni (pl. nagyon pontosan kell időzíteni, optimalizálási megfontolások, stb.). A hozzászólás módosítva: Júl 10, 2013
En igy szoktam elintezni a regiszterek valrozokennt valo hasznalatat:
Ez itt a hasznalat:
Igy barmilyen regiszter barmilyen bitjet egyszeruen tudod irni, olvasni ASM betetek hasznalata nelkul, es meg a program hordozhatosaga is jobb.
Az interrupt-on-change titka a nevében is bent van. Szerintem azért nem válaszoltak a problémádra, mert azt hittük, hogy elolvastad a leírásban, hogyan kell használni.
Tehát: Ha beüt a megszakítás, akkor be KELL olvasni a portot, hogy a belső tárolóban elmentésre kerüljön az állapota. És ehhez képest, ha megváltozik, akkor hívja megint a megszakítást. Ez így prímán működik a CCS-ben.
De ezzel a #byte direktívával nem csak az első 256 regiszterhez (azaz a BANK0-ban levő regiszterekhez) tudok nevet rendelni?
Kedves sysy!
Köszönöm válaszodat! Viszont nem értem. A beolvasás alatt input_a() utasítást értesz? És ilynkor a port milyen belső tárolóban mentődik el?
Ez bele van építve a PIC port áramköreibe. Minden porthoz van egy D tároló. Abba írogatja bele az állapotát a portnak beolvasáskor. Semmi teendőd vele, csak olvass egyet a portról.
input_a(); ahogy írtad. A hozzászólás módosítva: Júl 10, 2013
Minden regiszterhez használhatod a #byte direktívát. Én a regisztereknek a címeit is szoktam használni. Például:
#byte PORTA 0xF80 #byte LATA 0xF89 #byte INTCON 0xFF2 és így tovább...
Kedves sysy!
Csak most volt időm tovább foglalkozni a dologgal. Beolvastam a PORTA-t még a main-ben is, meg az interruptban is, de nem működik. Bele sem megy az interruptba. A program bekapcsoláskor 1 másodpercre felkapcsolja a PORTC-n levő 8 LED-et, majd lekapcsolja. Ezt követően a PORTA2-re kötött optokapcsoló kikapcsolásával a PORTA2 magasra egy, meg kellene hívódnia az interruptnak, ami a PORTC-n levő LED-ek felét kapcsolgatja tesztelés céljából, de nem kapcsolódnak fel, azaz be sem lép az interruptba. Pedig a chip PORTA2-es lábán mérem is az alacsony és magas jelszintet. Mi hiányzik még a programból?
Szia!
Proteus-ban szimulálva a programodat úgy működik ahogy írod, hogy működnie kellene. Ha igaz a szimuláció, akkor a PORTA2 lábon nem érzékeli az átmenetet (Én kapcsolót tettem rá). Sajnos nem ismerem a CCS-t, de megpróbálhatnád a PORTA2 állapotát jelezni az egyik LED-el a while ciklusban.
Nem tudom, hogy Sasmadárnak hogyan működött a program, de a gomb bemenet nincs definiálva sehol. Nem változóként kellett volna definiálni, hanem hozzáre
Szia!
Ha jól látom gomb változó csak flag-ként van használva nem bemenetként. Ahogy írtam Proteus-ban működik. Nincs ilyen processzorom, így valóságban nem tudtam próbálni.
Kedves sysy és Sasmadár!
Köszönöm, hogy foglalkoztok a problémámmal. Én sem ülök a babérjaimon, hanem próbálom kideríteni a hiba okát. A Bővebben: Link hozzászólásomban levő kis tesztprogramnak megnéztem a CCS C v4.114-ben történő fordításakor kapott lst file-ját:
Ebben a következő furcsaságokat találtam: 1. A 004D sorban BCF 0B.0 van írva a clear_interrupt(INT_RA) megfelelőjének, ami BCF INTCON.IOCIF-et jelent, azaz törli a IOCIF flag-et. Azonban a PIC16F1829 chip adatlapjában a 13.3 Interrupt Flags fejezetben írják, hogy "The IOCIF bit of the INTCON register reflects the status of all IOCAFx and IOCBFx bits." Illetve a 13.4 Clearing Interrupt Flags fejezetben "The individual status flags, (IOCAFx and IOCBFx bits), can be cleared by resetting them to zero." Továbbá a 8.6.1 INTCON REGISTER fejezetben "Note 1: The IOCIF Flag bit is read-only and cleared when all the Interrupt-on-Change flags in the IOCxF register have been cleared by software." Azaz szerintem nem úgy kell törölni az IOC megszakítás flag-jét, hogy törlöm az INTCON regiszter IOCIF bit-jét, hanem az IOCAFx regisztereket törlöm. 2. A 007D program sorban: MOVLB 07 = Bank 7 kiválasztása 007E programsorban BSF 14.2 = BSF IOCBP.2 azaz a PORTB 2-es pinjének pozitív átmenetének a figyelése!!! Azaz nem a PORTA 2-es pinjének figyelését állította be, hanem a PORTB 2-es pinjének. 3. A 0080 és 0081-es sor voltaképp 1-re állítja az INTCON regiszter GIE és PEIE bitjét. Hogy a PEIE bit-et minek kell 1-re állítani, azt nem tudom. Amikor ezt a teszt programot Assembly-be írtam meg, nem állítottam a PEIE bit-et 1-re, mégis működött a program. 4. A gomb változót csak arra használom, hogy az interruptot lekezelő szubrutinban hol egyik, hol másik sort hajtassam végre, azaz hol az első 4, hol a második 4 LED-et kapcsoljam fel, hogy lássam mikor lép be az interrupt-ba. Csak éppen egyszer sem lép be. 5. Kipróbáltam sysy a kódodat, de az sem működik. 6. A CCS C programnak megvolt a v4.108 verziója, de az még nem ismerte a PIC16F1829-es chipet. A legfrissebb CCS, amihez hozzájutottam, és már ismerte ezt a chipet, az a v4.114. Valószínűnek tartom, hogy ebben jelenhetett ez a chip meg először, és nem jól csinálták meg. Lehet a CCS C v5-össel már jól menne, de az sajnos nincs meg nekem. A hozzászólás módosítva: Júl 12, 2013
Szia!
Én 5.09-el fordítottam. A project-et úgy állítottam be, hogy nincs analóg bemenet használva. Ha Te nem állítottad be, akkor POTRA2 analóg bemenet reset után. ANSELA regiszter ANSA2 bit-et állítsd nullára, hogy digitális bemenet legyen. Bocs! Közben látom, hogy az általad fordított lista is törli ANSELA-t. Mellékelem az Én hex.-emet, ha van kedved próbáld ki, hogy a valóságban működik-e? A hozzászólás módosítva: Júl 12, 2013
Megnéztem nálam jó regiszterekkel fordított:
Kipróbáltam a hex file-t. Azt csinálja, hogy kb 5 másodpercig világít az összes lámpa. Majd kialszik. Ezután ha az optokapcsolót kikapcsolom (és ekkor a PORTA,2-re magas jel jut), akkor elkezd váltakozva hol az első 4, hol a második 4 LED lámpa világítani. Azaz szerintem mostmár bement az interruptba, csak valószínűleg most is úgy akarta törölni az IOC flag-et, hogy az INTCON-ban törli a 0-s IOCIF bit-et, ami viszont nem törölhető, csak olvasható. És a chip meg folyamatosan azt látja emiatt, hogy megint van egy megszakítás (mivel a vlóságban az IOCIF bit éréke 1 maradt), és újra bemegy a megszakítást lekezelő interrupt-ba, és átváltja az egyik 4 LED világítását a másik 4 LED világítására. Érdekes, hogy még az 5.09-ben sem tudták ezt az IOC-t normálisan megcsinálni.
Feltöltenéd az lst file-t is? Megnézném benne, hogy hogy törli az interrupt flag-et a megszakítás szubrutinjában. A hozzászólás módosítva: Júl 13, 2013
Mellékelem. Valóban törli INTCON-IOCIF-et még mindig. IOCAF.IOCAF2 bit-et viszont a programból kell törölni és ha IOCAF és IOCBF minden bitje 0, akkor törlődik INTCON.IOCIF.
Érdekes, hogy a szimulátorban csak a felfutó élekre váltanak a LED-ek.
Beírnál a program elejére egy #byte IOCAF = 0x393 sort, a megszakítást lekezelő szubrutin végére pedig egy IOCAF = 0x00 sort? És akkor ezzel szoftveresen törölnénk a megszakítás flag-et, és akkor szerintem már nem villognának felváltva a 4-4 LED. Ugyanis szerintem most is csak a felfutó élre vált a LED, csak mivel a megszakítást jelző flag nem lett törölve, így ahogy kijön a megszakítást lekezelő szubrutinból a program futás, már megy is vissza, mert azt hiszi, egy újabb felfutó él jött.
És akkor leellenőrizném a futását a chip-en élőben. Szerintem ezzel meg is lesz oldva a dolog. Illetve ha van 5.09-es CCS-ed, elküldenéd az ebben levő 16F1829.h header filet (valahol a Program Files\PICC\Devices könyvtárban vannak)? Meg szeretném nézni, hogy abban már benne van-e a PORTB-re vonatkozó IOC is. Ugyanis a v4.114-ben a header fileban csak a PORTA-ra vonatkozó IOC van benne, a chip adatlapja alapján (illetve Assembly-ben meg is csináltam) a PORTB-n is van IOC megszakítás. A hozzászólás módosítva: Júl 13, 2013
Módosítottam. IOCAF törlését az adatlap szerinti metódussal érdemes csinálni, hogy ha esetleg közben történt még I/O esemény az ne vesszen el lekezeletlenül.
A hozzászólás módosítva: Júl 13, 2013
Köszi, ezt már csak holnap próbálom ki, mert már elraktam a próbapanelt meg programozót. Jó éjt.
Csatolom a header-t. Jó éjt.
A hozzászólás módosítva: Júl 13, 2013
Így törli IOCAF.IOCAF2-t is:
Idézet: „.................... CLEAR_INTERRUPT(INT_RA2_L2H); 004D: MOVLB 07 004E: BCF 13.2 004F: BCF 0B.0 ”
Csak érdekességképpen jegyzem meg, hogy a PORTA.2 láb mellesleg az ext_int lába is a PIC-nek. Ezt használva és nem IOC-ként kezelve, nem kell játszadozni a bitekkel, mert ezt korrektül kezeli a CCS.
Kedves Sasmadár!
Az általad a v5.09-el fordított program tökéletesen működik. Csak felfutó élre megy bele az iterruptba. A v5.09-es CCS verzióból csatolt 16F1829.h header file-ban pedig már látom, hogy a PORTB IOC-je is benne van, nem csak a PORTA-é, mint nekem a v4.114 verzióban. Bárcsak nekem is v5.09-es verzióm lenne, és nem vesztegettem volna el 2 hetet ezzel az IOC-vel a rossz működés miatt. Annak ellenére, hogy tudjuk, hogy a v5.09-ben már jól működik ez a 16F1829 chip esetén, ennek ellenére nekem ASM-ben kell ezt megírnom a v4.114-es CCS-emen belül, mert ráadásul nekem a PORTB-n kell ez a IOC funkció. Azt még kipróbálhatnánk, hogy a v5.09 verzión belül kell-e az interruptban a PORT olvasása. Mert a 16F1829-es adatlapjában az IOC fejezetben én ezt nem olvastam, hogy "be KELL olvasni a portot, hogy a belső tárolóban elmentésre kerüljön az állapota. És ehhez képest, ha megváltozik, akkor hívja megint a megszakítást." Azaz ki kellene úgy is próbálni, hogy az interruptnál meghívott szubrutin elejéről ki kellene törölni az input_a() sort.
Kedves sysy.
Ez igaz, de nekem 2 db PORTB lábon kell IOC funkció majd. Le is írom, hogy mihez csinálom ezt az egészet. Egy majdan saját használatú nyák levilágító berendezés vezérlését tervezem. A mikrovezérlő a következőképpen fog működni: Egy egérből kiszedtem a görgetőgomb és az alatt levő nyomógomb részt (a görgetővel együtt az ott levő Infraled-et és annak jelét vevő fototranzisztort, ami ráadásul olyan kivitelű, hogy kettő az egyben, mivel kettő kell ahhoz, hogy az egérgomb forgatásának irányát is meg lehessen határozni). Namost ha benyomkodom a gombot, azzal kiválaszthatom, hogy a levilágítás időtartamát, vagy a melegítés időtartamát, vagy a melegítés hőmérsékletét akarom beállítani. Ezek közül amelyik ki van választva, annak az időtartamát meg a görgő görgetésével tudom beállítani. Lesz még egy nyomógomb, aminek megnyomásával a levilágítás vagy a melegítés indítható. A levilágítás alatt azt értem, hogy a fóliára kinyomtatott áramkört ráteszem a lakkal befújt nyáklapra, és UV lámpával világítom a beállított ideig. A melegítés alatt pedig azt értem, hogy a lakkal befújt nyáklapot valamilyen hőforrással (még nem tudom mi lenne a legalkalmasabb erre a célra) melegítem, hogy a lakk minél hamarabb megszáradjon a nyáklapon. Ez egy ládaszerű berendezés volna, aminek a lehajtható tető részében lenne a melegítő rész, az alja felén meg a levilágító UV csövek. Mert jelenleg filctollal rajzolom az áramkört a nyákra, és maratom le utána vas-kloriddal a felesleges rezet. És ez a filctollas áramkör átrajzolás meglehetősen időigényes. A berendezésen a kapcsolattartást egy LCD kijelző biztosítja (8bites üzemmódra terveztem meg a nyákot, aztán jutott eszembe, hogy 4bittel is lehet vezérelni). Kell még 2 pin az LCD enable és utasítás/adat pinjéhez. Kell 1-1 pin a funkció választó nyomógombnak illetve a start gombnak, ami a levilágítást vagy a melegítést indítja. Kell 2 pin a görgőnek. Kell 2 pin az Uv csöveket illetve a melegítő egység reléjét kapcsoló tranzisztornak, valamint 1 pin a hőmérséklet mérő szenzornak (a DS1820 hőmérséklet szenzorral 1 pinen is lehet kommunikálni). És ekkor 17 pin-nél járunk. Kell még 1-1 pin a föld és a Vdd-nek. Így jött ki, hogy egy 20 pin-es chip kell. Mondjuk első körben csak a levilágító részt fogom megépíteni, a melegítést majd megoldom manuálisan egy hajszárítóval kezdetben. Csak úgy akartam ezt az egészet megcsinálni, hogy alkalmas legyen melegítéses funkcióra is. A nyákra terveztem egy 4 pinen csatlakozási lehetőséget ICSP (áramkörön belüli programozás) célra, hogy ha esetleg módosítani kell a chip-en a programot, akkor azt is meg tudjam csinálni. 2 éve kezdtem tanulgatni ezt a mikrovezérlős dolgot, mert érdekelt, egyébként gépészmérnök vagyok, és nagyon élvezem ezt a dolgot. Hála istennek itt van ez az internet is, ahol csomó tudást össze lehet szedni, köszönhetően azon önzetlen embereknek, akik ilyen kis bevezető leírásokat, jegyzeteket készítenek, illetve akik pl. ilyen fórumokon is segítenek azoknak, akik megakadtak valamiben. Kár, hogy nem fiatalabb koromban találták ki ezt az internetet.
Szia!
Kivettem a port olvasást csatolom a hex-et. Proteus-ban működik így is.
Egy kis kiegészítés az előző hozzászólásomhoz. Először meghatároztam, hogy milyen chip kell a feladathoz, és meg is vettem. Aztán azért kell a PORTB-s IOC, mert előre ittam a medve bőrére, és mivel láttam a 16F1829 adatlapján, hogy a PORTB-n is van IOC, én oda terveztem azokat a dolgokat, amihez az IOC kell. És már le is gyártottam a nyákot, és ezután kezdtem neki a vezérlőprogram megírásához. Akkor szembesültem azzal, hogy a nekem meglevő CCS v4.086 nem is ismeri ezt a chip-et. Akkor ami frissebb verzióhoz "hozzájutottam", az a v4.114 volt. Ez már ismerte, bár azt a header file alapján rögtön furcsáltam, hogy miért csak a PORTA-s IOC-t ismeri. Mindenesetre elkeztem próbálkozni a PORTA-s IOC-vel, ami nem sikerült vele. Akkor írtam ASM-ben ilyen LED villogtatást az IOC tesztelésére, és az működött mind a PORTA, mind PORTB esetén. Azaz a chip az jó. Úgyhogy tovább próbálkoztam a CCS-el PORTA-s IOC-t csinálni, hátha csak én rontottam el valamit, és jártam ezt a fenti kanosszajárást.
Mindenesetre most ma hozzájutottam az 5-ös CCS-hez köszönhetően Nektek. Úgyhogy mostmár menni fog egyszerűen a dolog. Köszönöm segítségeteket. A hozzászólás módosítva: Júl 14, 2013
Kedves Sasmadár!
Kipróbáltam, és ahogy sejtettem, így is tökéletesen működik élőben is. Csak a felfutó élre indul az interrupt, és csak egyszer fut le egy felfutó élre.
Viszont most hogy már nekem is van CCS 5, kipróbáltam az IOC funkciót PORTB 4-es pinjére, aztán a 7-es pinjére is, de itt már a lefutó élnél is belemegy a megszakítást lekezelő ciklusba. Megírtam a teljes programot MPLAB-ban assembly-ben, és annál is úgy működött, hogy a lefutó élre is belement a megszakításba. Ez viszont már valami CHIP probléma lehet.
Errata nem ír ilyen hibáról. Proteus-ban működik átírva PORTB4-re és PORTB7-re.
|
Bejelentkezés
Hirdetés |