Forum: Mikrocontroller und Digitale Elektronik USART-Modul des PIC18F252 nutzen


von Adonai (Gast)


Lesenswert?

Hallo,

Ich versuche das USART-Modul des PIC18F252 anzusteuern. Ich programmiere 
mit C (MCC18 von Microchip).
Das Senden scheint zu funktioniren (gemessen mit dem KO).
Das Empfangen funktioniert aber nicht, denn der Interrupt wird nicht 
ausgelöst.

Sendeprogramm:
--------------
//Senden
#include <P18F252.h>
int ring;
void open_serial (void);
void InterruptHandler (void);
void wait (void);
#pragma code InterruptVektor = 0x08  //Vektor für hohe Priorität
void InterruptVektor (void)
{
 _asm
  goto InterruptHandler
 _endasm
}


#pragma code
#pragma interrupt InterruptHandler

void InterruptHandler()
{
  INTCONbits.GIE = 0;
    TXREG = ring;
    TXREG = TXREG & 0b00011111;
    PIR1bits.TXIF = 0;
  INTCONbits.GIE = 1;
}

void main (void)
{
ADCON1 = 7;
LATA = 0x00;
TRISA = 0x00;
TRISB = 0xFF;
ring = 0;
TXREG = 0;
open_serial();
  while(1)
  {
  ring = PORTB;
  PORTA = ring;
  }
}

void open_serial()
{
  // Configure UART serial transmit
        // Configured for:
  //  9600 Baud
  //  8N1

  // SPBRG - Baud Rate Generator Register
  SPBRG = 103; // 20MHz => 9600 baud (BRGH = 0)

  // BRGH - High Baud Rate Select Bit
  TXSTAbits.BRGH = 0; // (0 = low speed)

  // SYNC - USART Mode select Bit
  TXSTAbits.SYNC = 0; // (0 = asynchronous)

  // TRISC - Tri-state Data Direction Register for port C
  // RC6 - 6th pin of port C - used for Serial Transmit
  // RC7 - 7th pin of port C - used for Serial Receive
  TRISCbits.TRISC6 = 0; // (0 = pin set as output)
  TRISCbits.TRISC7 = 1; // (1 = pin set as input)

  // SPEN - Serial Port Enable Bit
  RCSTAbits.SPEN = 1; // (1 = serial port enabled)

  // TXIE - USART Transmit Interupt Enable Bit
  PIE1bits.TXIE = 1; // (1 = enabled)

  // RCIE - USART Receive Interupt Enable Bit
  PIE1bits.RCIE = 0; // (1 = enabled)

  // TX9 - 9-bit Transmit Enable Bit
  TXSTAbits.TX9 = 0; // (0 = 8-bit transmit)

  // RX9 - 9-bit Receive Enable Bit
  RCSTAbits.RX9 = 0; // (0 = 8-bit reception)

  // CREN - Continuous Receive Enable Bit
  RCSTAbits.CREN = 0; // (1 = Enables receiver)

  // TXEN - Trasmit Enable Bit
  TXSTAbits.TXEN = 1; // (1 = transmit enabled)

  // GIE - Global Interrupt Enable Bit
  INTCONbits.GIE = 1; // (1 = Enable all unmasked interrupts)

  // PEIE - Peripheral Interrupt Enable Bit
  INTCONbits.PEIE = 1; // (1 = Enable all unmasked peripheral 
interrupts)
  PIR1bits.PSPIF = 0;
  PIE1bits.PSPIE = 0;
  IPR1bits.PSPIP = 0;
}
--------------

Empfangsprogramm:
--------------
//Empfangen
#include <P18F252.h>
int ring;
void open_serial(void);
void InterruptHandler (void);
void InterruptVektor (void);
#pragma code InterruptVektor = 0x08  //Vektor für hohe Priorität
#pragma code
#pragma interrupt InterruptHandler

void main (void)
{
ADCON1 = 7;
LATA = 0x00;
TRISA = 0x00;
TRISB = 0x00;
ring = 0;
RCREG = 0;
open_serial();
  while(1)
  {
  PORTB = 0xFF;
  }
}

void open_serial()
{
  SPBRG = 103;
  TXSTAbits.BRGH = 0;
  TXSTAbits.SYNC = 0;
  TRISCbits.TRISC6 = 0;
  TRISCbits.TRISC7 = 1;
  RCSTAbits.SPEN = 1;
  PIE1bits.TXIE = 0;
  PIE1bits.RCIE = 1;
  TXSTAbits.TX9 = 0;
  RCSTAbits.RX9 = 0;
  RCSTAbits.CREN = 1;
  TXSTAbits.TXEN = 0;
  INTCONbits.GIE = 1;
  INTCONbits.PEIE = 0;
  PIR1bits.PSPIF = 0;
  PIE1bits.PSPIE = 0;
  IPR1bits.PSPIP = 0;
  IPR1bits.RCIP = 1;
  RCSTAbits.FERR = 0;
  RCSTAbits.OERR = 0;
}

