PIC16F877 - Interrupt auslösen bei Empfang eines Bytes

OP #1008826
Lesenswert?

Hallo,

ich laboriere im Moment an dem Interrupt meines PIC16F877 herum. Ziel 
ist es in die Interrupt-Routine zu springen, sobald die USART ein Byte 
empfängt. Leider funktioniert es so gar nicht.

Nachstehend der Code meines Testprogramms, im Hauptprogramm klickert 
mein Relais immer hin und her, sobald ich ein Byte an den PIC schicke 
sollte das Relais prompt ausgeschaltet werden (nicht sinnig, soll ja nur 
zum Testen sein).

Kann es sein, dass RB0 den Interrupt auslöst und nicht die USART? Wenn 
ja - wie kann man das ändern?

Gruß
Olaf



#include <C:\cc5\16F877.H>
#include <C:\cc5\int16CXX.H>

// 
Speicherschutz12,13,4,5=aus,Debug11=aus,ProgrammFlash9=an,EEpromRead8=an 
,
// NiedervoltProgr7=aus, NiederVoltReset6=an,EinschaltTimer3=an,
// WachDogTimer2=aus,Oszillator0,1=XC
#pragma config |= 0b.11.111101.11.00.10

//*******  Interrupt  *************************************************

#pragma origin 4

interrupt InterruptRuine(void)
{
int_save_registers
PORTA = 0b.0000.0000;
//PIR1bits.TXIF = 0;
int_restore_registers
}

//********************************************************************** 
********

void InitUSART()
{
    BRGH=1;
//    SPBRG=129;              // (9600 baud @ 20MHz input clock)
    SPBRG=20;              // Änderung!!! (57600 baud @ 20MHz input 
clock)

    SPEN = 1;               // Set_Serial_Pins;
    SYNC = 0;               // Set_Async_Mode;
    TX9 = 0;                // Set_8bit_Tx;
    RX9 = 0;                // Set_8bit_Rx;
    CREN = 1;               // Enable_Rx;
    TXEN = 1;               // Enable_Tx;
    RCIE=1;                 // Rx Interrupt ein!!!
}

//*******  Hauptprogramm 
*************************************************

void main(void)
{
    uns16 a;                // Variablen
    char n;
    char w;
    uns16 addr;
    uns16 test1;
    uns16 test2;

    TRISA = 0b.0000.0000;    // PortA als Ausgang definieren
    TRISB = 0b.0000.0000;    // PortB als Ausgang definieren
    TRISE = 0b.0000.0000;    // PortE als Ausgang definieren
    TRISD = 0b.0000.0000;

    PORTA = 0b.0000.0000;
    PORTB = 0;
    PORTE = 0;
    PORTD = 0b.0000.0000;

    TRISC=0b.1011.1100;     // RC6>TX, RC7>RX
    InitUSART();            // Hardwareschnittstelle des PICs einstellen

  while (1)
    {
    pause(500);
    pause(500);
    pause(500);
    pause(500);
    pause(500);
    pause(500);
      PORTA = 0b.1111.1111;
    pause(500);
    pause(500);
    pause(500);
    pause(500);
    pause(500);
    pause(500);
     PORTA = 0b.0000.0000;
    }
}
#1012195
Lesenswert?

Hallo Olaf,

um periphere Interrupts zuzulassen, müssen GIE und PEIE in INTCON 
gesetzt sein. Zusätzlich vorher das Enable-Bit des gewünschten Moduls 
(in deinem Fall RCIE) in einem der PIEx-Register setzen.

Des Weiteren macht einiges in deinem Code so keinen Sinn. Hinweis: 
Welches Ereignis soll eigentlich in der ISR behandelt werden - TX oder 
RC Interrupt?

Gruß,
Edson
OP #1014574
Lesenswert?

Hi Edson,

schönen Dank für deinen Tipp. PEIE hatte noch gefehlt, dewegen ist das 
Programm nicht in die Interrupt-Routine gesprungen. Leider springt es im 
Moment allerdings auch nicht mehr heraus, ich denke hier muss noch ein 
Flag per Software herausgenommen werden - da bin ich noch auf der Suche, 
bin aber guter Dinge - oder weißt du das auch?

Ich möchte den Interrupt nutzen um aus dem normalen Programm 
herauszuspringen, wenn ein Byte empfangen wird, es auszulesen, um dann 
wieder im normalen Programm weiterzumachen.

Gruß
Olaf
#1014878
Lesenswert?

gruser wrote:
>Leider springt es im
>Moment allerdings auch nicht mehr heraus, ich denke hier muss noch ein
>Flag per Software herausgenommen werden - da bin ich noch auf der Suche,
>bin aber guter Dinge - oder weißt du das auch?

Ja, das meinte ich mit dem Hinweis in meinem Beitrag. dds5 hat es dir im 
Detail verraten.

morph1 wrote:
>witzig, fragt man sich wofür ich das geschrieben hatte =)

Naja, wahrscheinlich konnte der gute Olaf deinen Tippfehler (PIE statt 
PEIE) mangels Erfahrung nicht selbst korrigieren.

Gruß,
Edson
OP #1015674
Lesenswert?

... hier sind nur Helden... dankeschön. Der doofe Olaf hats verstanden 
und es klappt sogar. Mir fällt nur auf dass die Variablen in der 
Interrupt-Routine neu definiert werden müssen - insofern kann ich nicht 
ohne weiteres Werte übergeben an mein normales Hauptprogramm. Tja - 
sicher wieder ein typischer Olaf - aber vielleicht helft ihr trotzdem 
noch einmal ;)
OP #1017808
Lesenswert?

Wenn man die Variablendeklaration unter #include... schreibt (und nicht 
in das Hauptprogramm "main") ist sie automatisch eine globale Variable.

Eine Sache ist mir noch aufgefallen, ich kann aus der Interrupt-Routine 
keine Funktion aufrufen. Gibt es da noch einen Trick?

Gruß
Olaf

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren