mikrocontroller.net

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


Autor: Adonai (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
}
--------------

Autor: Adonai (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann es sein, dass ich beim Empfangsprogramm etwas vergessen habe zu 
initialisieren?

Autor: Adonai (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Hier die aktuellste Version mit Kommentaren versehen:
//Empfangen
#include <P18F252.h>          //Bibliothek einbinden
int ring;                //Variable definieren
void open_serial(void);          //Definition der Unterprogramme
void initINT (void);          //Definition der Unterprogramme
void InterruptHandler (void);      //Definition der Unterprogramme
void InterruptVektor (void);      //Definition der Unterprogramme
#pragma code InterruptVektor = 0x08    //Vektor für hohe Priorität
#pragma code
#pragma interrupt InterruptHandler

void main (void) 
{
ADCON1 = 7;                //PORTA digital
LATA = 0x00;              
TRISA = 0x00;              //PORTA als Ausgang
TRISB = 0x00;              //PORTB als Ausgang
ring = 0;
RCREG = 90;                //Anfangswert RCREG
open_serial();              //USART-Modul konfigurieren
initINT();                //Interrupts konfigurieren
  while(1)
  {
  PORTB = 0xFF;            //PORTB auf High setzen
  }
}

void open_serial()
{
  SPBRG = 103;            //Baud-Rate
  TXSTAbits.BRGH = 0;         //Baud-Rate
  TXSTAbits.SYNC = 0;          //Asynchrone Übertragung
  TRISCbits.TRISC6 = 0;         //RB6 als Ausgang
  TRISCbits.TRISC7 = 1;         //RB7 als Ausgang 
  RCSTAbits.SPEN = 1;         //Seriellen Port aktivieren 
  TXSTAbits.TX9 = 0;           //8-Bit Sendung
  RCSTAbits.RX9 = 0;           //8-Bit Empfang
  RCSTAbits.CREN = 1;         //Empfänger aktivieren
  TXSTAbits.TXEN = 0;         //Sender deaktivieren
  PIR1bits.PSPIF = 0;          //Laut Datenblatt zu löschen
  PIE1bits.PSPIE = 0;          //Laut Datenblatt zu löschen
  IPR1bits.PSPIP = 0;          //Laut Datenblatt zu löschen
  RCSTAbits.FERR = 0;          //Laut Datenblatt zu löschen
  RCSTAbits.OERR = 0;          //Laut Datenblatt zu löschen
}

void initINT()
{
PIE1bits.TXIE = 0;             //Sende-Interrupt deaktivieren
PIE1bits.RCIE = 1;             //Empfangs-Interrupt aktivieren
INTCONbits.GIE = 1;           //Globale Interrupt-Freigabe
INTCONbits.PEIE = 1;          //Periphere Interupts freigeben
RCONbits.IPEN = 1;            //High-Priority Interrupts freigeben
INTCONbits.GIEH = 1;          //High-Priority Interrupts freigeben
IPR1bits.RCIP = 1;            //Empfangs-Interrupt erhält hohe Priorität
}

void InterruptHandler()          //Interrupt-Service-Routine
{
INTCONbits.GIE = 0;           //Interrupts deaktivieren
PORTB = 0x00;              //PORTB löschen (zeigt dass Interrupt ausgelöst wird)
PORTA = RCREG;              //Empfnags-Buffer auslesen
PIR1bits.RCIF = 0;            //Flag des Empfangs-Interrupt löschen
INTCONbits.GIE = 1;           //Interrupts wieder aktivieren
}

void InterruptVektor (void)        //Interrupt-Vektor festlegen
{
_asm
  goto InterruptHandler
 _endasm
}

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.