MSP430 - UART empfängt keine Zeichen

OP #1262926
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":
1
//******************************************************************************
2
//   MSP430x24x Demo - USCI_A0, 115200 UART Echo ISR, DCO SMCLK
3
//
4
//   Description: Echo a received character, RX ISR used. Normal mode is LPM0.
5
//   USCI_A0 RX interrupt triggers TX Echo.
6
//   Baud rate divider with 1MHz = 1MHz/115200 = ~8.7
7
//   UCBRx = 08; In UCA0MCTL: UCBRSx = round(0.7*8) = 05
8
//   ACLK = n/a, MCLK = SMCLK = CALxxx_1MHZ = 1MHz
9
//
10
//                MSP430F249
11
//             -----------------
12
//         /|\|              XIN|-
13
//          | |                 |
14
//          --|RST          XOUT|-
15
//            |                 |
16
//            |     P3.4/UCA0TXD|------------>
17
//            |                 | 115200 - 8N1
18
//            |     P3.5/UCA0RXD|<------------
19
//
20
//  B. Nisarga
21
//  Texas Instruments Inc.
22
//  September 2007
23
//  Built with CCE Version: 3.2.0 and IAR Embedded Workbench Version: 3.42A
24
//******************************************************************************
25
#include "msp430x24x.h"
26

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

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

48
// Echo back RXed character, confirm TX buffer is ready first
49
#pragma vector=USCIAB0RX_VECTOR
50
__interrupt void USCI0RX_ISR(void)
51
{
52
  while (!(IFG2&UCA0TXIFG));                // USCI_A0 TX buffer ready?
53
  UCA0TXBUF = UCA0RXBUF;                    // TX -> RXed character
54
}
#1263058
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.
1
while (!(IFG2&UCA0TXIFG));

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

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

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

25

26

27
#pragma vector=USCIAB0RX_VECTOR
28
__interrupt void USCI0RX_ISR(void)
29
{
30
  tmp = UCA0RXBUF;                    // save RXed character
31
}
#1263236
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ß.
Gast #1263433
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?
Gast #1263593
Lesenswert?

Die neuen werden ab Werk bei versch. Frequenzen kalibriert und die 
entspr. Kalibrierwerte im INFO_A abgelegt. Deshalb ja auch:
1
if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF)                                     
2
  {  
3
    while(1);                               // If calibration constants erased
4
                                            // do not load, trap CPU!!
5
  }   
6
  BCSCTL1 = CALBC1_1MHZ;                    // Set DCO
7
  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.
OP #1263898
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.
Gast #1264005
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)

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