Forum: Mikrocontroller und Digitale Elektronik MSP430 UART0 RX-ISR


von Andreas D. (galdo)


Lesenswert?

Hallo,

hat vielleicht von euch jemand eine Ahnung wie der Interrupt-Vektor zum 
UART0RX Interrupt in der Code Composer Essentials IDE lautet?

So funktionierts leider nicht:
1
__interrupt void usart0_rx (void);
2
USART0RX_ISR(usart0_rx)
3
__interrupt void usart0_rx (void)

Leider geben die TI-Beispiele keine weiteren Aufschlüsse...

Danke GALDO

von Christian R. (supachris)


Lesenswert?

Dann hast du irgendwo was falsch eingestellt, oder eine falsche 
Header-Datei drin. Die Beispiele von TI funktionieren definitv. Das UART 
Beispiel hab ich selber schon mit CCE kompiliert.
Arbeite aber nur noch mit GCC; deswegen kann ich´s jetzt nicht 
nachvollziehen.

von Andreas D. (galdo)


Lesenswert?

Ich habe die MSP430xG46x.h eingebunden. In der ist der USART0RX_ISR 
nicht definiert. Ich verwende stattdessen:
1
__interrupt void USART0_RX(void);
2
USCIAB0RX_ISR(USART0_RX)
3
__interrupt void USART0_RX(void)
Das war im UART-Bereich des Headerfiles definiert. Bin mir nicht sicher, 
dass das funktioniert - aber zumindest compiliert es mal :)

Ich verwende übrigends ein MSP430FG4618-Experimeters Board...

Galdo

von Christian R. (supachris)


Lesenswert?

Achso, naja, die neuen haben ja diese USI statt der alten USART drin, da 
musst du mal in den entsprechenden Code-Beipsielen schauen. Ich hatte 
den F1611, da wäre USART0RX richtig.

von Andreas D. (galdo)


Lesenswert?

Hallo,

ich habe nochmal eine Frage: Irgendwas schein mit dieser Zeile nicht zu 
stimmen:
1
interrupt (USCIRX_VECTOR) USART0_RX_ISR(void) {

Auf jeden Fall kommt der Code nicht in den Interrupt rein, obwohl ich 
Sachen tatsächlich über RS232 empfange. Wie man auch sieht, habe ich den 
code auf den freien MSPGCC umgestellt, um der Restriktion in der 
Codegröße zu umgehen.

Hat jemand eine Idee, wie ich den Eintritt in die ISR bewerkstelligen 
kann?

Vielen Dank
Galdo

von Christian R. (supachris)


Lesenswert?

Naja, hast du denn das GIE Bit gesetzt, also globale Interrupts 
freigegeben? Das RX-Int Flag für die USCI auch gesetzt?
Hast du die signal.h includiert?

von Andreas D. (galdo)


Lesenswert?

1
#include <signal.h>

in der main steht folgendes:
1
     _BIS_SR(LPM3_bits + GIE);               // Enter LPM3 w/ interrupts enabled

und in der initUART dies hier:
1
void init_usart() {
2
  //---------------------------------------------------------
3
  // init the 1st usart interface (usart0).
4
  // 9600 Baud with 8N1 is used for communication.
5
  //---------------------------------------------------------
6
  P2SEL     |=   0x30;                  // Activate RX / TX
7
  P4SEL     |= 0x0C0;                        // P4.7,6 UART option select
8
9
  IE2     |=   UCA0RXIE + URXIE1;      // enable Interrupt
10
11
  //Configure UART-Device
12
  UCA0CTL1   |=   UCSSEL_1;                // CLK = ACLK
13
  UCA0BR0   =   0x03;                    // 32k/9600 - 3.41
14
  UCA0BR1   =   0x00;                    //
15
  
16
  UCA0MCTL   =   0x06;                     // Modulation
17
  UCA0CTL1   &=   ~UCSWRST;                // **Initialize USCI state machine**  
18
}

von Andreas D. (galdo)


Lesenswert?

Ziel ist es, permanent per ISR den ADC abzustasten und die Werte dann in 
der Main über uart zu verschicken.
Es sollen aber auch quasi "gleichzeitig" über UART eintreffende Werte 
als CMDs verarbeitet werden. Die Auswertung der Eingaben erfolgt 
ebenfalls im main-loop.

Die ISR ist nur dazu da, ein Flag zu setzen und ein empfangenes Zeichen 
in ein Char-Array einzufügen.

Bei Bedarf, kann ich auch mal den kompletten Code anhängen. Hab ich 
vielleicht einen Denkfehler? Geht das so garnicht? Gibt es einen 
konflikt mit dem permanenten Senden (was in der Main passiert)?

Danke für eure Informationen
GALDO

von Christian R. (supachris)


Lesenswert?

Sollte eigentlich gehen. Es sei denn, du liegst mit der Baudrate 
daneben. Trotz Modulator ist es manchmal schwierig, die passende zu 
treffen, gerade bei so kleinen Teilerfaktoren. Dein ACLK passt aber? Und 
läuft auch im LMP3 weiter, ja?

von Andreas D. (galdo)


Angehängte Dateien:

Lesenswert?

Naja - ich kann auf 9600 mit 8N1 auf dem PC was empfangen, also sollte 
doch ansich auch das senden gehen.

Ich verstehs leider auch net ganz und hab dir mal den komplette c-code 
angehängt.

Víelleicht hast du ja noch ne Idee, oder vielleicht "beißt" sich der ISR 
mit irgendwas anderem... Bin leider net so versiert was den MSP betrifft 
und arbeite das erste mal damit.

Wie kann ich denn das mit dem LMP3 überprüfen?

Danke GALDO

von Christian R. (supachris)


Lesenswert?

Hm, komisch, auf die Schnelle sehe ich jetzt keinen groben Fehler. Für 
verschachtelte Interrupts musst du zu Beginn der ISR, die unterbrochen 
werden darf, den GIE wieder freigeben. Vielleicht liegt da der Hund 
verbuddelt

von Andreas D. (galdo)


Lesenswert?

Sorry, die blöde Frage, aber das geht wie?
1
_BIC_SR_IRQ(LPM3_bits + GIE);

am Anfang der ISR?

Oder als Alternative: wie kann ich einstellen, dass ISRs nicht 
unterbrochen werden dürfen? Weiß zwar noch nicht genau, ob ich das haben 
will, wär aber mal gut zu wissen :D

Danke GALDO

von Christian R. (supachris)


Lesenswert?

Naja, standardmäßig wird zum Beginn der ISR das GIE Bit gelöscht. So 
sind ISRs erst mal nicht unterbrechbar.

Willst du Interrupts verschachteln, musst du den GIE freigeben, das geht 
genz einfach mit:

_EINT();

Willst du eine bestimmte Stelle "schützen" also nicht unterbrechbar 
machen, dann einfach:

_DINT();

von Andreas D. (galdo)


Lesenswert?

So war das gemeint ;)

