Forum: Compiler & IDEs MSP430 MDB 9600NRZ 11BITS


von Stefan W. (Firma: CHEOPS Elektronik KG) (sweidinger)


Lesenswert?

Hallo Leute, so ich hab da mal n Problem.

Ich würde gerne mit dem MSP430F149 MDB Daten einlesen und die dann auf 
die seriele Schnittstelle ausgeben.
Soweit bin ich bisher:
************************************************************************ 
****
#include  <msp430x14x.h>

#define DELTA 256                           // target DCO = DELTA*(4096) 
= 1048576

unsigned int Compare, Oldcapture;

void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT

  P3SEL |= 0xC0;                            // P3.6,7 = USART1 TXD/RXD
  ME2 |= UTXE1 + URXE1;                     // Enable USART1 TXD/RXD
  UCTL1 |= CHAR;                            // 8-bit character
  UTCTL1 |= SSEL0;                          // UCLK = ACLK
  UBR01 = 0x03;                             // 32k/9600 - 3.41
  UBR11 = 0x00;                             //
  UMCTL1 = 0x4A;                            // Modulation
  UCTL1 &= ~SWRST;                          // Initialize USART state 
machine
  IE2 |= URXIE1;                            // Enable USART1 RX 
interrupt

  P3SEL |= 0x30;                            // P3.6,7 = USART1 TXD/RXD
  ME1 |= UTXE0 + URXE0;                     // Enable USART0 TXD/RXD
  UCTL0 |= CHAR;                            // 8-bit character
  UTCTL0 |= SSEL0;                          // UCLK = ACLK
  UBR00 = 0x03;                             // 32k/9600 - 3.41
  UBR10 = 0x00;                             //
  UMCTL0 = 0x4A;                            // Modulation
  UCTL0 &= ~SWRST;                          // Initialize USART state 
machine
  IE1 |= URXIE0;

  CCTL2 = CM_1 + CCIS_1 + CAP + CCIE;       // CAP, ACLK, interrupt
  TACTL = TASSEL_2 + MC_2 + TACLR;          // SMCLK, cont-mode, clear

  _BIS_SR(LPM3_bits + GIE);                 // Enter LPM3 w/ interrupt
}

#pragma vector=USART0RX_VECTOR
__interrupt void usart0_rx (void)
{
  //while (!(IFG1 & UTXIFG0));                // USART0 TX buffer ready?
  TXBUF1 = RXBUF0;                          // RXBUF0 to TXBUF0
}

************************************************************************ 
**
Mir ist schon klar, dass das nicht so funktionieren kann, da der MDB ja 
11Bit.
Ich glaube man kann sowas mit einer Soft-UART lösen. Allerdings bin ich 
absoluter Neuling in Sachen C und in Sachen MSP430.... ;-)

Jaja, ich weis, ich sollte mir für den Anfang leiber was leichteres 
Suchen.. ;-)

Wäre super nett, wenn mich da irgendwer unterstützen könnte...

von Stefan (Gast)


Lesenswert?

>Mir ist schon klar, dass das nicht so funktionieren kann, da der MDB ja
>11Bit.
Ja und?
Eine UART mit Start - 8Daten - Parity - Stop hat auch 11bit!

>Ich glaube man kann sowas mit einer Soft-UART lösen. Allerdings bin ich
>absoluter Neuling in Sachen C und in Sachen MSP430.... ;-)
Software-UART geht sicher. Dazu gibt's genug Tutorials im Netz

Ich glaube aber, dass es auch mit der Hardware-UART funktioniert:
Der einzige Unterschied zwischen UART und MDB-Protokoll ist ja das 
Parity bzw. Mode-bit. Wenn Du nun Deine UART mit Parity konfigurierst, 
musst Du nur das Parity Error-Flag auswerten und mit dem Datenbyte 
vergleichen. Somit müsste sich herausfinden lassen, ob das Mode-bit 
(bzw. Parity-bit bei UART) '0' oder '1' war.

Wenn der MSP430 was senden soll, könntest Du dann die UART-Parität 
zwischen 'even' und 'odd' wechseln, um je nach Datenbyte ein Mode-bit 
von '0' oder '1' zu erzielen!