void InterruptHandler()
{
INTCONbits.GIE = 0;
PORTB = 0x00;
PORTA = RCREG;
PIR1bits.RCIF = 0;
INTCONbits.GIE = 1;
}

void InterruptVektor (void)
{
_asm
  goto InterruptHandler
 _endasm
}
--------------

von Adonai (Gast)


Lesenswert?

Kann es sein, dass ich beim Empfangsprogramm etwas vergessen habe zu 
initialisieren?

von Adonai (Gast)


Lesenswert?

Hallo,

Hier die aktuellste Version mit Kommentaren versehen:
1
//Empfangen
2
#include <P18F252.h>          //Bibliothek einbinden
3
int ring;                //Variable definieren
4
void open_serial(void);          //Definition der Unterprogramme
5
void initINT (void);          //Definition der Unterprogramme
6
void InterruptHandler (void);      //Definition der Unterprogramme
7
void InterruptVektor (void);      //Definition der Unterprogramme
8
#pragma code InterruptVektor = 0x08    //Vektor für hohe Priorität
9
#pragma code
10
#pragma interrupt InterruptHandler
11
12
void main (void) 
13
{
14
ADCON1 = 7;                //PORTA digital
15
LATA = 0x00;              
16
TRISA = 0x00;              //PORTA als Ausgang
17
TRISB = 0x00;              //PORTB als Ausgang
18
ring = 0;
19
RCREG = 90;                //Anfangswert RCREG
20
open_serial();              //USART-Modul konfigurieren
21
initINT();                //Interrupts konfigurieren
22
  while(1)
23
  {
24
  PORTB = 0xFF;            //PORTB auf High setzen
25
  }
26
}
27
28
void open_serial()
29
{
30
  SPBRG = 103;            //Baud-Rate
31
  TXSTAbits.BRGH = 0;         //Baud-Rate
32
  TXSTAbits.SYNC = 0;          //Asynchrone Übertragung
33
  TRISCbits.TRISC6 = 0;         //RB6 als Ausgang
34
  TRISCbits.TRISC7 = 1;         //RB7 als Ausgang 
35
  RCSTAbits.SPEN = 1;         //Seriellen Port aktivieren 
36
  TXSTAbits.TX9 = 0;           //8-Bit Sendung
37
  RCSTAbits.RX9 = 0;           //8-Bit Empfang
38
  RCSTAbits.CREN = 1;         //Empfänger aktivieren
39
  TXSTAbits.TXEN = 0;         //Sender deaktivieren
40
  PIR1bits.PSPIF = 0;          //Laut Datenblatt zu löschen
41
  PIE1bits.PSPIE = 0;          //Laut Datenblatt zu löschen
42
  IPR1bits.PSPIP = 0;          //Laut Datenblatt zu löschen
43
  RCSTAbits.FERR = 0;          //Laut Datenblatt zu löschen
44
  RCSTAbits.OERR = 0;          //Laut Datenblatt zu löschen
45
}
46
47
void initINT()
48
{
49
PIE1bits.TXIE = 0;             //Sende-Interrupt deaktivieren
50
PIE1bits.RCIE = 1;             //Empfangs-Interrupt aktivieren
51
INTCONbits.GIE = 1;           //Globale Interrupt-Freigabe
52
INTCONbits.PEIE = 1;          //Periphere Interupts freigeben
53
RCONbits.IPEN = 1;            //High-Priority Interrupts freigeben
54
INTCONbits.GIEH = 1;          //High-Priority Interrupts freigeben
55
IPR1bits.RCIP = 1;            //Empfangs-Interrupt erhält hohe Priorität
56
}
57
58
void InterruptHandler()          //Interrupt-Service-Routine
59
{
60
INTCONbits.GIE = 0;           //Interrupts deaktivieren
61
PORTB = 0x00;              //PORTB löschen (zeigt dass Interrupt ausgelöst wird)
62
PORTA = RCREG;              //Empfnags-Buffer auslesen
63
PIR1bits.RCIF = 0;            //Flag des Empfangs-Interrupt löschen
64
INTCONbits.GIE = 1;           //Interrupts wieder aktivieren
65
}
66
67
void InterruptVektor (void)        //Interrupt-Vektor festlegen
68
{
69
_asm
70
  goto InterruptHandler
71
 _endasm
72
}

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.