mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik MSP430 UART RX Interrupt- und Empfangsfehler


Autor: Megabyte (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo µC-Gemeinde,
ich habe beim MSP430F1611 das Problem, dass der Interrupt beim Empfangen 
mit UART nur ausgelöst wird, wenn ich mehr als ein Zeichen sende, also 
nur bei zwei oder mehr.
Auch werden die Zeichen nicht richtig empfangen (z. B. wenn ich ein 
(also zwei) 'a' sende kommt am µC im RXBUF0 0xa7 (§) raus)

Ich habe die Hardware für ein Schulprojekt gestellt bekommen. Es wurden 
ein 8MHz- und ein 32768Hz-Quarz verbaut und ich hoffe richtig verbunden 
(laut Schaltplan: ja)

hier die Initialisierung von der UART
void initSerial () {
  // UART Reset für Konfiguration
  U0CTL |= 0x01;
  // P3.5 als Input
  P3DIR &= ~(0x20);
  // P3.4 als Output
  P3DIR |= 0x10;
  // Alternativ-Funktion von P3.5 + 4 auswählen (UART)
  P3SEL |= 0x20 | 0x10;
  // 8-MHz-Quarz aktivieren (X2)
  BCSCTL1 &= ~(0x80);
  // 8-MHz-Quarz als Quelle für SMCLK auswählen
  BCSCTL2 |= 0x08;
  // SMCLK auf 1 MHz runterteilen
  BCSCTL2 |= 0x40 | 0x20;
  // keine Parität
  U0CTL &= ~(0x80);
  // ein Stoppbit
  U0CTL &= ~(0x20);
  // 8-Bit-Daten
  U0CTL |= 0x10;
  // kein Listen-Mode
  U0CTL &= ~(0x08);
  // UART-Mode auswählen
  U0CTL &= ~(0x04);
  // kein Mulitprozessor-Mode
  U0CTL &= ~(0x02);
  // SMCLK als UCLK auswählen
  U0TCTL |= 0x20;
  U0TCTL &= ~(0x10);
  
//  // Baudrate: 115200 mit SMCLK (8 MHz)
//  UBR10 = 0x00;
//  UBR00 = 0x45;
//  UMCTL0 = 0xaa;

//  // Baudrate: 28800 mit SMCLK (8 MHz)
//  UBR10 = 0x01;
//  UBR00 = 0x15;
//  UMCTL0 = 0xbb;

  // Baudrate: 28800 mit SMCLK (1 MHz)
  UBR10 = 0x00;
  UBR00 = 0x45;
  UMCTL0 = 0xaa;

  // Senden aktivieren
  ME1 |= 0x80;
  // Empfangen aktivieren
  ME1 |= 0x40;
  // UART Reset zurücksetzen
  U0CTL &= ~(0x01);
  // UART RX Interrupt aktivieren
  IE1 |= 0x40;
}

und die ISR
#pragma vector = USART0RX_VECTOR
__interrupt void ser0int () {
  while (!(IFG1 & UTXIFG0));                // USART0 TX buffer ready?
  TXBUF0 = RXBUF0;                          // RXBUF0 to TXBUF0
}

in der main-Funktion werden alle Interrupts zugelassen (und sobald zwei 
Zeichen gesendet bzw. empfangen werden springt der Controller ja auch in 
die ISR)

Ach noch nebenbei, das Senden funktioniert einwandfrei (also µC -> PC).

Bitte um schnelle Hilfe!!
Gruss Michael

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>>// Baudrate: 28800 mit SMCLK (1 MHz)
  UBR10 = 0x00;
  UBR00 = 0x45;
  UMCTL0 = 0xaa;
Wenn ich mal die Modulation ausser Acht lasse, komme ich hier auf 14,4k 
und nicht 28,8k

Autor: Megabyte (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, sind 14400! Hab mir die Baudrate neu berechnen lassen, aber 
vergessen den Kommentar zu aktualisieren.

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du musst auf jeden Fall nach Aktivieren des XT2 ein Delay einfügen und 
prüfen, ob das Fault-Flag weg ist. Das dauert einige Zeit, bis der Quarz 
fertig angeschwungen hat. Eventuell kommt die UART Logik durcheinander, 
wenn der noch nicht ganz fertig ist....

Autor: MartinH (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nur so nebenbei. Hast du am Anfang den Watchdog deaktiviert?
->  WDTCTL = WDTPW + WDTHOLD;             // halte watchdog an

Ansonsten würde ich auch sagen, erstmal warten bis der Quarz 
eingeschwungen ist.

Dann nochmal die Register gegenchecken, ob du wirklich SMCLK = MCLK / 8
gesetzt hast.

Autor: MartinH (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zum Debuggen ist es auch immer recht hilfreich wenn man direkt die Namen 
der einzelnen Bits benutzt, und nicht die Hex-Zahlen selbst:
Probier mal folgendes:
ME1 |= UTXE0 + URXE0;    // USART0 einschalten (TX- und RX-teil)
UCTL0 |= CHAR;           // 8 data bits, 1 stop bit, no parity (8N1)
UTCTL0 |= SSEL1;         // SMCLK als UCLK festlegen
UBR00 = 0xA0;            // 19200 baud aus 8 MHz erzeugen
UBR10 = 0x01;            // siehe application note tabelle 1, seite 9
UMCTL0 = 0x00;           // keine korrektur der division noetig
UCTL0 &= ~SWRST;         // USART freigeben
IE1 |= URXIE0;           // RX-interrupt anschalten
IFG1 &= ~UTXIFG0;  // initales interrupt-flag loeschen

Vorher SMCLK ohne Vorteiler von MCLK ableiten, und die Pins wie gehabt 
einstellen.  Evtl liegt es auch nur darann, dass das initiale Int-Flag 
bei dir nicht gelöscht wird.

Autor: Megabyte (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wird gelöscht! Mach ich schon in der Init!
void init () {
  // 8-MHz-Quarz aktivieren (X2)
  BCSCTL1 &= ~(0x80);

  // OSC-Fault-Flag zurücksetzen
  do {
    IFG1 &= ~(0x02);
    for (unsigned char i = 0xff; i > 0; i --);
  } while (IFG1 & 0x02);

  // 8-MHz-Quarz als Quelle für MCLK auswählen
  BCSCTL2 |= 0x80; // X2 als Quelle für MCLK
}

Autor: Megabyte (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, bitte einfach vergessen.
Die SCH... Hardware macht mein schönes RS232-Signal zunichte!
ohne HW +6V -6V
mit HW  +4V -1V

da kann nix gehen

Trotzdem vielen Dank für die schnellen und guten Antworten und für die 
verbratenen Gehirnzellen.

LG Michael

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.