von Peter D. (peda)


Lesenswert?

Stefan wrote:

> Ich glaube aber, dass es auch mit der Hardware-UART funktioniert:
> Der einzige Unterschied zwischen UART und MDB-Protokoll ist ja das
> Parity bzw. Mode-bit.

Hat der MSP430 denn keinen 9-Bit Modus?
Die AVR und 8051 haben den jedenfalls.


> Wenn der MSP430 was senden soll, könntest Du dann die UART-Parität
> zwischen 'even' und 'odd' wechseln, um je nach Datenbyte ein Mode-bit
> von '0' oder '1' zu erzielen!

Das ist tricky.
Dann darf kein Sendepuffer benutzt werden.
Und Empfangen geht dabei garnicht.


Peter

von Christian R. (supachris)


Lesenswert?

Der MSp430 kann in Hardware nur 7 und 8 Bit. Aber die Software-UART ist 
mit dem Timer so einfach zu machen, gerade bei 9600 Baud kein Thema. Da 
gibts sogar eine AppNote von TI, die muss halt dann nur etwas angepasst 
werden.

von Stefan (Gast)


Lesenswert?

Ne Software AppNote von TI? Ja? Wo? Ich find keine....???

von Christian R. (supachris)


Lesenswert?

Da bei Code-Examples zu finden: 
http://focus.ti.com/general/docs/techdocsabstract.tsp?abstractName=slaa307a 
ist aber in ASM geschrieben mit Header-Datei für C.
Da hab ich aber auch mal die komplette C-Variante gesehen. Müsste ich 
nochmal suchen. ich hab zumindest in einem Projekt bei mir eine 57600 
Baud Software-UART mit dem F1611 drin.

von Stefan W. (Firma: CHEOPS Elektronik KG) (sweidinger)


Lesenswert?

Das wär natührlich besser wenn es sowas in C geschrieben gibt.
Weil Assembler kenn ich mich nun doch überhaupt nich aus...^^

von Stefan (Gast)


Lesenswert?

In der Zeit, in der hier AppNotes gesucht werden, hättest Du die 
"Parity-Methode" mit HW-UART schon längst programmiert ;-)

von Stefan W. (Firma: CHEOPS Elektronik KG) (sweidinger)


Lesenswert?

Bist du dir sicher, ob das mit dem Parity funzt? Weil er gibt ja nur 
zurück, ob des Paryti Bit stimmt, oder falsch ist...??? Steht zumindest 
so im Datenblatt?? ;-)

von Stefan (Gast)


Lesenswert?

Wenn Du Dein empfangenes Datenbyte kennst und zudem weisst, ob ein 
Parity-Error aufgetreten ist oder nicht, dann kannst Du Dir auch 
ausrechenen, ob's '0' oder '1' war!

von Christian R. (supachris)


Lesenswert?

