Forum: Mikrocontroller und Digitale Elektronik MSP430: UART empfängt nicht und erzeugt Fehler im Debugger


von Falk B. (falk)


Lesenswert?

Hallo Gemeinde,

ich habe ein Problem mit einem MSP430F123. Ich will den UART per Polling 
nutzen. Senden geht, auch Strings. Aber ich kann nix empfangen. Wenn ich 
einen Breakpoint auf die While-Schleife in getc() setzte, bis dorthin im 
Debugger laufe, ein Zeichen per HTERM an den MSP sende (mit 300 Baud!) 
und dann im Debugger auf F11 (Single Step) drücke kommt immer wieder 
"Failed to excute step". Der Cursor im Dissassebler springt zum Label 
?cstart_begin. Was kann das sein? Die Interrupts sind definitiv nicht 
aktiv. Der MSP läuft mit einem 3,6864MHz Quarz an Xin/Xout. Das ist auch 
OK, hab ich gemessen, und ausserdem kann ich senden und per HTERM 
empfangen. Nur nicht umgekehrt. Ärgerlich, an so ner Trivialität 
festzuhängen :-(
1
// get a char from UART
2
3
uint8_t getc(void) {
4
  uint8_t tmp;
5
  while (!(IFG2 & URXIFG0));                // USART0 RX data available?
6
  tmp = RXBUF0;
7
  return tmp;
8
}
9
10
// put a char to UART
11
12
void putc(uint8_t data) {
13
  while (!(IFG2 & UTXIFG0));                // USART0 TX buffer ready?
14
  TXBUF0 = data;
15
}
16
17
// put a string to UART
18
19
void puts(char *data) {
20
  char tmp;
21
  while (tmp=*data++) putc(tmp);                // write char to UART when not NULL
22
}
23
24
int main( void )
25
{
26
  uint8_t i;
27
  char string[]="Test ";
28
  
29
  // Stop watchdog timer to prevent time out reset
30
  WDTCTL = WDTPW + WDTHOLD;
31
32
  // Switch XO to high speed Xtal, use als MCLK, SMCLK and ACLK
33
  BCSCTL1 |= XTS;                           // ACLK = LFXT1 = HF XTAL
34
  do
35
  {
36
      IFG1 &= ~OFIFG;                       // Clear OSCFault flag
37
      for (i = 0xFF; i > 0; i--);           // Time for flag to set
38
  }
39
  while ((IFG1 & OFIFG));                   // OSCFault flag still set?
40
  BCSCTL2 |= SELM_3;                        // MCLK = LFXT1 (safe)
41
42
  
43
  // Configure IO
44
  P1DIR=0xFF;                               // unused
45
  P2DIR=0xFF;                               // P2.3 DATA_OUT, out
46
  P3DIR=0x9F;                               // P3.3 CLOCK_OUT, out
47
                                            // P3.4 TXD, UART, out
48
                                            // P3.5 RXD, UART, in
49
                                            // P3.6 DATA_IN, in
50
                                            // P3.7 DATA_DIR, out
51
  P2OUT = 0x08;                             // set clock_out high
52
53
  // Configure UART @ 115k2, no Interrupts; TODO
54
  UCTL0 |= SWRST;                          // Reset USART state machine  
55
  P3OUT |= 0x10;  
56
  P3SEL |= 0x30;                            // P3.4,5 = USART0 TXD/RXD  
57
  ME2 |= UTXE0 + URXE0;                     // Enabled USART0 TXD/RXD
58
  UCTL0 |= CHAR;                            // 8-bit character
59
  UTCTL0 |= SSEL0;                          // UCLK = ACLK
60
//  UBR00 = 0x20;                             // 115200 baud @ 3.6864 MHz
61
  UBR00 = 0x00;                             // 300 baud @ 3.6864 MHz
62
  UBR10 = 0x30;                             // 
63
  UMCTL0 = 0x00;                            // Modulation
64
  UCTL0 &= ~SWRST;                          // Initalize USART state machine
65
  
66
 // inc_reset();
67
68
  puts(string);
69
  while(1) {                                // endless main loop
70
//    putc('A');
71
//    puts(string);
72
//    _delay_us(10000);
73
    i=getc();
74
    putc(i);            // test
75
//    if (i=='P') cmd_p_large();
76
//    if (i=='p') cmd_p_small();
77
  }
78
79
}

MfG
Falk

von Christian R. (supachris)


Lesenswert?

Kein Wunder, die beiden Flags UTXIFG0 und URXIFG0 liegen ja auch im IFG1 
Register und nicht im IFG2. Dort liegen die für die 2. USART, falls 
vorhanden.

von Falk B. (falk)


Lesenswert?

@ Christian R. (supachris)

>Kein Wunder, die beiden Flags UTXIFG0 und URXIFG0 liegen ja auch im IFG1
>Register und nicht im IFG2. Dort liegen die für die 2. USART, falls
>vorhanden.

Nein, beim MSP430F12xx liegen die in IFG2. Siehe Datenblatt. Und Senden 
geht ja schliesslich auch ordentlich, ohne verschluckte Zeichen.

MfG
Falk

von Jörg S. (joerg-s)


Lesenswert?

> Wenn ich einen Breakpoint auf die While-Schleife in getc() setzte...
Dann setz den Braekpoint doch mal auf "tmp = RXBUF0;" Oder schau einfach 
erst mal nach (Mit dem Debugger) ob das gesendete Zeichen überhaupt im 
Empfangsregister landet.

von Christian R. (supachris)


Lesenswert?

Stimmt, mein Fehler. Dachte, der F123 gehört zur selben Gattung wie die 
14x und 16x usw. Wieder was gelernt.

Ansonsten kann ich sonst keinen Fehler sehen. Ist die Hardware definitiv 
in Ordnung? Mal das Echo-Beispiel mit dem Interrupt aus den Demos 
probiert? Evtl. steht im Errata Sheet auch was drinne?

von Falk B. (falk)


Lesenswert?

@  Jörg S. (joerg-s)

>Dann setz den Braekpoint doch mal auf "tmp = RXBUF0;" Oder schau einfach
>erst mal nach (Mit dem Debugger) ob das gesendete Zeichen überhaupt im
>Empfangsregister landet.

Das versuche ich ja. Aber der Prozessor stürzt scheinbar nach verlassen 
der While-Schleife ab!

@ Christian R. (supachris)

>Ansonsten kann ich sonst keinen Fehler sehen. Ist die Hardware definitiv
>in Ordnung?

Denke ich schon. Senden geht, ist sehe auch die RX Daten vom PC direkt 
am Pin sauber anliegen.

> Mal das Echo-Beispiel mit dem Interrupt aus den Demos
>probiert?

Nein. Aber mit Polling muss es doch erst recht klappen, das ist doch nun 
weiss Gott trivial.

> Evtl. steht im Errata Sheet auch was drinne?

Der gleiche Prozessor ist schon auf einer anderen Platine erfolgreich 
mit UART im Einsatz. Aber ich schau nochmal nach.

MfG
Falk

von Jörg S. (Gast)


Lesenswert?

> Das versuche ich ja. Aber der Prozessor stürzt scheinbar nach verlassen
> der While-Schleife ab!
Dan erst mal weg mit der while Schleife und dafür ne andere Testroutine 
Z.B.:
1
uint8_t getc(void) 
2
{
3
  unsigned char tmp[20];
4
  unsigned char i;
5
6
  i = 0;
7
8
  temp[i] = RXBUF0;
9
10
  while (1)
11
  {
12
    if (RXBUF0 != tmp[i]) tmp[++i] = RXBUF0;
13
    if (i == 10) break;  // Evt. hier Breakpoint
14
  }
15
16
  _NOP();   // Oder hier Breakpoint
17
}

von Falk B. (falk)


Lesenswert?

AHHHHHH!!!!!

Asche auf mein unwürdiges Haupt!

Ich hab in meinem Debugaufbau ein Kabel falsch angeklemmt. Statt an RX 
vom uC an VCC vom Programmieradapter, weil beide nebeneindander liegen 
und über Widerstände getrennt sind! Klar, das Startbit zieht mir dann 
VCC auf Masse (AUA!) und macht einen Reset vom Debugger.

MfG
Falk

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.