mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik MSP430 - UART empfängt keine Zeichen


Autor: Hans Wurst (hans_wurst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich verwende das Beispiel "msp430x24x_uscia0_uart_01_115k.c" von TI um 
die UART-Schnittstelle von meinem MSP430F247 zu erstellen.

Wenn ich zusätzlich noch eine Funktion erstelle um ein Zeichen zu 
versenden ,funktioniert das wunderbar. Das Empfangen von Zeichen 
funktioniert jedoch selbst bei unverändertem Beispielcode nicht. Der 
RX-Buffer scheint immer leer zu sein und ein Interrupt wird 
dementsprechend auch nie ausgelöst.
Hat jemand schon ein ähnliches Problem gehabt?

Hier mal der unveränderte Beispielcode vom 
"msp430x24x_uscia0_uart_01_115k.c":
//******************************************************************************
//   MSP430x24x Demo - USCI_A0, 115200 UART Echo ISR, DCO SMCLK
//
//   Description: Echo a received character, RX ISR used. Normal mode is LPM0.
//   USCI_A0 RX interrupt triggers TX Echo.
//   Baud rate divider with 1MHz = 1MHz/115200 = ~8.7
//   UCBRx = 08; In UCA0MCTL: UCBRSx = round(0.7*8) = 05
//   ACLK = n/a, MCLK = SMCLK = CALxxx_1MHZ = 1MHz
//
//                MSP430F249
//             -----------------
//         /|\|              XIN|-
//          | |                 |
//          --|RST          XOUT|-
//            |                 |
//            |     P3.4/UCA0TXD|------------>
//            |                 | 115200 - 8N1
//            |     P3.5/UCA0RXD|<------------
//
//  B. Nisarga
//  Texas Instruments Inc.
//  September 2007
//  Built with CCE Version: 3.2.0 and IAR Embedded Workbench Version: 3.42A
//******************************************************************************
#include "msp430x24x.h"

void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF)                                     
  {  
    while(1);                               // If calibration constants erased
                                            // do not load, trap CPU!!
  }   
  BCSCTL1 = CALBC1_1MHZ;                    // Set DCO
  DCOCTL = CALDCO_1MHZ;
  P3SEL = 0x30;                             // P3.4,5 = USCI_A0 TXD/RXD
  UCA0CTL1 |= UCSSEL_2;                     // SMCLK
  UCA0BR0 = 8;                              // 1MHz 115200
  UCA0BR1 = 0;                              // 1MHz 115200
  UCA0MCTL = UCBRS2 + UCBRS0;               // Modulation UCBRSx = 5
  UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
  IE2 |= UCA0RXIE;                          // Enable USCI_A0 RX interrupt

  __bis_SR_register(LPM0_bits + GIE);       // Enter LPM0, interrupts enabled
}

// Echo back RXed character, confirm TX buffer is ready first
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
  while (!(IFG2&UCA0TXIFG));                // USCI_A0 TX buffer ready?
  UCA0TXBUF = UCA0RXBUF;                    // TX -> RXed character
}

Autor: Benjamin S. (recycler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du empfängst ein Zeichen, schiebst es in das Sende register. Beim 2. 
Aufruf bzw. Empfang wartest du so lange, bis das Senden Abgeschlossen 
ist.
while (!(IFG2&UCA0TXIFG));

Und ab da hängt dein Kollege im Interrupt.
#include "msp430x24x.h"
char tmp;

void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF)                                     
  {  
    while(1);                               // If calibration constants erased
                                            // do not load, trap CPU!!
  }   
  BCSCTL1 = CALBC1_1MHZ;                    // Set DCO
  DCOCTL = CALDCO_1MHZ;
  P3SEL = 0x30;                             // P3.4,5 = USCI_A0 TXD/RXD
  UCA0CTL1 |= UCSSEL_2;                     // SMCLK
  UCA0BR0 = 8;                              // 1MHz 115200
  UCA0BR1 = 0;                              // 1MHz 115200
  UCA0MCTL = UCBRS2 + UCBRS0;               // Modulation UCBRSx = 5
  UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
  IE2 |= UCA0RXIE;                          // Enable USCI_A0 RX interrupt

  __bis_SR_register(LPM0_bits + GIE);       // Enter LPM0, interrupts enabled
}



#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
  tmp = UCA0RXBUF;                    // save RXed character
}