Naja, bringt leider alles nix - irgendwas funktioniert da nicht. Die ISR 
wird leider immer noch nicht angesprungen :(

Und eigentlich ist es ja so gedacht, dass alle ISR komplett durchlaufen 
werden. Bin meines Erachtens eigentlich lang genug in main um keine 
Eingaben zu verpassen :) - oder habe ich bereits an dieser Stelle einen 
Denkfehler?

Trotzdem vielen Dank für alle bisherigen Antworten. Vielleicht hast du 
ja spontan noch nen Geistesblitz - ich hab leider keinen mehr...

Galdo

von Andreas D. (galdo)


Lesenswert?

Hat denn keiner mehr ne Idee?

Senden kann ich mit der eingestellten Konfiguration, nur es wird kein 
Interrupt ausgelößt, wenn ich was an das Device schicke.

Es soll eine Kommunikation mit 9600 Baud und 8N1 aufgebaut werden, 
vielleicht ist da irgendwas falsch eingestellt, was ich nicht ganz 
verstehe. Wie gesagt das Senden vom MSP-Board klappt auch und 
hyperterminal ist auf 9600 8N1 eingestellt und empfängt das ganze 
Zeusch.

Aus den Codes werde ich leider auch nicht ganz schlau, und in den 
Demo-Codes fürs DEV-Board ist leider nicht so ein Beispiel drin :(

Wär schön, wenn sich noch ein MSP-Profi den Code mal ansehen könnte und 
vielleicht dem Fehler auf die schliche kommt.

Es wird eigentlich "permanent" was versendet - vielleicht liegts ja 
daran...

Danke GALDO

von Christian R. (supachris)


Lesenswert?

Probier doch erst mal die UART-Empfangsfunktion ohne die anderen Sachen 
alle aus. Vielleicht klappt da ja schon was nicht. Ansonsten schätze 
ich, dass du ständig in einer ISR bist, und dadurch kein anderer 
Interrupt ausgelöst werden kann.

von Andreas D. (galdo)


Lesenswert?

Geht leider auch nicht :(

Also irgendwie muss was an der Einstellung falsch sein. Wie gesagt TX 
funktioniert, allerdings nicht RX - hyperterm verweigert schon die 
Eingabe von zeichen, wie als müsste man dem Programm mitteilen, dass das 
Gerät empfangsbereit wäre.

hier noch mal der Init-Code:
1
void init_usart() {
2
  //---------------------------------------------------------
3
  // init the 1st usart interface (usart0).
4
  // 9600 Baud with 8N1 is used for communication.
5
  //---------------------------------------------------------
6
7
  P2SEL     |= 0x30;                  // Activate RX / TX
8
  IE2     |= UCA0RXIE;          // enable Interrupt
9
10
  //Configure UART-Device
11
  UCA0CTL1   |=   UCSSEL_1;                // CLK = ACLK
12
  UCA0BR0   =   0x03;                    // 32k/9600 - 3.41
13
  UCA0BR1   =   0x00;                    //
14
  
15
  UCA0MCTL   =   0x06;                     // Modulation
16
  UCA0CTL1   &=   ~UCSWRST;                // **Initialize USCI state machine**
17
}

Hat irgendjemand vielleicht noch ne Idee verzweifel_mode_on

Danke GALDO

von Andreas D. (galdo)


Lesenswert?

Wat ein blöder fehler - ich habs gefunden... danke an alle!!!
1
UCA0CTL1   &=   ~UCSWRST;
resettet sämtliche vorher getroffenen Einstellungen, daher sind auch 
alle Kommunikationseinstellungen flöten...

Einfach an den Anfang der INIT, und das Problem ist gelöst!

Danke nochmals :D

GALDO

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.