Forum: Mikrocontroller und Digitale Elektronik Startschwierigkeiten mit MSP430 [Launchpad]


von Fabian H. (Firma: Technische Universität Berlin) (brein)


Angehängte Dateien:

Lesenswert?

Hallo Leute,

seit geraumer Zeit habe ich das Launchpad von TI und auch ein wenig mit 
der Ein- und Ausgabe gespielt. Das funktioniert auch soweit.
Nun habe ich hier ein SerLCD von Sparkfun liegen welches im wesentlichen 
ein HD44780 ist, welches über SPI angesprochen werden kann.

Nun versuche ich es also über SPI anzusprechen und bin dabei über die 
MSP430 Codebeispiele gestolpert.

Irgendwie scheint der Code nicht zu stimmen:
1
void init_spi(void)
2
{
3
  ME1 |= USPIE0;                        // Enable USART0 SPI mode
4
  UTCTL0 = CKPH+SSEL1+SSEL0+STC;        // SMCLK, 3-pin mode
5
  UCTL0 = CHAR+SYNC+MM;                 // 8-bit SPI Master **SWRST**
6
  UBR00 = 0x02;                         // UCLK/2 
7
  UBR10 = 0x00;                         // 0
8
  UMCTL0 = 0x00;                        // no modulation
9
  P3SEL |= 0x0E;                        // P3.1-3 SPI option select
10
  P3DIR |= 0x01;                        // P3.0 output direction
11
  _EINT();                              // Enable interrupts
12
}
Alle Referenzen kennt meine IDE (Code Composer Studio 5) nicht.
Gut, dass der MSP430G2231 keinen dritten Port hat ist klar. Auf P1SEL 
und P1DIR geändert und das Problem ist schon mal gelöst.