Autor: Hans Wurst (hans_wurst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die Antwort.
Mein Problem ist jedoch, dass er erst gar nicht in die ISR rein springt. 
Wenn ich dort einen Breakpoint setzte, wird er trotzdem nie erreicht.

Autor: Benjamin S. (recycler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich kenne den 247 nicht, aber hast du einen Uhrenquarz (32,768khz) dran. 
Sonst geht garnix. Jedenfalls bei den alten war das so, weil die die Clk 
für den DCO verwenden.

2. Fehlt nicht ein #include signal.h ???
Irgendwas musst für den Interrupt noch eingebunden werden, soweit ich 
dass noch weiß.

Autor: Jörg S. (joerg-s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Er sagt ja das er problemlos senden kann. Die Clocks sollten also 
passen.

Am Portpin kommt auch ganz sicher was an?

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ich kenne den 247 nicht, aber hast du einen Uhrenquarz (32,768khz) dran.
>Sonst geht garnix. Jedenfalls bei den alten war das so, weil die die Clk
>für den DCO verwenden.
Das ist ja grad das Tolle, dass man dann eben keinen Quarz braucht!

>2. Fehlt nicht ein #include signal.h ???
>Irgendwas musst für den Interrupt noch eingebunden werden, soweit ich
>dass noch weiß.
Nein, "msp430x24x.h" reicht!

Ist überhaupt der richtige RX-Pin beschaltet?

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OT:
@Jörg: kommst Du Dir verfolgt vor ? ;-))

Autor: Jörg S. (joerg-s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>@Jörg: kommst Du Dir verfolgt vor ? ;-))
Nö, geht noch ;)

Autor: Benjamin S. (recycler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Stefan und Jorg. Bei den alten Brauchte man einen zum abgleich, damit 
das stibil lief. Mit den neuen MSPs hab ich leider keine Erfahrung.
Ob das mit dem DCO so richtig hinhaut kann ich auch nicht sagen und ob 
es da nicht zu Jitter kommt.

Hast du sicher RX Pin 0 verwendet und nicht RX1?

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die neuen werden ab Werk bei versch. Frequenzen kalibriert und die 
entspr. Kalibrierwerte im INFO_A abgelegt. Deshalb ja auch:
if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF)                                     
  {  
    while(1);                               // If calibration constants erased
                                            // do not load, trap CPU!!
  }   
  BCSCTL1 = CALBC1_1MHZ;                    // Set DCO
  DCOCTL = CALDCO_1MHZ;

>Ob das mit dem DCO so richtig hinhaut kann ich auch nicht sagen und ob
>es da nicht zu Jitter kommt.
Das haut hin und der DCO ist erstaunlich genau.
Hab mal 'nen 2012 mit Fön und Kältespray malträtiert und keine mir 
messbare Abweichung feststellen können.

Autor: Benjamin S. (recycler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke, das ist sehr interessant. Habe mit dem 169er und einem noch 
älteren Modell gespielt, da wurde im Datenblatt hingewiesen, dass der 
DCO nicht zu ganau ist. Aber wie gesagt, das war damals.

Autor: Hans Wurst (hans_wurst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Benjamin S. schrieb:
> ...hast du einen Uhrenquarz (32,768khz) dran. Sonst geht garnix. Jedenfalls
> bei den alten war das so, weil die die Clk für den DCO verwenden.

Einen Uhrenquarz habe ich leider nicht. Wenn das wirklich so ist, dann 
kan ich wohl leider nicht empfangen.


> ...Fehlt nicht ein #include signal.h ??? Irgendwas musst für den
> Interrupt noch eingebunden werden, soweit ich dass noch weiß.

Das dieses Beispiel direkt von TI stammt und zum MSP dazugehört, gehe 
ich davon aus, dass der Code vollständig sein sollte.

Autor: Jörg S. (joerg-s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Einen Uhrenquarz habe ich leider nicht. Wenn das wirklich so ist, dann
>kan ich wohl leider nicht empfangen.
Wie schon gesagt: Wenn senden geht, ist der CLK OK!

Autor: Benjamin S. (recycler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das denk ich.
Verwende mal folgende ISR:
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
  char tmp;
  tmp = UCA0RXBUF;                    // save RXed character
}

und setzte den breakpoint auf tmp. Schau dann ob er reinspringt.

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wir wissen immer noch nicht, ob der richtige RX-Pin verwendet wird und 
ob an dem Pin überhaupt was ankommt.
Weitere Fehlerquellen:
Baudrate, Stopbits, Parity
Falls da irgendwas nicht stimmt, wird auch kein RX-IRQ ausgelöst, siehe 
User-Guide UCAxCTL1-Register, UCRXEIE-Bit (hier =0)

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nachtrag:
Dein Sender hat nicht zufällig Hardware-Handshake aktiviert und wartet 
vergebens auf Sendefreigabe?

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.