Jump to content
43oh

Recommended Posts

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;
   }
}
//------------------------------------------------------------------------------

Link to post
Share on other sites

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

post-32602-135135556537_thumb.png

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...