Aber die Registerbezeichnungen für das USI sind der IDE gänzlich 
unbekannt.
Ein Blick in die <msp430g2231.h> zeigt:
1
/************************************************************
2
* USI
3
************************************************************/
4
#define __MSP430_HAS_USI__                    /* Definition to show that Module is available */
5
6
7
SFR_8BIT(USICTL0);                            /* USI  Control Register 0 */
8
SFR_8BIT(USICTL1);                            /* USI  Control Register 1 */
9
SFR_8BIT(USICKCTL);                           /* USI  Clock Control Register */
10
SFR_8BIT(USICNT);                             /* USI  Bit Counter Register */
11
SFR_8BIT(USISRL);                             /* USI  Low Byte Shift Register */
12
SFR_8BIT(USISRH);                             /* USI  High Byte Shift Register */
13
SFR_16BIT(USICTL);                            /* USI  Control Register */
14
SFR_16BIT(USICCTL);                           /* USI  Clock and Counter Control Register */
15
SFR_16BIT(USISR);                             /* USI  Shift Register */
16
17
18
#define USIPE7                 (0x80)         /* USI  Port Enable Px.7 */
19
#define USIPE6                 (0x40)         /* USI  Port Enable Px.6 */
20
#define USIPE5                 (0x20)         /* USI  Port Enable Px.5 */
21
#define USILSB                 (0x10)         /* USI  LSB first  1:LSB / 0:MSB */
22
#define USIMST                 (0x08)         /* USI  Master Select  0:Slave / 1:Master */
23
#define USIGE                  (0x04)         /* USI  General Output Enable Latch */
24
#define USIOE                  (0x02)         /* USI  Output Enable */
25
#define USISWRST               (0x01)         /* USI  Software Reset */
26
27
28
#define USICKPH                (0x80)         /* USI  Sync. Mode: Clock Phase */
29
#define USII2C                 (0x40)         /* USI  I2C Mode */
30
#define USISTTIE               (0x20)         /* USI  START Condition interrupt enable */
31
#define USIIE                  (0x10)         /* USI  Counter Interrupt enable */
32
#define USIAL                  (0x08)         /* USI  Arbitration Lost */
33
#define USISTP                 (0x04)         /* USI  STOP Condition received */
34
#define USISTTIFG              (0x02)         /* USI  START Condition interrupt Flag */
35
#define USIIFG                 (0x01)         /* USI  Counter Interrupt Flag */
36
37
38
#define USIDIV2                (0x80)         /* USI  Clock Divider 2 */
39
#define USIDIV1                (0x40)         /* USI  Clock Divider 1 */
40
#define USIDIV0                (0x20)         /* USI  Clock Divider 0 */
41
#define USISSEL2               (0x10)         /* USI  Clock Source Select 2 */
42
#define USISSEL1               (0x08)         /* USI  Clock Source Select 1 */
43
#define USISSEL0               (0x04)         /* USI  Clock Source Select 0 */
44
#define USICKPL                (0x02)         /* USI  Clock Polarity 0:Inactive=Low / 1:Inactive=High */
45
#define USISWCLK               (0x01)         /* USI  Software Clock */
46
47
48
#define USIDIV_0               (0x00)         /* USI  Clock Divider: 0 */
49
#define USIDIV_1               (0x20)         /* USI  Clock Divider: 1 */
50
#define USIDIV_2               (0x40)         /* USI  Clock Divider: 2 */
51
#define USIDIV_3               (0x60)         /* USI  Clock Divider: 3 */
52
#define USIDIV_4               (0x80)         /* USI  Clock Divider: 4 */
53
#define USIDIV_5               (0xA0)         /* USI  Clock Divider: 5 */
54
#define USIDIV_6               (0xC0)         /* USI  Clock Divider: 6 */
55
#define USIDIV_7               (0xE0)         /* USI  Clock Divider: 7 */
56
57
58
#define USISSEL_0              (0x00)         /* USI  Clock Source: 0 */
59
#define USISSEL_1              (0x04)         /* USI  Clock Source: 1 */
60
#define USISSEL_2              (0x08)         /* USI  Clock Source: 2 */
61
#define USISSEL_3              (0x0C)         /* USI  Clock Source: 3 */
62
#define USISSEL_4              (0x10)         /* USI  Clock Source: 4 */
63
#define USISSEL_5              (0x14)         /* USI  Clock Source: 5 */
64
#define USISSEL_6              (0x18)         /* USI  Clock Source: 6 */
65
#define USISSEL_7              (0x1C)         /* USI  Clock Source: 7 */
66
67
68
#define USISCLREL              (0x80)         /* USI  SCL Released */
69
#define USI16B                 (0x40)         /* USI  16 Bit Shift Register Enable */
70
#define USIIFGCC               (0x20)         /* USI  Interrupt Flag Clear Control */
71
#define USICNT4                (0x10)         /* USI  Bit Count 4 */
72
#define USICNT3                (0x08)         /* USI  Bit Count 3 */
73
#define USICNT2                (0x04)         /* USI  Bit Count 2 */
74
#define USICNT1                (0x02)         /* USI  Bit Count 1 */
75
#define USICNT0                (0x01)         /* USI  Bit Count 0 */
76
/************************************************************

Im User's Guide der MSPx2xx Familie 
http://www.ti.com/lit/ug/slau144i/slau144i.pdf (Ab Seite 511; Übersicht 
Seite 520;) lauten die Register wieder anders:
1
USART control register          U0CTL
2
Transmit control register       U0TCTL
3
Receive control register        U0RCTL
4
Modulation control register     U0MCTL
5
Baud rate control register 0    U0BR0
6
Baud rate control register 1    U0BR1
7
Receive buffer register         U0RXBUF
8
Transmit buffer register        U0TXBUF
9
SFR module enable register 1    ME1
10
SFR interrupt enable register 1 IE1
11
SFR interrupt flag register 1   IFG1
Im wesentlichen ist im Beispielcode die '0' für USART0 an das Ende der 
Referenz gerutscht.

Jetzt habe ich also zwei Fragen:
1. Wie lauten nun die richtigen Registernamen und wo erfahre ich das?
2. Wieso kennt der Header kein Sende- und Empfangsbuffer das Datenblatt 
aber schon (U0RXBUF)?

Ich habe sicher etwas gehörig missverstanden.
Könnt Ihr mir helfen?

Vielen Danken
Fabian

P.S.
Während ich den Post schrieb, fand ich folge nützliche Seiten:
http://processors.wiki.ti.com/index.php/MSP430_LaunchPad_(MSP-EXP430G2)#Download_all_MSP430G2xx_code_examples
http://processors.wiki.ti.com/index.php/MSP430_LaunchPad#Code_examples.2FSnippets
Da werde ich sicher fündig.
Dennoch sind meine Fragen weiterhin offen.

von Fabian H. (Firma: Technische Universität Berlin) (brein)


Lesenswert?

Ich sehe gerade, mir ist schon mal der erste Fehler unterlaufen.
Irgendwie habe ich "serial" auf SPI gemünzt, dabei scheint es wohl aber 
UART zu sein.

Ich denke aber, die von mir beschriebenen Probleme/Fragen sollten die 
gleichen sein.

Denn wenn ich mir so den Sample Code ansehe:
1
void InitUSART(char USART0, char USART1, unsigned int baudrate1, unsigned int baudrate2, char IR0, char IR1)
2
{
3
  if (USART0) ME1 |= UTXE0 + URXE0;    // falls gesetzt, USART0 einschalten (TX- und RX-teil)
4
  if (USART1) ME2 |= UTXE1 + URXE1;    // falls gesetzt, USART1 einschalten (TX- und RX-teil)
5
  UCTL0 |= CHAR;                       // 8 data bits, 1 stop bit, no parity (8N1)
6
  UCTL1 |= CHAR;
7
  UTCTL0 |= SSEL1;                     // SMCLK als UCLK festlegen
8
  UTCTL1 |= SSEL1;
9
  if (baudrate1==19200)
10
  {
11
    UBR00 = 0xA0;                      // 19200 baud aus 8 MHz erzeugen
12
    UBR10 = 0x01;                      // siehe application note tabelle 1, seite 9
13
    UMCTL0 = 0x00;                     // keine korrektur der division noetig
14
  }
15
  if (baudrate2==19200)
16
  {
17
    UBR01 = 0xA0;                      // 19200 baud aus 8 MHz erzeugen
18
    UBR11 = 0x01;                      // siehe application note tabelle 1, seite 9
19
    UMCTL1 = 0x00;                     // keine korrektur der division noetig
20
  }
21
  if (USART0) UCTL0 &= ~SWRST;         // USART freigeben
22
  if (USART1) UCTL1 &= ~SWRST;
23
  if (IR0==0) IE1 |= URXIE0;           // IR0: 0 -> nur RX-interrupt anschalten
24
  if (IR0==1) IE1 |= UTXIE0;           //      1 -> nur TX-interrupt anschalten
25
  if (IR0==2) IE1 |= URXIE0 + UTXIE0;  //      2 -> TX- und RX-interrupt anschalten
26
  if (IR1==1||IR1==2) IFG1 &= ~UTXIFG0;  // initales interrupt-flag loeschen
27
  if (IR1==0) IE2 |= URXIE1;           // IR1: 0 -> nur RX-interrupt anschalten
28
  if (IR1==1) IE2 |= UTXIE1;           //      1 -> nur TX-interrupt anschalten
29
  if (IR1==2) IE2 |= URXIE1 + UTXIE1;  //      2 -> TX- und RX-interrupt anschalten
30
  if (IR1==1||IR1==2) IFG1 &= ~UTXIFG1;  // initales interrupt-flag loeschen
31
 
32
}
kann ich zum Beispiel im Datenblatt weder UCTL0 noch UBR00 finden.
Zu mal ich zutun habe zu unterscheiden, welche davon Flags und welche 
davon Register sind.

Ich werde das heute Abend nochmal überprüfen.

Gruß
Fabian

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Du solltest Dir die Codebeispiele von TI besorgen, die sind auf die 
MSP430Gxx-Familie und die dort zu findende Peripherie ausgelegt.

Für 'G2x53 und 'G2x33 (Launchpad 1.5)
http://www.ti.com/litv/zip/slac485a

Für 'G2x01, 'G2x11, 'G2x21 und 'G2x31 (Launchpad < 1.5)
http://www.ti.com/litv/zip/slac463a

Was das Forum hier bietet, das ist nur für sehr alte MSP430-Varianten 
nutzbar.

von Max G. (l0wside) Benutzerseite


Lesenswert?

Das mit dem USART müsste schon passen, die von TI verwendeten Interfaces 
sprechen je nach Konfiguration eine ganze Reihe serielle Dialekte, 
darunter SPI.

Allerdings sind die Registerbezeichnungen zwischen den einzelnen 
MSP430-Unterfamilien nicht einheitlich. Den prinzipiellen Programmfluss 
kannst du vermutlich schon übernehmen, aber bei den 
Registerbezeichnungen wirst du die Family User´s Guides von MSP430G2231 
und dem im Codebeispiel verwendeten Derivat nebeneinanderlegen müssen 
und abgleichen.

Alternativ kannst du auch entweder die von Rufus verlinkten Beispiele 
nehmen oder es anhand des Family User´s Guide auch zu Fuß versuchen. Bei 
mir hat das auch geklappt, und dann versteht man auch besser, was man da 
anstellt.

Gruß,

Max

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Max G. schrieb:
> Das mit dem USART müsste schon passen

Das tut es nur, wenn die gleiche Peripherie vorliegt. Die USART aber 
der alten 'F16xx-Reihe hat mit der USCI der neueren Reihen nicht mehr 
gemein, als daß sie auch in irgendeinem MSP430 verwendet wird.

Daher sind die 
http://www.mikrocontroller.net/articles/MSP430_Codebeispiele mit 
Vorsicht zu genießen, zumal nicht explizit darauf eingegangen wird, 
welches Peripheriemodul genau genutzt wird.


Es ist daher sehr ratsam, sich auf die TI-Codebeispiele zu beziehen, die 
für die in den jeweils verwendeten Familienmitgliedern tatsächlich 
vorhandene Peripherie ausgelegt sind.

von Fabian H. (Firma: Technische Universität Berlin) (brein)


Lesenswert?

Danke erstmal.

An die Code-Beispiele hätte ich mich jetzt auch erstmal gewannt. Nur 
hatte ich nicht darauf geachtet auf die Version des Launchpads selber zu 
schauen.

Ich sehe gerade, dass meines der Rev. 1.4 ist.
Dabei ist es erst etwa ein halbes Jahr alt. (Die Lagerzeit nicht mit 
eingerechnet natürlich.)
Ich habe zu hause aber noch ein jüngeres rumliegen. Was also, wenn ich 
ein G2231 mit einem Launchpad 1.5 programmieren möchte? Auf was müsste 
ich da achten oder an welche Codes sollte ich mich da eher halten?

Irgendwie werde ich auch aus dem User's Guide nicht recht schlau. Habe 
so das Gefühl, wenn ich mich nur mit dem Guide hinsetzen würde, würde 
ich es nicht hinbekommen. Ich finde ja noch nicht einmal die im Code 
verwendeten Register (auf die Schnelle jetzt).

Also heute Abend nochmal in aller Ruhe ransetzen.

Danke soweit
Fabian

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Fabian Hoemcke schrieb:
> Was also, wenn ich
> ein G2231 mit einem Launchpad 1.5 programmieren möchte? Auf was müsste
> ich da achten oder an welche Codes sollte ich mich da eher halten?

Die Launchpadversionen erwähnte ich nur, um darauf hinzuweisen, daß mit 
den unterschiedlichen Versionen unterschiedliche Controller ausgeliefert 
werden. Entscheidend ist der Controller, den Du letzlich verwendest, 
nicht die Version des Launchpads.

Bei Dir also ein 'G2231, und damit http://www.ti.com/litv/zip/slac463a

von Fabian H. (Firma: Technische Universität Berlin) (brein)


Lesenswert?

Besten Dank!

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.