Die C-Variante (6MHz Quarz, 57600 Baud)
1
#define Bitime_5  27                      // ~ 0.5 bit length + small adjustment
2
#define Bitime    52 
3
4
unsigned int RXTXData;
5
unsigned char BitCnt;
6
7
volatile unsigned int TAR_Value;
8
9
// Function Transmits Character from RXTXData Buffer
10
11
void TX_Byte (void)
12
{
13
  BitCnt = 0xA;                             // Load Bit counter, 8data + ST/SP
14
  CCR0 = TAR;                               // Current state of TA counter
15
  CCR0 += Bitime;                           // Some time till first bit
16
  RXTXData |= 0x100;                        // Add mark stop bit to RXTXData
17
  RXTXData = RXTXData << 1;                 // Add space start bit
18
  CCTL0 = OUTMOD0 + CCIE;                   // TXD = mark = idle
19
  while ( CCTL0 & CCIE );                   // Wait for TX completion
20
}
21
22
// Function Readies UART to Receive Character into RXTXData Buffer
23
void RX_Ready (void)
24
{
25
  BitCnt = 0x8;                             // Load Bit counter
26
  //CCTL0 = SCS + CCIS0 + OUTMOD0 + CM1 + CAP + CCIE;   // Sync, Neg Edge, Cap
27
  CCTL0 = CCIS0 + OUTMOD0 + CM1 + CAP + CCIE;   // Sync, Neg Edge, Cap
28
}
29
30
interrupt (TIMERA0_VECTOR) Timer_A (void)
31
{
32
CCR0 += Bitime;                           // Add Offset to CCR0
33
34
// RX
35
  if (CCTL0 & CCIS0)                        // RX on CCI0B?
36
  {
37
    if( CCTL0 & CAP )                       // Capture mode = start bit edge
38
    {
39
    CCTL0 &= ~ CAP;                         // Switch from capture to compare mode
40
    CCR0 += Bitime_5;
41
    _BIC_SR_IRQ(SCG1 + SCG0);               // DCO remains on after reti
42
    }
43
    else
44
    {
45
    RXTXData = RXTXData >> 1;
46
      if (CCTL0 & SCCI)                     // Get bit waiting in receive latch
47
      RXTXData |= 0x80;
48
      BitCnt --;                            // All bits RXed?
49
      if ( BitCnt == 0)
50
//>>>>>>>>>> Decode of Received Byte Here <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
51
      {
52
        CCTL0 &= ~ CCIE;                      // All bits RXed, disable interrupt
53
    
54
            
55
      }
56
//>>>>>>>>>> Decode of Received Byte Here <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
57
    }
58
  }
59
// TX
60
  else
61
  {
62
    if ( BitCnt == 0)
63
    CCTL0 &= ~ CCIE;                        // All bits TXed, disable interrupt
64
    else
65
    {
66
      CCTL0 |=  OUTMOD2;                    // TX Space
67
      if (RXTXData & 0x01)
68
      CCTL0 &= ~ OUTMOD2;                   // TX Mark
69
      RXTXData = RXTXData >> 1;
70
      BitCnt --;
71
    }
72
  }
73
}
In der Initialisierung im Hauptprogramm muss noch folgendes rein:
1
CCTL0 = OUT;                              // TXD Idle as Mark
2
TACTL = TASSEL_2 + MC_2 + TACLR + ID_1;   // SMCLK, continuous mode

von Stefan W. (Firma: CHEOPS Elektronik KG) (sweidinger)


Lesenswert?

Ah, klasse. So, kann mir jetzt noch jemand helfen, wie ich des auf 
9600Baud und 7.372MHz umbastel? ;-)

von Stefan W. (Firma: CHEOPS Elektronik KG) (sweidinger)


Angehängte Dateien:

Lesenswert?

Hum, ich glaub ich hätte da mal n Problem....^^
(siehe Anhang)

#include <msp430x24x.h>  hab ich ganz oben reingeschrieben... ;-)

von Stefan (Gast)


Lesenswert?

1
#pragma vector = TIMERA0_VECTOR
2
__interrupt void Timer_A (void)

von Stefan W. (Firma: CHEOPS Elektronik KG) (sweidinger)


Lesenswert?

Hehe, zu spät, nu hab ich es auch schon. gg
Jetz muss ich es nur noch auf 9600Baud bei einem 7.372MHz Quarz 
umbasteln.
Und wo muss ich die Ports für die UART eintragen?
Und was fürn Befehl muss ich nu ausführen um den RXBUFFER auszugeben?

Ich weis, viele Fragen... ;-)

von Christian R. (supachris)


Lesenswert?

Naja, bissl denken musst du schon selber auch noch. Dafür wirst du ja 
sicherlich bezahlt, oder? Die Bitzeiten für deine Baudrate auszurechnen 
kann ja nicht so schwer sein. Die Ports sind fest, und zwar die vom 
Timer A, über die auch der BootstrapLoader läuft. P1.1 und 2.2 meistens. 
RXBUffer gibts keinen, das Ding ist nur Halbduplex, es gibt RXTXData, 
das gemeinsame Empfang/Sende-Byte.

von Stefan (Gast)


Lesenswert?

>In der Zeit, in der hier AppNotes gesucht werden, hättest Du die
>"Parity-Methode" mit HW-UART schon längst programmiert ;-)
... und mittlerweile schon zwei weitere Projekte fertiggestellt...
Einfach mal die Scheuklappen abnehmen und selber a' bisser'l denken!

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.