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...
>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!
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
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.
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.
Das wär natührlich besser wenn es sowas in C geschrieben gibt. Weil Assembler kenn ich mich nun doch überhaupt nich aus...^^
In der Zeit, in der hier AppNotes gesucht werden, hättest Du die "Parity-Methode" mit HW-UART schon längst programmiert ;-)
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?? ;-)
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!
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 |
Ah, klasse. So, kann mir jetzt noch jemand helfen, wie ich des auf 9600Baud und 7.372MHz umbastel? ;-)
Hum, ich glaub ich hätte da mal n Problem....^^ (siehe Anhang) #include <msp430x24x.h> hab ich ganz oben reingeschrieben... ;-)
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... ;-)
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.
>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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.