Fórum témák
» Több friss téma |
Üdv Mindenkinek!
PIC16F628-ból próbálnék rs232 megszakítást kikönyörögni. Annyi sikerélményem már van, hogy adatvételkor elugrik az interrupt szubrutinra, de az a baj, hogy ott is marad, tehát interrupt után nem tér vissza a főprogramba, hanem az interrupt szubrutinnál lefagy a program. Tudnátok valami ötletet adni?! Esetleg forráskódot(asm, ccs,...)? Köszönöm!
CCS-re:
interrupt rutinokból nem RET, hanem RETI v IRET utasítással kell visszatérni, bár picet nem programozok, így nem azoknál mi a megfelelű utasítás...azt nem irtad milyen nyelven progizol...
RETFIE utasítással, de csakis a work és status visszatöltése után.
az én kódom annyiban különbözik, hogy nincs benne ez: "stream=pc" és a getc()-be se raktam bele a "pc" karakterpárost. Mit jelentenek ezek a kifejezések ("stream=pc" és getc()-ben a "pc")? Egyébként egy pillanat és kipróbálom. Nagyon köszönöm a gyors válaszokt!
Szóval, most ott tartok, hogy a szubrutinra ugráskor nem fagy le a program, és visszatér a főprogramba, de ezt csak egyszer hajlandó megcsinálni, tehát:
1, bekapcsolom 2, főprogram fut 3, sr232 adat olvasásra szubrutinra ugrik 4, szubrutinból visszatér De a szubrutinból való visszatérés után nem reagál többször a megszakításra. Most mit csináljak?
Nem hajtod végre a megszakításnál elengedhetetlen lépéseket: Bővebben: Link
Értem, de végig olvastam a linket, amit adtál, s a C programban leírtakkal az én programom is megegyezik. Valamint a cikkben az alábbi van ismertetve: "C nyelv esetén nem kell törődnünk a regiszter lementésekkel, mert ezt megoldja a fordító". Tehát a megszakításom tökéletesen működik, de csak egyszer. Mit kell beállítanom? Valamelyik flag-et kell törölni? Vagy valamelyik regiszter értékét kell beállítani? És ezt C nyelven hogyan? Miért van az, hogy mindig csak egyetlen egyszer képes végrehajtani a megszakítást és aztán többször nem? Szubrutinra ugrik->Utasítást végrehajt-> visszaugrik->folytatja a főprogramot, de ettől kezdve nincs tovább megszakítás
A PIR1 regiszter RCIF bitjét törölni kellene. 18F-nél az RCREG regiszter olvasásával törlődik, de a 16-os sorozatnál tudomásom szerint nem. Úgy hogy asm-ben: bcf PIR1,RCIF.
Igen, már másfél órája lapozgatom a pic16cxx jegyzetemben a megszakítás kezelést és éppen most kezdett gyanússá válni ez a regiszter, de most, hogy már te is ezt tanácsolod, így már biztos vagyok benne, hogy ez lesz a hiba. Be is illesztettem a C fordítóba, hogy:
#ASM BCF PIR1,RCIF #ENDASM de nem fordítja le kódot, pedig biztos, hogy ez lesz a megoldás. Nagyon-nagyon köszönöm a javaslatot. Próbálom beleerőszakolni a C programomba az asm kódot, szólok, ha sikerült...
ahhoz nem kell asm makró, egyszerűen megnézed, hogy hányas bit az RCIF és kimaszkolod...1 olvasás,egy és művelet és egy írás...
Az RCIF az 5-ös bit a PIR1 regiszterben. A PIR1 regiszter címe pedig 0x0C. Szóval akkor mit kell a CCS -be beírnom, hogy a fenti utasítást végrehajtsa, vagyis a PIR1 regiszter 5-ös bitjét törölje. Nem értem, hogy mit kell maszkolnom, éselnem stb. ahhoz, hogy ezt a bitet töröljem. Elmondanád és kisegítenél egy kódrészlettel, amit beszúrhatok a CCS-be?! Már 6 órája próbálom összehozni ezt a megszakítást és azt hiszem már csak ez az utasítás van hátra. Nagyon hálás lennék, és köszönöm az eddigieket is!
Előre a deklarációs részhez:
#byte PIR1 = 0x0C Majd utánna a megfelelő helyre: bit_clear(PIR1,5); a #byte-os sorral létrehozol egy bytera mutató pointert, ami mutat a 0x0C regiszterre. utánna ezt a CCS-ben ugyanúgy tudod kezelni, mint egy normál változót. Így akár bit_clear-elheted is. Bár nem értem továbbra sem, hogy a CCS-ben miért nem működik neked az interrupt. Rendesen hiba nélkül kell működnie.
Nos, köszönöm a választ, módosítottam a programot, de ígysem működik! Végülis ezzel az információval is egy új funkciót tanultam meg a CCS-ről, de az interrupt továbbra sem működik, csak így:
1, főprogram fut 2, rs232 megszakításra elugrik a szubrutinra 3, végrehajtja a szubrutint 4, visszatér a főprogramra, ami folytatódik ...de ez csak egyetlen egyszer hajtódik végre. Amikor egyszer "igénybe veszem" az interruptot, attól fogva nem hajlandó mégegyszer, csak ha ki/bekapcsolom az áramkört, vagy ha a MCLR lábat GND-re húzom, amivel resetet váltok ki. Szóval újraindítás után ismét működik a megszakítás, de csak egyszer.
Akkor ez hardver hiba. Ki/bemenetek rendben? Tegyél egy szkópot a tápra és nézd meg nincs-e rajta valami zavar soros jel közben.
Vagy esetleg vágj hozzánk egy kapcsrajzot, hogy tudjuk segíteni.
Végre, sikerült!!! Nos, nem teljesen azt csinálja, amit legelőször megálmodtam, de legalább már az interrupt többször is képes meghívódni reset nélkül is. Szóval azt csináltam, hogy szubrutint leegyszerűsítettem, hogy csak beolvassa az adatot és felvillant egy ledet, aztán ennyi:
char data; char kod[]={""}; #int_rda void rda_isr() { data=getc(pc); kod[i]=data; i++; output_high(PIN_A1); } Eddig pedig az volt, hogy: data=getc(pc); kod[i]=data; i++; output_high(PIN_A0); output_high(PIN_A1); delay_ms(10); output_low(PIN_A0); output_low(PIN_A1); delay_ms(10); output_high(PIN_A0); output_high(PIN_A1); delay_ms(10); output_low(PIN_A0); output_low(PIN_A1); Ötleteket mondanátok, hogy miért nem működhetett a több utasítást tartalmazó szubrutinnal? De végülis ez már csak részletkérdés, mert megoldódott a probléma. Azt tudni kell szerintem az adatokról, hogy egy 6x8bájtos adatsorozatot kellett fogadni. Mégegyszer nagyon köszönöm a segítőkészséget!
Megszakításban soha nem szoktunk / szabad hosszú utasítást írni.
Legtöbbször csak egy flag-et billent át a program és a main loopban történik minden utasítás végrehajtása. Így egyfajta szimultán, multitaskhoz hasonló feladat végrehajtást lehet megvalósítani. De azzal, hogy Te interruptban sleepeltél (delay), elkövetten a világ legnagyobb PIC-es és bármilyen processzoros hibáját ![]()
Csak azt tudom ehhez még zárásként hozzáfűzni, hogy minden fejlesztésből tanul az ember valamit. Köszönöm a hozzászólásokat, és a segítséget! Remélem, hogy más is tanulni fog a hibámból. (vagy nincs még egy ilyen hülye, mint én... )
Szívesen segítettünk, senki sem pákával vagy billentyűzettel az altájában született
![]()
Üdvözlet!
PC és PIC16F628 közötti kommunikációt próbálok megvalósítani az alábbi link alapján: http://www.oz1bxm.dk/PIC/628uart_c.htm A PIC üzenete sikeresen kiírodik a HyperTerminal ablakban, de amit a pc küld a PIC-nek, az nem kerül vissza a monitorra. A program: #include <16F628.h> #fuses INTRC_IO, NOLVP, NOWDT, PUT, BROWNOUT #use delay(clock=4000000) #use rs232(baud=9600, xmit=pin_B2, rcv=pin_B1) main() { printf("PIC16F628 alive\n\r"); // send alive message while(true) { putc(getc()); // echo the received characters } } Valakinek van valamilyen ötlete, hogy mi lehet a probléma? A pic-cel van a baj, vagy pc-vel? A válaszokat köszönöm előre is!
Először is több sebből vérzik. Első az INT_RC, ami miatt elcsúszhat az asszinkronitás.
A második pedig a tristate-ek. Ha a B1 bemenet, receive láb, akkor tedd még a mainba az elejéhez, hogy "set_tris_b(0b11111011);"
Nos, javítottam, de még így sem mükszik! Amit a pic elkuld a pc-nek, az a monitoron kiirodik, de ha a pc kuld a pic-nek, akkor nem történik semmi! Más ötleted van?
Üdv!
Probléma a következő: két pic16f628 rs232 keresztül kommunikál; -az egyik pic elküld egy számot a másiknak és a másik --felkapcsol a szám alapján egy ledet; -a kommunikáció működik is mindaddig, amíg próbapanel gnd-ből kivezetett drótot kézzel megfogom és szorítom. Amikor ezt a drótot elengedem, akkor a küldő pic működése leáll és nem küldi a számokat; Mi lehet a hiba? Szoftveres vagy hardveres? ![]() Nos kikapcsoltam, s így működik! ![]()
Viszont ez nem megoldás, hogy kikapcsoltad a BOR-t. Inkább a picek tápjának szűrését kellene rendbehozni.
Nos, igen! Valahogy éreztem, hogy ez kb. olyan megoldás, mint amikor a lakásomba betörnek és kikapcsolom a riasztót, miközben a betörők rámolják ki a lakásomat
![]() De mit kellene tennem? Mit javasolsz? Eddig annyit tettem, hogy a Vdd lábhoz tettem egy 100µF kondit. Az MCLR lábat is stabilizálni kéne? Mert ott csak egy 1K ellenállás van? Vagy a tápfeszt kell stabilizálni még? De ha nem elég a kondi, akkor hogyan stabilizálhatok még a 78L05 feszültségét?
A 100µF elektrolit az nem szűrés, az pufferelés. Egy-egy 100nF-os kerámiakondenzátort rakj a 78L05 bemenetére, kimenetére, és a pic táplábai közé is.
![]() ![]()
Olvasom, de nem követem
![]() Kinek is kell itt pont? ![]()
Adott két PIC: egy 18f1320 belső 8 MHz oszcival, valamint egy 18f4620 külső 10 MHz kvarccal. A probléma, amit sehogy sem tudok megoldani, hogy a "kicsi" PIC egy bájtot átküldjön a "nagy" PIC-nek soros kommunikációval. Ami miatt nem boldogulok, az az, hogy a két PIC-nek csak két lába van összekötve. Próbáltam "RX,TX lábként" használni kölcsönösen felcserélve ezt a két vezetéket, de nem tudtam a kommunikációt szinkronizálni. Ha valaki tudna segíteni megköszönöm.
|
Bejelentkezés
Hirdetés |