This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

msp430g2231:HELP

Other Parts Discussed in Thread: MSP430G2231, MSP430G2131, MSP430G2553, MSP430G2253, IAR-KICKSTART

Hi

I am working on msp430g2231 and I have very less knowledge about it.

I have written a Code to test the working of ISR(interrupt sub routine)  of timer_a.

But I think there is a problem and the program is unable to execute the sub routine.

The idea is to blink an LED(P1.0) upon button press(P1.3).(Note: blinking is just to check whether the program is executing the ISR or not?)

----------------------------

and 

TACCTL0= CM_3 | CCIS_1 | SCS | CAP | CCIE;

Please tell me  do we need to route the button with CCI0B externally or it is already routed???

Please follow the code below and help.

-----------------------------------------------------------------------------------------------------------------------------

#include "msp430g2231.h"

void main(void)
{
WDTCTL= WDTPW | WDTHOLD;
P1OUT = 0;
P1DIR = 0x01;
P1SEL = BIT3;
TACCTL0= CM_3 | CCIS_1 | SCS | CAP | CCIE;
TACTL = TASSEL_2 | ID_3 | MC_2 | TACLR;
for ( ;;)
{
__low_power_mode_3();
}
}

# pragma vector = TIMERA0_VECTOR
__interrupt void TIMERA0_ISR (void)
{
P1OUT=0x01;

}


  • hello salony

    Have no hardware with me to test my suggestion but anyway:

    salony agarwal said:
    P1DIR = 0x08;

    sets P1.3 as output but you need this as an input for your button.

    void main(void)
    {
    WDTCTL= WDTPW | WDTHOLD; // seem to be okay (switch off the watchdog)
    P1OUT &= ~0x01;  // init Output with LED -> not that important in your case (depends on the schematic of your design) LED on or off
    P1DIR  |= 0x01;  // Led is on Port 1.0 -> set BIT0 from P1 as output

    //P1SEL = BIT3; // what do you want to do here? select pullup? I think it selects a special function on the input of your button. seems to be wrong -> suggest to comment this

    /* I can't check this for you at the moment -> sorry
    TACCTL0= CM_3 | CCIS_1 | SCS | CAP | CCIE;
    TACTL = TASSEL_2 | ID_3 | MC_2 | TACLR;
    for ( ;;)
    {
    __low_power_mode_3();
    }
    }

    # pragma vector = TIMERA0_VECTOR
    __interrupt void TIMERA0_ISR (void)
    {
        if ((P1IN & 0x03) == 0)   //  if BIT3 == 0 -> Button pressed on P1 (in case you have a pull-up and button against GND)

            P1OUT ^=0x01; // toggle LED P1.0 (XOR of BIT1);

       else

           P1OUT &= ~0x01; // Init Led to defined state when no button is pressed
    }


    Hope this helps a little

    cheers, Matthias

     

     

  • Hi matthias

    Thanks a lot.

    But the real problem is not about LED blinking.I just want to test whether on a BUTTON PRESS  my program is executing the ISR(interrupt service routine ) or not.

    Therefore just to test I have written P1OUT=0x01 in the ISR for timer A.

    #include "msp430g2231.h"
    #include <stdint.h>
    #include <stdio.h>
    void main(void)
    {
    WDTCTL= WDTPW | WDTHOLD;
    //FILE *output_file;

    P1OUT = 0x00;
    P1DIR = 0x01;
    P1SEL = BIT3; //this is to route P1.3 to CCI0B according to the book..
    TACCTL0= CM_3 | CCIS_1 | SCS | CAP | CCIE; //
    TACTL = TASSEL_2 | ID_3 | MC_2 | TACLR;
    for ( ;;)
    {
    __low_power_mode_3();
    }
    }

    # pragma vector = TIMERA0_VECTOR
    __interrupt void TIMERA0_ISR (void)
    {

    P1OUT=0x01;
    //static uint16_t lasttime;
    //FILE *output_file;
    //fopen("c:\nivedita\database.txt", "w");
    //fprintf((TACCR0-lasttime), "Cannot open %s\n", "c:\nivedita\database.txt");
    //fprintf( TACCR0 - lasttime,"c:\nivedita\database.txt");
    //lasttime= TACCR0;
    //printf("%d",TACCR0);
    }
    ALL THE COMMENTED LINES ABOVE ARE A PART OF THE ACTUAL CODE.BUT NOTHING WAS WORKING SO JUST TO TEST I HAVE WRITTEN P1OUT=0X01.
  • I think P1.3 can't be used as TA0 capture input for G2231.

    Try P1.1   for CCI0A.

    Or P1.2 for CCI1A , but you need to use the TIMERA1_VECTOR interrupt as well 

    as configureTACCTL1 . 

  • Thanks Rame

    But P1.1 is TXD and P1.2 is RXD. so can I use them??

    And I need these pins for other purpose.So Is there any alternative??

  •  

    Hi Salony

    Okay, it’s not so easy. Think you expect your button to trigger the capturing function of your timer. (CCI0B input for capturing both edges.)

    salony agarwal said:
    P1SEL = BIT3; //this is to route P1.3 to CCI0B according to the book..

    Your code to setup the timer should work as far as I can see, but given I understand the documentation of the chip, P1.3 can’t be routed to CCI0B according document SLAS694I (msp430g2131.pdf)  See: Table 19. Port P1 (P1.3) Pin Functions.

    So it depends on your hardware if you have another button available, e.g. on P1.1

    • Still think, that you need to toggle the LED or at least clear it in your main loop for(; ;), otherwise it will turn on and stay turned on forever.
    • Once you solved this, bouncing of your button may cause unexpected results.
    • Perhaps you need to configure the clock according your needs too. (You use ClockSource = SMCLK/8 for your timer)
    • Further I would recommend you not to enter lowpower-mode as long as your design is not verified to work with the timer interrupt.Ho

    Hope this helps,

    Cheers, Matthias

  •  

    Hi
    Think that P1.6 can be used as TA0.CCI1B. Perhaps this helps more.

    Document SLAS694I

    See Table 22 Page 41: Maybe TA0.CCR1B is a typo and should be read as TA0.CCI1B, (like on page 35 for the MSP430G2x21-device)


    BR

    Matthias

  • Hi

    Do  you want to use P1.1 and 1.2 as TX and RX pins for Software (Timer ) UART?

    If not , P1.1 and 1.2 are not necessarily TXD and RXD since the MSP430G2231 has no

    hardware UART.

    If yes, this might complicate things since this chip only has one Timer (Timer_A).

    and  2 capture and compare registers (CCR0 and CCR1). but CCR0 is used in

    the transmit mode and CCR1 is used in the receive mode.

    BTW, what do you want to do during ISR  (Timer capture ) except for that LED .

    Don't  think the 'commented' codes in the ISR will work.

    Regards,

     

  • Hi Matthias

    Thanks a lot. I will  use another pin as per the datasheet.

    And I also want to know whether PRINTF works on CCS (v4) or not.

    I am getting errors in a simple program of "hello world".

    ------------------------------------------------------------------------------------------------

    errors encountered during linking; "one.out" not built		one	line 0	1329298983243	24
    placement fails for object ".text", size 0x10cc (page 0).  Available ranges: FLASH        size: 0x7e0        unused: 0x756        max hole: 0x756		one	line 0	1329298983239	241
    run placement fails for object ".bss", size 0x22c (page 0).  Available ranges: RAM          size: 0x80         unused: 0x4a         max hole: 0x48		one	line 0	1329298983239	242
    run placement fails for object ".cio", size 0x120 (page 0).  Available ranges: RAM          size: 0x80         unused: 0x4a         max hole: 0x48		one	line 0	1329298983239	243
    unresolved symbol sleep, first referenced in ./main.obj		one	line 0	1329298983242	244
    function declared implicitly	one	main.c	line 28	1329298983237	239
    function declared implicitly	one	main.c	line 31	1329298983238	240
    -------------------------------------------------------------------------------------------------------------
    please suggest something.
    
    
    thanks.
  • Hi Rame

    Thanks a lot for the information.

    Actually I want to interface an IR(infrared) sensor which gives a PWM output.

    I need to take the values at every instant and store it in a TEXT file or get the result printed.(But PRINTF command is not working)

    so before executing the main program i wanted to test it first.So I used the button P1.3 (on and off at different instants to give a pulse ) to check if I can capture a PWM output or not?

    thanks

  • Hello Salony

    You are working on a small microcontroller.

    printf is a ressorce greedy  RAM consuming thing with all its options. Of course you can write something similar and you may call it printf too, but I would suggest you another path to make your information accessible for the outside word. Perhaps there is a way to tell your controller how to emulate an UART and teach it to be your stdio, but it is likely that this approach consumes all your FLASH. Try SPI or perhaps I2C. I suggest you to use some data-lines and a strobe signal and perhaps you have something like a logic-analyzer. Or create a ringbuffer in RAM and store your results there. (After a while you can use your debugger to examine them.)

    regards, Matthias

  • Hi

    Are you trying to measure the pulse width (from the IR sensor) and display

    the data on your computer with a Launchpad connected?

    That would be an interesting weekend project.

    But you might want to use MSP430G2553 (if you want to use DIP).

    Regards,

  • By the way, what's the frequency (or period)  of the sensor PWM output.

  • Hi Rame

    Yes,exactly.But I dont want to use DIP.

    But I am facing problem in displaying the output on the screen because neither the"  printf "

    function works nor I am able to create a Text file.(Because of less memory space).

    what do you suggest?

  • If you are using a Launchpad (I suspect this  because you use MSP430G2231)  , you will have to write a code for your microcontroller

    that will acquire data (pulse width?) and send data to your computer via UART (Serial  - Virtual COM Port VCP).

    On the computer, you will need to write an application program that will receive the data and plot it (or write it on a textfile).

    Alternatively, you can use a serial port monitor program just to see the data sent via serial (COM).

    However, doing this with MSP430G2231 will be difficult because this chip has no hardware UART although

    software UART is possible .

    I suggested MSP430G2253 since it also comes in DIP (Dual in Line Package) which you can

    insert on the Launchpad IC socket.

    For a start, you can verify if MSP430G2231 that you have now can our properly determine the pulse width

    from the sensor. You can program  the MSP430G2231 to  light up one of the LEDs if the pulse width is above 

    or below a specified value. What is exactly is the output of your sensor  (frequency / period) or simply what's the part number?

  • Hi Rame

    Thanks a lot.

    The output of sensor is PWM wave.The duration ofthe pulse will help in determining the temperature.

    Can you please tell me why should i go for MSP430G2253 ?(Besides being a 20 DIP IC )

    thanks

  • Hi

    What is  the period of the PWM wave ?You'll need this in order to select the proper

    clock source and configuration for the Timer.

    I suggested MSP430G2253 because it has a hardware UART that will allow

    easy communication to your PC.It comes with a USCI module.

  • hello salony

     i think the soft -uart that comes with the example-code from ti will fit your needs,. no need to use MSP430G2253 so far. temperature is not changing too fast over time for an emulated uart. by the way, A led and and a series-resistor may be sufficent to build an opto- transmitter instead of using a level shifter. a receiver can be built with a few parts and can be powered from tx while pressing a key in e.g. hyperterm. selelct 2400 or 1200 baud 8484.PROTOTYPE.zip  

    cheers, matthias

  • hello Matthias

    I tried to run the soft-uart example code from TI  but I am unable to do so.

    I dont know how to give input to the port while the program is running and how to check the output for the uart program.

    Moreover P2 port is also used but as I can see there is no P2 port in msp430g2231.

    Thanks

  • Hi Rame

    Thanks a ton. The period of PWM wave is 1.024 ms.

    So please suggest should I go for msp430g2253 or work on msp430g2231 ?

    Thanks

  •   

    Since you will also have to use the Timer for capturing pulse width , using MSP430G2231 will be complicated(but perhaps possible). This device only has a one Timer module(TIMER_A) which you will have to reconfigure everytime you use it to acquire data(capture mode) and for UART (compare mode). So if you can get MSP430G2253, I suggest using it .

     

    Here’s a code that is suppose to blink P1.0 if the PWM input is greater than 50%.

    Let me know if you try it and it works.

     

    /PWM input on P1.2 (freq approx 976Hz)

    //Indicator P1.0 LED ,toogles if PWM duty cycle > 50%

    // Ongoing debug ....rev a0

     

    #include "msp430G2231.h"

     

    unsigned int counter=0;

    float data_1=0;

    float data_2=0;

    float data=0;

     

    void main(void)

    {

                WDTCTL= WDTPW + WDTHOLD;

                P1DIR = 0x01;

            P1SEL |= BIT2;

                TACCTL1= CM_3 + CCIS_0 + SCS + CAP + CCIE;

                TACTL = TASSEL_2 + ID_3 + MC_2 + TAIE;

            _BIS_SR(LPM0_bits + GIE);                

    }

     

     

    # pragma vector = TIMERA1_VECTOR

    __interrupt void TIMERA0_ISR (void)

     

    {

       switch (TAIV)

       { 

       case 2:

         {if (data_1==0)data_1=CCR1;    //capture rising edge

          else

          { data_2=CCR1+(counter*65535);  //capture falling edge ,add timer overflow cycles

            data=data_2-data_1;       //calculate difference

             if(data>70400) P1OUT^=0x01;}

            break;}

       case 4:break;

       case 10:{counter++;break;}  //count up timer every time timer overflows

       

       }

       }

     

     

     

     

  • As I understand it right, transmit of data is sufficent for you. So you can use the same timer. Tune it for the bitrate and shift out one bit every time you get the cyclic interrupt. Capture of PWM is another task, independant  from this. You need a timestamp on every edge and nothing else. it's possible even if you have to write your delay-loop in c, without a timer. the jitter coming from the interrupt will not be a problem with your period. Had a look for some sample code that I wrote long time ago but unfortunatly was not able to find it after this years. but it worked fine, back in 2009.

    So if you want to go to mass production, it can make a difference to choose only MSP430G2231. But Rame is right for a DYS-project, it's easyer and faster to take MSP430G2253.

    BR Matthias

     

  • Hi Rame,

    Thanks for the code. I have not tried it yet but will let you know if it works or not. I was on my own going through the code generated by you and I could not understand how have you calculated the values like:

    counter* 65535 and data> 70400 . Please inform me.. It will enhance my approach.

    Regards,

  • Hi Rame,

    It's regarding your code. We can get the range of min. 4ms from SMCLK to max of 16sec from ACLK. And the 50% duty cycle of IR sensor corresponds to 0.512msec which means that the count will always be less than 65535. 

    What frequency have you used for SMCLK? 16 or 1 MHZ before dividing by 8.

    Thanks.

  • Hi Salony

    I agree. I must have made the mistake while punching in the numbers  on windows calculator.

    The default SMCLK from DCO  is approx 1.1MHz so we will not divide it by 8 .

    You can change the SMCLK to 1MHz or 16MHz by configuring the DCO.

    +++++++++++++++++++++++

    //1Mhz
      BCSCTL1 = CALBC1_1MHZ;                    // Set range
      DCOCTL = CALDCO_1MHZ;                     //



     //16Mhz
      BCSCTL1 = CALBC1_16MHZ;                   // Set range
      DCOCTL = CALDCO_16MHZ;                    //

    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    Here is a revised code but have not  tested it. If you have a working one post it here

    and we'll try to see if we can send data via software UART using CCR0.

    /PWM input on P1.2 (freq approx 976Hz)

    //Indicator P1.0 LED ,toogles if PWM duty cycle > 50%

    // Ongoing debug ....rev a1

     

    #include "msp430G2231.h"

     

    int data_1=0;

    int data_2=0;

    int data=0;

     

    void main(void)

    {

                WDTCTL= WDTPW + WDTHOLD;

                P1DIR = 0x01;

               P1SEL |= BIT2;

                TACCTL1= CM_1 + CCIS_0 + SCS + CAP + CCIE;

                TACTL = TASSEL_2 + MC_2 + TAIE;

            _BIS_SR(LPM0_bits + GIE);                

    }

     

     

    # pragma vector = TIMERA1_VECTOR

    __interrupt void TIMERA0_ISR (void)

     

    {

       switch (TAIV)

       { 

       case 2:

         {if (data_1==0){data_1=CCR1;    //time stamp rising edge

     TACCTL1|= CM_2 ;} // change mode to falling edge

          else

          { data_2=CCR1;  /time stamp falling edge

            data=data_2-data_1;       //calculate difference

              TACCTL1|= CM_1 ;//change capture mode to rising edge

             if(data>563) P1OUT^=0x01;}

            break;}

       case 4:break; //not used

       case 10:break; //not used

       

       }

       }

     

  • Hi Rame

    Thanks a lot.Now I am able to verify the values.

    I will soon test the code and will post the desired  code as soon as possible.

    I will need your help for the software UART coding part.

    I am unable to run the UART code (baud 9600) given by TI.So please assist me.

    thanks

  • By the way, I did not reset data_1 to zero after having calculated data.

    You will have to insert a line to do it. Thanks.

  • Hi Rame,

    In the code you have written, i think you have not considered the condition when rollover of timerA occurs.

    I have revised it but not executed.Please check if its correct.

    # pragma vector = TIMERA1_VECTOR

    __interrupt void TIMERA0_ISR (void)

     

    {

       switch (TAIV)

       { 

       case 2:

         {

    if (data_1==0)

    {


    data_1=CCR1;    //time stamp rising edge

     TACCTL1|= CM_2 ;

    } // change mode to falling edge  

          else

          {

    data_2=CCR1;  /time stamp falling edge

            data=data_2-data_1;       //calculate difference

    if(data >1147)         //1.042 msec corresponds to count value of 1147=47B considering 1.1MHz clock frequency.

    {

    data=65535-data;

    }

              TACCTL1|= CM_1 ;//change capture mode to rising edge

             if(data>563) P1OUT^=0x01;

             data_1==0;}

            break;}

       case 4:break; //not used

       case 10:break; //not used

       

       }

       }

     

  • Hi

    I don't think there is a need to worry about 'rollover' condition.

    We can simply declare data, data_1 and data_2 as unsigned integers.

    unsigned int data;

    unsigned int data_1;

    unsigned int data_2;

    The Timer is operating in continuous mode(it counts until FFFF).

    If it reaches 'rollover'  (FFFF ->0) , say , data_1=FFFA (dec 65530) and data_1=0010(dec 16). The difference is still 16(dec 22).

    And I think you'll need to reset data_1=0 (one '=' sign)  , immediately after calculating 'data'.

    I suggest you test it with your sensor connected.

    Regards

  • Hi Rame

    Please tell how to run this code and how to give input to the ports in CCS (version4) ?

    This is an example code of soft- UART given in TI tutorial for MSP430. I want to test it in order to send the values captured by the IR sensor to PC. 

    -------------------------------------------------------------------------------------------------------------------------------------

    #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; // WHAT THIS SIGN INDICATES ">>=" ??
    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;
    }
    }
    ------------------------------------------------------------
    Thanks.
  • Hi salony

    salony agarwal said:
    txData >>= 1; // WHAT THIS SIGN INDICATES ">>=" ??

    This shifts the value in txData one bit to the right. The most right bit is sent to the port every time the timer interrupt occurs. (->the time for one bit @ choosen baudrate) An uart is similar to a shift register. Here the value is perpared for the next bit to appear on the out-pin (tx). Start-bit and stop-bit are not part of the tx-data. Therefore 10 bits are needed to transmit 8 bits of information.

    if you need no receive functionality, you can discard <Receive Interrupt Handler> and further simplify your design.

    cheers, matthias

  • Hi Matthias

    Thanks a lot.

    I am not able to understand how this code works.P1.1 and P1.2 (TXD and RXD ) are not used anywhere except for PDIR.

    Please explain when and how will the interrupt generate ?

    Can you please tell how can I run this code on CCS(v4).

    Thanks

  • Hello Salony

    The timer module can be programmed for a pin action to be executed when the compare value matches the free running counter. Have a look for the OUTMODx keyword in the manual.  Its amazing what can be done with the Ouput-Modes: Toggle, Set, Reset, and combinations of them 

    Your RX from the example works in a similar way: routed directly to the timer. So there is no code needed to treat them like IO-ports as it would  be needed for leds and buttons in general.

    I use CSS(5.1) and would recommend you to do the same. It's free too for your purposes. post your project and perhaps I can find some time at weekend to help you merging your code with UART-Example.

    Cheers, matthias

  • Hi Salony,

    First, you need an application program running on your PC that will read

    the com port. You can create one or you can install a serial port reader application

    such as any of the following.

    http://www.serialporttool.com/CommPalInfo.htm

    http://www.232analyzer.com/232default.htm

    Since you will only need to send data , I have modified the code above and

    removed the "receive" actions. Try to download this into your MSP430G2231.

    It should send  "UART TEST OK" if the P1.3 button is pressed. 

    You were asking about CCSv4. I think there are plenty of tutorials

    available on how to use it. Personally , I would suggest you use

    IAR embedded workbench kickstart.

    Link : http://www.ti.com/tool/iar-kickstart

    //code

    #include "msp430g2231.h"

    //------------------------------------------------------------------------------
    // Hardware-related definitions
    //------------------------------------------------------------------------------
    #define UART_TXD 0x02 // TXD on P1.1 (Timer0_A.OUT0)

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

    //------------------------------------------------------------------------------
    // 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 ; // Timer function for TXD/RXD pins
    P1REN=BIT3 //enable pull up resistor in case external resistor is not populated
    P1DIR |= 0x02
    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");

    while(1)
    {
    while((BIT3&P1IN)==0)
    {
            TimerA_UART_print("UART TEST OK");
                    }
               while((BIT3&P1IN)==0)
                   {                                                                                     //do nothing
    }

    }
    }




    //------------------------------------------------------------------------------
    // Function configures Timer_A for full-duplex UART operation
    //------------------------------------------------------------------------------
    void TimerA_UART_init(void)
    {
    TACCTL0 = OUT; // Set TXD Idle as Mark = '1'
    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; // WHAT THIS SIGN INDICATES ">>=" ??
    txBitCnt--;
    }
    }
  • That's C++ 101.

    It is the C++ short version for x = x>>1 and does a right-shift of the variable, dropping th ecurent BIT0 and making BIT1 the new BIT0 (and BIT2 to BIT1etc.).

  • Hi Michael

    My program of SOFT-UART is running successfully.I am using putty for  the terminal display of the result.

    Can you please tell me how do i write a program on PC to modify the data received for example plotting of graph(for numerical values)?

    or is there any software which will do the work directly?

    In my actual program i need to get the PWM wave from an infrared sensor,convert the PWM output to respective temperature value and finally store the values and plot it against time.

    thanks

  • Hi Rame

    My program of SOFT-UART is running successfully.I am using putty for  the terminal display of the result.

    Can you please tell me how do i write a program on PC to modify the data received for example plotting of graph(for numerical values)?

    or is there any software which will do the work directly?

    In my actual program i need to get the PWM wave from an infrared sensor,convert the PWM output to respective temperature value and finally store the values and plot it against time.

    thanks

  • Take a look at this project.

    It receives commands from PC and sends answers (msotly ADC conversion results) to the PC, using a LaunchPad. Onteh PC side, the application has a simple Windows Forms UI (C#) for the controls and uses a free scope library for the plotting. However, it is not an x/y plot but rather a realtime display of incoming values.
    However, it is worth a look if you want to know how things like this can be done.

    Of course you can replace the calls to the library by your own line drawing functions.

**Attention** This is a public forum