Jump to content

Hello World snippit from NJCs Uart lesson

Recommended Posts

MSP-EXP430G2 Launchpad Board - Chip is a G2231

This code will print 'Hello World !!' to your terminal each time you push the p1.3 button, the first push you might get some garbage till they sync.

Easy enough to fix however the button works 2 times and skips the 3 then works 2 times and skips the 3rd.

Any help here would be great.


Modified by Nicholas J. Conn - http://msp430launchpad.blogspot.com

Date Modified: 07-25-10

Modified by Larry N Critchfield 9600-8-N-1-N

Hello World !! Interrupt on P1.3 requests output to Terminal


#include  "msp430g2231.h"

#define     TXD                   BIT1        	// TXD on P1.1
#define     Bitime         		  104 			//9600 Baud, SMCLK=1MHz (1MHz/9600)=104

unsigned char BitCnt;  // Bit count, used when transmitting byte
unsigned int TXByte;  // Value sent over UART when Transmit() is called 

// Function Definitions

void Transmit(void);

void main(void)
 WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer

 P1DIR |= 0x01;                            // Set P1.0 to output direction
 P1IE |= 0x08;                             // P1.3 interrupt enabled
 P1IES |= 0x08;                            // P1.3 Hi/lo edge
 P1IFG &= ~0x08;                           // P1.3 IFG cleared

 _BIS_SR(LPM4_bits + GIE);                 // Enter LPM4 w/interrupt

// Port 1 interrupt service routine
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
P1IFG &= ~0x08;                           // P1.3 IFG cleared
unsigned int uartUpdateTimer = 10;  	  // Loops until byte is sent
unsigned int i = 0;         			  // Transmit value counter 33 = !

BCSCTL1 = CALBC1_1MHZ;               	  // Set range  
DCOCTL = CALDCO_1MHZ;      				  // SMCLK = DCO = 1MHz

P1SEL |= TXD;                             //  
P1DIR |= TXD;                             //     
__bis_SR_register(GIE);        			  // interrupts enabled\

int arInteger[14] = {72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 32, 33, 33};

/* Main Application Loop */ 

if (i > 13)							  // 	
	i = 0;
	P1OUT = 0x00;

if ((--uartUpdateTimer == 0))    
	P1OUT = 0x01;
	TXByte = arInteger[i];      

	uartUpdateTimer = 10;    

// Function Transmits Character from TXByte

void Transmit()
 CCTL0 = OUT;                              // TXD Idle as Mark  
 TACTL = TASSEL_2 + MC_2;               	// SMCLK, continuous mode   
 BitCnt = 0xA;                       		// Load Bit counter, 8 bits + ST/SP  
 CCR0 = TAR;     
 CCR0 += Bitime;                  			// Set time till first bit  
 TXByte |= 0x100;                 			// Add stop bit to TXByte (which is logical 1)  
 TXByte = TXByte << 1;            			// Add start bit (which is logical 0)     
 CCTL0 =  CCIS0 + OUTMOD0 + CCIE; 			// Set signal, intial value, enable interrupts  
 while ( CCTL0 & CCIE );          			// Wait for TX completion  
 TACTL = TASSEL_2;             			// SMCLK, timer off (for power consumption)

// Timer A0 interrupt service routine
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
 CCR0 += Bitime;     				// Add Offset to CCR0    
 if ( BitCnt == 0)     			// If all bits TXed, disable interrupt    
 CCTL0 &= ~ CCIE ;
 CCTL0 |=  OUTMOD2;                    // TX Space    
 if (TXByte & 0x01)      
 CCTL0 &= ~ OUTMOD2;                   // TX Mark    
 TXByte = TXByte >> 1;    
 BitCnt --;  


Link to post
Share on other sites

Hi Fairwind,

Thanks for uploading your example.


you push the p1.3 button, the first push you might get some garbage till they sync.

Easy enough to fix however the button works 2 times and skips the 3 then works 2 times and skips the 3rd.

Any help here would be great.

You may try debouncing your button. A simple way is to look at the value every 1ms or so for 5 to 6 times. If the value is the same(1 or 0), then it takes that value.

Link to post
Share on other sites



I'm real glad to see that my code is going to good use! I would recommend changing a few things if you are up for it.


First I would put the clock calibration in the beginning of your code, right after the watchdog disable, there really is no need to set the DCO more than once. Also if you decide that you want to, try to modify your button press interrupt to only set a flag which starts the sending operation. It is generally considered bad to put so much code inside of an interrupt routine. For example, have your main() contain a loop which looks for a flag which the button press sets, causing it to send hello world. Or if you are worried about power consumption, turn off the CPU in your main loop, and then turn it on in the button interrupt routine which would then cause your main function to send hello world. Don't feel though that you must, these are just suggestions :-). Great job with the code, and I'm glad it works!


Very good idea with the code, it gave me the idea that I should write a tutorial on using multiple interrupts like you have. Interrupts are a very powerful thing.





Link to post
Share on other sites


Thanks for the comments. They are all good ideas. They will most likely solve my missing

3rd button press. In the debugger the program is hung somewhere and pressing the button

again brings it back. Strange...

I look forward to any tut you might post, I am new to C++ and there is much to learn!!

How about showing us some interrupt code like you suggested.

Thanks again


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.

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...