mnpumar 2 Posted July 8, 2012 Share Posted July 8, 2012 I'd like to control an MSP430G2231 connected to my PC using the launchpad. After doing a little research, it looks like UART may be what I need. I found some code examples from TI, but I don't really understand how they work. What I'd like to do is send a signal from my PC to the MSP430 which would tell it to enable/disable certain pins. Here is the code i found, would anybody mind explaining how to use it? What is the difference between these two UART code samples? How do I send/receive on my PC? Do I need some sort of terminal? Can someone please explain? //****************************************************************************** // MSP430G2xx1 Demo - Timer_A, Ultra-Low Pwr UART 2400 Echo, 32kHz ACLK // // Description: Use Timer_A CCR0 hardware output modes and SCCI data latch // to implement UART function @ 2400 baud. Software does not directly read and // write to RX and TX pins, instead proper use of output modes and SCCI data // latch are demonstrated. Use of these hardware features eliminates ISR // latency effects as hardware insures that output and input bit latching and // timing are perfectly synchronised with Timer_A regardless of other // software activity. In the Mainloop the UART function readies the UART to // receive one character and waits in LPM3 with all activity interrupt driven. // After a character has been received, the UART receive function forces exit // from LPM3 in the Mainloop which echo's back the received character. // ACLK = TACLK = LFXT1 = 32768Hz, MCLK = SMCLK = default DCO // //* An external watch crystal is required on XIN XOUT for ACLK *// // // MSP430G2xx1 // ----------------- // /|\| XIN|- // | | | 32kHz // --|RST XOUT|- // | | // | CCI0B/TXD/P1.5|--------> // | | 2400 8N1 // | CCI0A/RXD/P1.1|<-------- // #define RXD 0x02 // RXD on P1.1 #define TXD 0x20 // TXD on P1.5 // Conditions for 2400 Baud SW UART, ACLK = 32768 #define Bitime_5 0x06 // ~ 0.5 bit length + small adjustment #define Bitime 0x0E // 427us bit length ~ 2341 baud unsigned int RXTXData; unsigned char BitCnt; void TX_Byte (void); void RX_Ready (void); // D. Dang // Texas Instruments Inc. // October 2010 // Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10 //****************************************************************************** #include void main (void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer CCTL0 = OUT; // TXD Idle as Mark TACTL = TASSEL_1 + MC_2; // ACLK, continuous mode P1SEL = TXD + RXD; // P1DIR = TXD; // // Mainloop for (; { RX_Ready(); // UART ready to RX one Byte _BIS_SR(LPM3_bits + GIE); // Enter LPM3 w/ interr until char RXed TX_Byte(); // TX Back RXed Byte Received } } // Function Transmits Character from RXTXData Buffer void TX_Byte (void) { BitCnt = 0xA; // Load Bit counter, 8data + ST/SP while (CCR0 != TAR) // Prevent async capture CCR0 = TAR; // Current state of TA counter CCR0 += Bitime; // Some time till first bit RXTXData |= 0x100; // Add mark stop bit to RXTXData RXTXData = RXTXData << 1; // Add space start bit CCTL0 = CCIS0 + OUTMOD0 + CCIE; // TXD = mark = idle while ( CCTL0 & CCIE ); // Wait for TX completion } // Function Readies UART to Receive Character into RXTXData Buffer void RX_Ready (void) { BitCnt = 0x8; // Load Bit counter CCTL0 = SCS + OUTMOD0 + CM1 + CAP + CCIE; // Sync, Neg Edge, Cap } // Timer A0 interrupt service routine #pragma vector=TIMERA0_VECTOR __interrupt void Timer_A (void) { CCR0 += Bitime; // Add Offset to CCR0 // TX if (CCTL0 & CCIS0) // TX on CCI0B? { if ( BitCnt == 0) CCTL0 &= ~ CCIE; // All bits TXed, disable interrupt else { CCTL0 |= OUTMOD2; // TX Space if (RXTXData & 0x01) CCTL0 &= ~ OUTMOD2; // TX Mark RXTXData = RXTXData >> 1; BitCnt --; } } // RX else { if( CCTL0 & CAP ) // Capture mode = start bit edge { CCTL0 &= ~ CAP; // Switch from capture to compare mode CCR0 += Bitime_5; } else { RXTXData = RXTXData >> 1; if (CCTL0 & SCCI) // Get bit waiting in receive latch RXTXData |= 0x80; BitCnt --; // All bits RXed? if ( BitCnt == 0) //>>>>>>>>>> Decode of Received Byte Here <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< { CCTL0 &= ~ CCIE; // All bits RXed, disable interrupt _BIC_SR_IRQ(LPM3_bits); // Clear LPM3 bits from 0(SR) } //>>>>>>>>>> Decode of Received Byte Here <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< } } } //****************************************************************************** // MSP430G2xx1 Demo - Timer_A, Ultra-Low Pwr UART 9600 Echo, 32kHz ACLK // // Description: Use Timer_A CCR0 hardware output modes and SCCI data latch // to implement UART function @ 9600 baud. Software does not directly read and // write to RX and TX pins, instead proper use of output modes and SCCI data // latch are demonstrated. Use of these hardware features eliminates ISR // latency effects as hardware insures that output and input bit latching and // timing are perfectly synchronised with Timer_A regardless of other // software activity. In the Mainloop the UART function readies the UART to // receive one character and waits in LPM3 with all activity interrupt driven. // After a character has been received, the UART receive function forces exit // from LPM3 in the Mainloop which configures the port pins (P1 & P2) based // on the value of the received byte (i.e., if BIT0 is set, turn on P1.0). // ACLK = TACLK = LFXT1 = 32768Hz, MCLK = SMCLK = default DCO // //* An external watch crystal is required on XIN XOUT for ACLK *// // // MSP430G2xx1 // ----------------- // /|\| XIN|- // | | | 32kHz // --|RST XOUT|- // | | // | CCI0B/TXD/P1.1|--------> // | | 9600 8N1 // | CCI0A/RXD/P1.2|<-------- // // D. Dang // Texas Instruments Inc. // October 2010 // Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10 //****************************************************************************** #include "msp430g2231.h" //------------------------------------------------------------------------------ // Hardware-related definitions //------------------------------------------------------------------------------ #define UART_TXD 0x02 // TXD on P1.1 (Timer0_A.OUT0) #define UART_RXD 0x04 // RXD on P1.2 (Timer0_A.CCI1A) //------------------------------------------------------------------------------ // Conditions for 9600 Baud SW UART, SMCLK = 1MHz //------------------------------------------------------------------------------ #define UART_TBIT_DIV_2 (1000000 / (9600 * 2)) #define UART_TBIT (1000000 / 9600) //------------------------------------------------------------------------------ // Global variables used for full-duplex UART communication //------------------------------------------------------------------------------ unsigned int txData; // UART internal variable for TX unsigned char rxBuffer; // Received UART character //------------------------------------------------------------------------------ // Function prototypes //------------------------------------------------------------------------------ void TimerA_UART_init(void); void TimerA_UART_tx(unsigned char byte); void TimerA_UART_print(char *string); //------------------------------------------------------------------------------ // main() //------------------------------------------------------------------------------ void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer DCOCTL = 0x00; // Set DCOCLK to 1MHz BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; P1OUT = 0x00; // Initialize all GPIO P1SEL = UART_TXD + UART_RXD; // Timer function for TXD/RXD pins P1DIR = 0xFF & ~UART_RXD; // Set all pins but RXD to output P2OUT = 0x00; P2SEL = 0x00; P2DIR = 0xFF; __enable_interrupt(); TimerA_UART_init(); // Start Timer_A UART TimerA_UART_print("G2xx1 TimerA UART\r\n"); TimerA_UART_print("READY.\r\n"); for (; { // Wait for incoming character __bis_SR_register(LPM0_bits); // Update board outputs according to received byte if (rxBuffer & 0x01) P1OUT |= 0x01; else P1OUT &= ~0x01; // P1.0 if (rxBuffer & 0x02) P1OUT |= 0x08; else P1OUT &= ~0x08; // P1.3 if (rxBuffer & 0x04) P1OUT |= 0x10; else P1OUT &= ~0x10; // P1.4 if (rxBuffer & 0x08) P1OUT |= 0x20; else P1OUT &= ~0x20; // P1.5 if (rxBuffer & 0x10) P1OUT |= 0x40; else P1OUT &= ~0x40; // P1.6 if (rxBuffer & 0x20) P1OUT |= 0x80; else P1OUT &= ~0x80; // P1.7 if (rxBuffer & 0x40) P2OUT |= 0x40; else P2OUT &= ~0x40; // P2.6 if (rxBuffer & 0x80) P2OUT |= 0x80; else P2OUT &= ~0x80; // P2.7 // Echo received character TimerA_UART_tx(rxBuffer); } } //------------------------------------------------------------------------------ // Function configures Timer_A for full-duplex UART operation //------------------------------------------------------------------------------ void TimerA_UART_init(void) { TACCTL0 = OUT; // Set TXD Idle as Mark = '1' TACCTL1 = SCS + CM1 + CAP + CCIE; // Sync, Neg Edge, Capture, Int TACTL = TASSEL_2 + MC_2; // SMCLK, start in continuous mode } //------------------------------------------------------------------------------ // Outputs one byte using the Timer_A UART //------------------------------------------------------------------------------ void TimerA_UART_tx(unsigned char byte) { while (TACCTL0 & CCIE); // Ensure last char got TX'd TACCR0 = TAR; // Current state of TA counter TACCR0 += UART_TBIT; // One bit time till first bit TACCTL0 = OUTMOD0 + CCIE; // Set TXD on EQU0, Int txData = byte; // Load global variable txData |= 0x100; // Add mark stop bit to TXData txData <<= 1; // Add space start bit } //------------------------------------------------------------------------------ // Prints a string over using the Timer_A UART //------------------------------------------------------------------------------ void TimerA_UART_print(char *string) { while (*string) { TimerA_UART_tx(*string++); } } //------------------------------------------------------------------------------ // Timer_A UART - Transmit Interrupt Handler //------------------------------------------------------------------------------ #pragma vector = TIMERA0_VECTOR __interrupt void Timer_A0_ISR(void) { static unsigned char txBitCnt = 10; TACCR0 += UART_TBIT; // Add Offset to CCRx if (txBitCnt == 0) { // All bits TXed? TACCTL0 &= ~CCIE; // All bits TXed, disable interrupt txBitCnt = 10; // Re-load bit counter } else { if (txData & 0x01) { TACCTL0 &= ~OUTMOD2; // TX Mark '1' } else { TACCTL0 |= OUTMOD2; // TX Space '0' } txData >>= 1; txBitCnt--; } } //------------------------------------------------------------------------------ // Timer_A UART - Receive Interrupt Handler //------------------------------------------------------------------------------ #pragma vector = TIMERA1_VECTOR __interrupt void Timer_A1_ISR(void) { static unsigned char rxBitCnt = 8; static unsigned char rxData = 0; switch (__even_in_range(TAIV, TAIV_TAIFG)) { // Use calculated branching case TAIV_TACCR1: // TACCR1 CCIFG - UART RX TACCR1 += UART_TBIT; // Add Offset to CCRx if (TACCTL1 & CAP) { // Capture mode = start bit edge TACCTL1 &= ~CAP; // Switch capture to compare mode TACCR1 += UART_TBIT_DIV_2; // Point CCRx to middle of D0 } else { rxData >>= 1; if (TACCTL1 & SCCI) { // Get bit waiting in receive latch rxData |= 0x80; } rxBitCnt--; if (rxBitCnt == 0) { // All bits RXed? rxBuffer = rxData; // Store in global variable rxBitCnt = 8; // Re-load bit counter TACCTL1 |= CAP; // Switch compare to capture mode __bic_SR_register_on_exit(LPM0_bits); // Clear LPM0 bits from 0(SR) } } break; } } //------------------------------------------------------------------------------ Quote Link to post Share on other sites
MishoOo 3 Posted July 8, 2012 Share Posted July 8, 2012 Here is the modified code that i used to controll 2 H-Bridges with the launchpad: //****************************************************************************** // MSP430G2xx2 Demo - Timer_A, Ultra-Low Pwr UART 9600 Echo, 32kHz ACLK // // Description: Use Timer_A CCR0 hardware output modes and SCCI data latch // to implement UART function @ 9600 baud. Software does not directly read and // write to RX and TX pins, instead proper use of output modes and SCCI data // latch are demonstrated. Use of these hardware features eliminates ISR // latency effects as hardware insures that output and input bit latching and // timing are perfectly synchronised with Timer_A regardless of other // software activity. In the Mainloop the UART function readies the UART to // receive one character and waits in LPM3 with all activity interrupt driven. // After a character has been received, the UART receive function forces exit // from LPM3 in the Mainloop which configures the port pins (P1 & P2) based // on the value of the received byte (i.e., if BIT0 is set, turn on P1.0). // ACLK = TACLK = LFXT1 = 32768Hz, MCLK = SMCLK = default DCO // //* An external watch crystal is required on XIN XOUT for ACLK *// // // MSP430G2xx2 // ----------------- // /|\| XIN|- // | | | 32kHz // --|RST XOUT|- // | | // | CCI0B/TXD/P1.1|--------> // | | 9600 8N1 // | CCI0A/RXD/P1.2|<-------- // // D. Dang // Texas Instruments Inc. // December 2010 // Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10 //****************************************************************************** #include "msp430g2452.h" //------------------------------------------------------------------------------ // Hardware-related definitions //------------------------------------------------------------------------------ #define UART_TXD 0x02 // TXD on P1.1 (Timer0_A.OUT0) #define UART_RXD 0x04 // RXD on P1.2 (Timer0_A.CCI1A) //------------------------------------------------------------------------------ // H-Bridge Transistors Definitions //------------------------------------------------------------------------------ #define LEFT BIT3 //P2.3 #define RIGHT BIT4 //P2.4 #define BCK BIT5 //P2.5 #define FWD BIT6 //P1.6 //------------------------------------------------------------------------------ // Conditions for 9600 Baud SW UART, SMCLK = 1MHz //------------------------------------------------------------------------------ #define UART_TBIT_DIV_2 (1000000 / (9600 * 2)) #define UART_TBIT (1000000 / 9600) //------------------------------------------------------------------------------ // Global variables used for full-duplex UART communication //------------------------------------------------------------------------------ unsigned int txData; // UART internal variable for TX unsigned char rxBuffer; // Received UART character //------------------------------------------------------------------------------ // Function prototypes //------------------------------------------------------------------------------ void TimerA_UART_init(void); void TimerA_UART_tx(unsigned char byte); void TimerA_UART_print(char *string); //------------------------------------------------------------------------------ // main() //------------------------------------------------------------------------------ volatile unsigned int flagFWD=0, flagBACK=0; void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer DCOCTL = 0x00; // Set DCOCLK to 1MHz BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; P1OUT = 0x00; // Initialize all GPIO P1SEL = UART_TXD + UART_RXD; // Timer function for TXD/RXD pins P1DIR = 0xFF & ~UART_RXD; // Set all pins but RXD to output P2OUT = 0x00; P2SEL = 0x00; P2DIR = 0xFF; __enable_interrupt(); TimerA_UART_init(); // Start Timer_A UART TimerA_UART_print("Mihai Tautu FILS - 2012\r\n"); TimerA_UART_print("Verbindung erstellt\r\n"); for (; { // Wait for incoming character __bis_SR_register(LPM0_bits); if(rxBuffer == 0x77) //w sent from keyboard { TimerA_UART_print("goForward\r\n"); P2OUT &= ~(BCK | LEFT | RIGHT); P1OUT |= FWD; flagFWD = 1; flagBACK = 0; } if(rxBuffer == 0x73) //s sent from keyboard { TimerA_UART_print("goBack\r\n"); P1OUT &= ~FWD; P2OUT &= ~(LEFT | RIGHT); P2OUT |= BCK; flagFWD = 0; flagBACK = 1; } if(rxBuffer == 0x61) //a sent from Keyboard { P2OUT &= ~RIGHT; P2OUT |= LEFT; if(flagFWD == 1) TimerA_UART_print("goForward+Left\r\n"); else if(flagBACK == 1) TimerA_UART_print("goBack+Left\r\n"); else TimerA_UART_print("goLeft\r\n"); } if(rxBuffer == 0x64) //d sent from Keyboard { P2OUT &= ~LEFT; P2OUT |= RIGHT; if(flagFWD == 1) TimerA_UART_print("goForward+Right\r\n"); else if(flagBACK == 1) TimerA_UART_print("goBack+Right\r\n"); else TimerA_UART_print("goRight\r\n"); } if(rxBuffer == 0x78) //x { TimerA_UART_print("STOP\r\n"); P1OUT &= ~FWD; P2OUT &= ~(RIGHT | BCK | LEFT); flagFWD = 0; flagBACK = 0; } // Echo received character //TimerA_UART_tx(rxBuffer); } } //------------------------------------------------------------------------------ // Function configures Timer_A for full-duplex UART operation //------------------------------------------------------------------------------ void TimerA_UART_init(void) { TACCTL0 = OUT; // Set TXD Idle as Mark = '1' TACCTL1 = SCS + CM1 + CAP + CCIE; // Sync, Neg Edge, Capture, Int TACTL = TASSEL_2 + MC_2; // SMCLK, start in continuous mode } //------------------------------------------------------------------------------ // Outputs one byte using the Timer_A UART //------------------------------------------------------------------------------ void TimerA_UART_tx(unsigned char byte) { while (TACCTL0 & CCIE); // Ensure last char got TX'd TACCR0 = TAR; // Current state of TA counter TACCR0 += UART_TBIT; // One bit time till first bit TACCTL0 = OUTMOD0 + CCIE; // Set TXD on EQU0, Int txData = byte; // Load global variable txData |= 0x100; // Add mark stop bit to TXData txData <<= 1; // Add space start bit } //------------------------------------------------------------------------------ // Prints a string over using the Timer_A UART //------------------------------------------------------------------------------ void TimerA_UART_print(char *string) { while (*string) { TimerA_UART_tx(*string++); } } //------------------------------------------------------------------------------ // Timer_A UART - Transmit Interrupt Handler //------------------------------------------------------------------------------ #pragma vector = TIMER0_A0_VECTOR __interrupt void Timer_A0_ISR(void) { static unsigned char txBitCnt = 10; TACCR0 += UART_TBIT; // Add Offset to CCRx if (txBitCnt == 0) { // All bits TXed? TACCTL0 &= ~CCIE; // All bits TXed, disable interrupt txBitCnt = 10; // Re-load bit counter } else { if (txData & 0x01) { TACCTL0 &= ~OUTMOD2; // TX Mark '1' } else { TACCTL0 |= OUTMOD2; // TX Space '0' } txData >>= 1; txBitCnt--; } } //------------------------------------------------------------------------------ // Timer_A UART - Receive Interrupt Handler //------------------------------------------------------------------------------ #pragma vector = TIMER0_A1_VECTOR __interrupt void Timer_A1_ISR(void) { static unsigned char rxBitCnt = 8; static unsigned char rxData = 0; switch (__even_in_range(TA0IV, TA0IV_TAIFG)) { // Use calculated branching case TA0IV_TACCR1: // TACCR1 CCIFG - UART RX TACCR1 += UART_TBIT; // Add Offset to CCRx if (TACCTL1 & CAP) { // Capture mode = start bit edge TACCTL1 &= ~CAP; // Switch capture to compare mode TACCR1 += UART_TBIT_DIV_2; // Point CCRx to middle of D0 } else { rxData >>= 1; if (TACCTL1 & SCCI) { // Get bit waiting in receive latch rxData |= 0x80; } rxBitCnt--; if (rxBitCnt == 0) { // All bits RXed? rxBuffer = rxData; // Store in global variable rxBitCnt = 8; // Re-load bit counter TACCTL1 |= CAP; // Switch compare to capture mode __bic_SR_register_on_exit(LPM0_bits); // Clear LPM0 bits from 0(SR) } } break; } } //------------------------------------------------------------------------------ You can compare my code with the standard TI Demo code and see what i have done to open PINs when specific characters are sent thru a Terminal Program I have attached u a Terminal programm. U will use that to communicate with your launchpad. You will have to select the COMM port on witch your launchpad is (check windows device manager for MSP430 UART COMM port). In the termianl program you have to select the proper baudrate. P.S I am using the msp430g2452 on my Launchpad. So you will have to change the "#include "msp430g2452.h" with something proper to your device. Terminal.rar mnpumar, bluehash and larsie 3 Quote Link to post Share on other sites
mnpumar 2 Posted July 8, 2012 Author Share Posted July 8, 2012 Thank you so much! I'm going to give this a try tomorrow and I'll let you know how it goes. Quote Link to post Share on other sites
RobG 1,892 Posted July 8, 2012 Share Posted July 8, 2012 Terminal app's page Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.