Fórum témák

» Több friss téma
Fórum » RS232 Interrupt PIC16F628
 
Témaindító: Rikfic, idő: Aug 9, 2007
Témakörök:
Lapozás: OK   1 / 3
(#) Rikfic hozzászólása Aug 9, 2007 /
 
Ü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!
(#) Topi válasza Rikfic hozzászólására (») Aug 9, 2007 /
 
CCS-re:
  1. //Fejrészben:
  2. #use rs232(baud=19200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=pc)
  3.  
  4. //Majd az interrupt:
  5. //============================================================
  6. #int_RDA
  7. void RDA_isr() {
  8. //============================================================
  9. int data;
  10.   data = getc(pc);
  11. }
  12.  
  13. //Mainben pedig:
  14.         enable_interrupts(INT_RDA);
  15.         enable_interrupts(GLOBAL);
(#) pokot válasza Rikfic hozzászólására (») Aug 9, 2007 /
 
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...
(#) Topi válasza pokot hozzászólására (») Aug 9, 2007 /
 
RETFIE utasítással, de csakis a work és status visszatöltése után.
(#) Rikfic válasza Topi hozzászólására (») Aug 9, 2007 /
 
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!
(#) Rikfic hozzászólása Aug 9, 2007 /
 
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?
(#) Topi válasza Rikfic hozzászólására (») Aug 9, 2007 /
 
Nem hajtod végre a megszakításnál elengedhetetlen lépéseket: Bővebben: Link
(#) Rikfic válasza Topi hozzászólására (») Aug 9, 2007 /
 
É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
(#) MPi-c válasza Rikfic hozzászólására (») Aug 9, 2007 /
 
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.
(#) Rikfic válasza MPi-c hozzászólására (») Aug 9, 2007 /
 
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...
(#) pokot válasza Rikfic hozzászólására (») Aug 9, 2007 /
 
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...
(#) Rikfic válasza pokot hozzászólására (») Aug 9, 2007 /
 
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!
(#) Topi válasza Rikfic hozzászólására (») Aug 9, 2007 /
 
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.
(#) Rikfic válasza Topi hozzászólására (») Aug 9, 2007 /
 
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.
(#) Topi válasza Rikfic hozzászólására (») Aug 9, 2007 /
 
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.
(#) Rikfic hozzászólása Aug 9, 2007 / 4
 
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!
(#) Topi válasza Rikfic hozzászólására (») Aug 9, 2007 /
 
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
(#) Rikfic hozzászólása Aug 9, 2007 /
 
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... )
(#) Topi válasza Rikfic hozzászólására (») Aug 9, 2007 /
 
Szívesen segítettünk, senki sem pákával vagy billentyűzettel az altájában született
(#) zsotya hozzászólása Okt 1, 2007 /
 
Ü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!
(#) Topi válasza zsotya hozzászólására (») Okt 1, 2007 /
 
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);"
(#) zsotya válasza Topi hozzászólására (») Okt 1, 2007 /
 
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?
(#) zsotya hozzászólása Okt 8, 2007 /
 
Ü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?
(#) zsotya válasza zsotya hozzászólására (») Okt 8, 2007 /
 
Amikor feltettem a kérdést, rá 3 percre eszembe jutott, hogy mi lenne ha kikapcsolnám a Brown Out Reset -et!
Nos kikapcsoltam, s így működik!
(#) potyo válasza zsotya hozzászólására (») Okt 8, 2007 /
 
Viszont ez nem megoldás, hogy kikapcsoltad a BOR-t. Inkább a picek tápjának szűrését kellene rendbehozni.
(#) zsotya válasza potyo hozzászólására (») Okt 8, 2007 /
 
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?
(#) potyo válasza zsotya hozzászólására (») Okt 8, 2007 /
 
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.
(#) Rikfic hozzászólása Okt 9, 2007 /
 
Hmm.. Nagyon szuper! Szívesen adnék neked 50 pontot! Remélem az egyik moderátor elolvassa, és ad neked
(#) Moderátor hozzászólása Rikfic hozzászólására (») Okt 9, 2007
 
Olvasom, de nem követem
Kinek is kell itt pont?
(#) Gruebber hozzászólása Jan 3, 2008 /
 
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.
Következő: »»   1 / 3
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