Msp430g2533 lm35

Thread Starter

ivaninspace

Joined Jul 28, 2013
10
Hello I am using
Code composer 5.1
Microcontroller: MSP430G2533
LM35
Using Putty for m hyperterminal

Question: I can't seem to get the data of two LM35's to display on my hyperterminal? The follow code is the best I've been able to think of.

The code is based on the following website.
http://karve.in/?p=597#comment-507

code:
Rich (BB code):
#include <msp430g2553.h>
#include <stdbool.h>
////////////////Defines////////////////
#define LED1        BIT6
#define LED0        BIT0
#define Error       BIT0
#define GND         BIT4
#define DAT         BIT5
#define DAT2	    BIT7////////////////////////////////////////////////////new
#define VCC         BIT0 //port P2.0
char buffer[4];
float temp;
float temp2;
int n_temp,r_temp;

int x=0,y=0;

////////////////Function Protos////////////////
void TX(char *tx_message);
static char *i2a(unsigned i, char *a, unsigned r);
char *itoa(int i, char *a, int r);
void ADC_init(void);

static char *i2a(unsigned i, char *a, unsigned r)
{
    if (i/r > 0) a = i2a(i/r,a,r);
    *a = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[i%r];
    return a+1;
}

char *itoa(int i, char *a, int r)
{
    if ((r < 2) || (r > 36)) r = 10;
    if (i < 0)
    {
        *a = '-';
        *i2a(-(unsigned)i,a+1,r) = 0;
    }
    else *i2a(i,a,r) = 0;
    return a;
}

void TX(char *tx_message)
{
    unsigned int i=0; //Define end of string loop int
    char *message; // message variable
    unsigned int message_num; // define ascii int version variable
    message = tx_message; // move tx_message into message
    while(1)
    {
        if(message==0) // If end of input string is reached, break loop.
        {break;}
        message_num = (int)message; //Cast string char into a int variable
        UCA0TXBUF = message_num; // write INT to TX buffer
        i++; // increase string index
        __delay_cycles(10000); //transmission delay
        if(i>50) //prevent infinite transmit
        {
            P1OUT |= Error;
            break;
        }
    } // End TX Main While Loop
} // End TX Function

///////////////////////////////////////////////////////////////////////////////////////////////////
void ADC_init()
{
    /* Configure ADC  Channel */
    ADC10CTL1 = INCH_5 + ADC10DIV_3 ;         // Channel 5, ADC10CLK/4
    ADC10CTL0 = SREF_0 + ADC10SHT_3 + ADC10ON + ADC10IE;  //Vcc & Vss as reference
    ADC10AE0 |= BIT5;                         //P1.5 ADC option
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void ADC2_init()
{
    /* Configure ADC  Channel */
    ADC10CTL1 = INCH_7 + ADC10DIV_3 ;         // Channel 7, ADC10CLK/4
    ADC10CTL0 = SREF_0 + ADC10SHT_3 + ADC10ON + ADC10IE;  //Vcc & Vss as reference
    ADC10AE0 |= BIT7;                         //P1.7 ADC option
}
///////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////MAIN PROGRAM LOOP//////////////////////////////////////////////////

void main(void)
{


    WDTCTL = WDTPW + WDTHOLD;         // Stop WDT
    BCSCTL1 = CALBC1_1MHZ;            // Set DCO to 1MHz
    DCOCTL = CALDCO_1MHZ;
    ////////////////USCI setup////////////////
    P1SEL = BIT1 + BIT2;            // Set P1.1 to RXD and P1.2 to TXD
    P1SEL2 = BIT1 + BIT2;            //
    UCA0CTL1 |= UCSSEL_2;            // Have USCI use SMCLK AKA 1MHz main CLK
    UCA0BR0 = 104;                  // Baud: 9600, N= CLK/Baud, N= 10^6 / 9600
    UCA0BR1 = 0;                  // Set upper half of baud select to 0
    UCA0MCTL = UCBRS_1;               // Modulation UCBRSx = 1
    UCA0CTL1 &= ~UCSWRST;             // Start USCI
    ////////////////General GPIO Defines////////////////
    P1DIR |= (LED1+GND+LED0);            //Define GPIOs as outputs else GPIOs are inputs
    P2DIR |=VCC;
    P1OUT =0;                     //All Outputs off except for Green_LED
    P2OUT|=VCC;
    P1OUT&=~GND;

while(1)
{
/*    do{
///////////////////SETUP ADC10 TO READ FROM CH A4 (P1.5)/////////////////////////////////////////////
    ADC_init();
    __enable_interrupt();                     // Enable interrupts.
    int value=0;
///////////////////////////////Main Loop/////////////////////////////////////////////////////////////

    	__delay_cycles(1000);                   // Wait for ADC Ref to settle
        ADC10CTL0 |= ENC + ADC10SC;             // Sampling and conversion start
        __bis_SR_register(CPUOFF + GIE);        // LPM0 with interrupts enabled
        value = ADC10MEM;
        temp=value*0.317;
        r_temp=((temp*10)-10) * ((temp*10)/10);
        itoa(temp, buffer, 10);
        TX("External Temp:");
        TX(buffer);
        TX(".");
        itoa(r_temp, buffer, 10);
        TX(buffer);
        TX(" Celsius\r\n");
        P1OUT ^= LED0;
        _delay_cycles(500000);
        y=0;
        x++;
}while(x==1000);*/

do{
///////////////////SETUP ADC10 TO READ FROM CH A4 (P1.7)/////////////////////////////////////////////
    ADC2_init();
    __enable_interrupt();                     // Enable interrupts.
    int value2=0;
///////////////////////////////Main Loop/////////////////////////////////////////////////////////////

        __delay_cycles(1000);                   // Wait for ADC Ref to settle
        ADC10CTL0 |= ENC + ADC10SC;             // Sampling and conversion start
        __bis_SR_register(CPUOFF + GIE);        // LPM0 with interrupts enabled
        value2 = ADC10MEM;
        temp2=value2*0.317;
        r_temp=((temp2*10)-10) * ((temp2*10)/10);
        itoa(temp2, buffer, 10);
        TX("Internal Temp:");
        TX(buffer);
        TX(".");
        itoa(r_temp, buffer, 10);
        TX(buffer);
        TX(" Celsius\r\n");
        P1OUT ^= LED0;
        _delay_cycles(500000);
        x=0;
        y++;
}while(y==1000);

} //End while

} // End Main Program

// ADC10 interrupt service routine
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR (void)
{
  __bic_SR_register_on_exit(CPUOFF);        // Return to active mode
  P1OUT ^= LED1;
}
 
Last edited by a moderator:

tshuck

Joined Oct 18, 2012
3,534
So have you got working? Have you verified that your uC is able to send data over to the terminal correctly? What about interfacing to the LM35?

In short, what is and isn't working?

Question: I can't seem to get the data of two LM35's to display on my hyperterminal?
Adding a question mark doesn't make it a question.
 

Thread Starter

ivaninspace

Joined Jul 28, 2013
10
The programming in the link I provided works great, I can see the temp of the LM35 on my computer. Now I'm trying to change a bit so that it outputs the value of two LM35s. The second LM35 I am trying to view as well is connected to port P1.7 using the same ground and Vcc as the first. When I try to run two different While loops or just simply add a copy of the code in the int main but changing it for the new pin, it outputs the text like below but the values are not different. I can put my finger on the second LM35 and I don't see any change in the second LM35 value. But once I put my finger on the first LM35 the value changes but for both.

This is an example of how the hyperterminal would output the data
------------------------
First LM35: 19 Celsius
Second LM35: 19 Celsius
 

tshuck

Joined Oct 18, 2012
3,534
For one thing, when both ADC blocks are in effect, you are ORing the contents of the ADC10AE0 register, meaning that after configuring the first LM35, you have INCHx = 0b0101,
Rich (BB code):
ADC10AE0 |= BIT5;
then you OR that value with BIT 7, making INCHx = 0111
Rich (BB code):
ADC10AE0 |= BIT7;
, which would be fine - for a single cycle. Since your do-while loop is only done once (while(y==1000); will always be false, unless, on the off chance that it gets initialized to 1000, but even then, it will get incremented and be stuck in the same loop).

Rich (BB code):
char *message; // message variable
[...]
    message = tx_message; // move tx_message into message
I know that this wasn't written by you, but this is the problem with trying to copy another person's code without understanding the syntax. This is a pointer, you are copying a pointer, not moving anything.

Anyway, I'm off to the store, I'll have another look when I get back...
 

Thread Starter

ivaninspace

Joined Jul 28, 2013
10
Thanks for looking this over for me. I decided to take out the (Do While) and just leave one continuous while loop with both LM35's being sampled. But I still managed to get the first LM35's value in both outputs when i view it on the hyperterminal. I think I'm having a problem with the ADC10CTL1 where the CONSEQ is not set to 01 for Sequence of Channels. Am I going on the right track? I really appreciate your time!
Here is the new code
#include <msp430g2553.h>
#include <stdbool.h>
////////////////Defines////////////////
#define LED1 BIT6
#define LED0 BIT0
#define Error BIT0
#define GND BIT4
#define DAT BIT5
#define DAT2 BIT7////////////////////////////////////////////////////new
#define VCC BIT0 //port P2.0
char buffer[4];
float temp;
float temp2;
int r_temp,r_temp2;


////////////////Function Protos////////////////
void TX(char *tx_message);
static char *i2a(unsigned i, char *a, unsigned r);
char *itoa(int i, char *a, int r);

void ADC_init(void);
void ADC2_init(void);

static char *i2a(unsigned i, char *a, unsigned r)
{
if (i/r > 0) a = i2a(i/r,a,r);
*a = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[i%r];
return a+1;
}

char *itoa(int i, char *a, int r)
{
if ((r < 2) || (r > 36)) r = 10;
if (i < 0)
{
*a = '-';
*i2a(-(unsigned)i,a+1,r) = 0;
}
else *i2a(i,a,r) = 0;
return a;
}

void TX(char *tx_message)
{
unsigned int i=0; //Define end of string loop int
char *message; // message variable
unsigned int message_num; // define ascii int version variable
message = tx_message; // move tx_message into message
while(1)
{
if(message==0) // If end of input string is reached, break loop.
{break;}
message_num = (int)message; //Cast string char into a int variable
UCA0TXBUF = message_num; // write INT to TX buffer
i++; // increase string index
__delay_cycles(10000); //transmission delay
if(i>50) //prevent infinite transmit
{
P1OUT |= Error;
break;
}
} // End TX Main While Loop
} // End TX Function

///////////////////////////////////////////////////////////////////////////////////////////////////
void ADC_init()
{
/* Configure ADC Channel */
ADC10CTL1 = INCH_5 + ADC10DIV_3; // Channel 5, ADC10CLK/4
ADC10CTL0 = SREF_0 + ADC10SHT_3 + ADC10ON + ADC10IE; //Vcc & Vss as reference
ADC10AE0 |= BIT5; //P1.5 ADC option
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void ADC2_init()
{
/* Configure ADC Channel */
ADC10CTL1 = INCH_7 + ADC10DIV_3; // Channel 7, ADC10CLK/4
ADC10CTL0 = SREF_0 + ADC10SHT_3 + ADC10ON + ADC10IE; //Vcc & Vss as reference
ADC10AE0 |= BIT7; //P1.7 ADC option
}
///////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////MAIN PROGRAM LOOP//////////////////////////////////////////////////

void main(void)
{


WDTCTL = WDTPW + WDTHOLD; // Stop WDT
BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1MHz
DCOCTL = CALDCO_1MHZ;
////////////////USCI setup////////////////
P1SEL = BIT1 + BIT2; // Set P1.1 to RXD and P1.2 to TXD
P1SEL2 = BIT1 + BIT2; //
UCA0CTL1 |= UCSSEL_2; // Have USCI use SMCLK AKA 1MHz main CLK
UCA0BR0 = 104; // Baud: 9600, N= CLK/Baud, N= 10^6 / 9600
UCA0BR1 = 0; // Set upper half of baud select to 0
UCA0MCTL = UCBRS_1; // Modulation UCBRSx = 1
UCA0CTL1 &= ~UCSWRST; // Start USCI
////////////////General GPIO Defines////////////////
P1DIR |= (LED1+GND+LED0); //Define GPIOs as outputs else GPIOs are inputs
P2DIR |=VCC;
P1OUT =0; //All Outputs off except for Green_LED
P2OUT|=VCC;
P1OUT&=~GND;
while(1)
{
///////////////////SETUP ADC10 TO READ FROM CH A4 (P1.5)/////////////////////////////////////////////
ADC_init();
__enable_interrupt(); // Enable interrupts.
int value=0;
///////////////////////////////Main Loop/////////////////////////////////////////////////////////////

__delay_cycles(1000); // Wait for ADC Ref to settle

ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
__bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled
value = ADC10MEM;

temp=value*0.317;
r_temp=((temp*10)-10) * ((temp*10)/10);

itoa(temp, buffer, 10);
TX("External Temp:");
TX(buffer);
TX(".");
itoa(r_temp, buffer, 10);
TX(buffer);
TX(" Celsius\r\n");
P1OUT ^= LED0;

_delay_cycles(500000);
_delay_cycles(500000);


///////////////////SETUP ADC10 TO READ FROM CH A4 (P1.7)/////////////////////////////////////////////
ADC2_init();
__enable_interrupt(); // Enable interrupts.
int value2=0;
///////////////////////////////Main Loop/////////////////////////////////////////////////////////////

__delay_cycles(1000); // Wait for ADC Ref to settle

ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
__bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled
value2 = ADC10MEM;

temp2=value2*0.317;
r_temp2=((temp2*10)-10) * ((temp2*10)/10);

itoa(temp2, buffer, 10);
TX("Internal Temp:");
TX(buffer);
TX(".");
itoa(r_temp2, buffer, 10);
TX(buffer);
TX(" Celsius\r\n");
P1OUT ^= LED0;

_delay_cycles(500000);
_delay_cycles(500000);

} //End while

} // End Main Program

// ADC10 interrupt service routine
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR (void)
{
__bic_SR_register_on_exit(CPUOFF); // Return to active mode
P1OUT ^= LED1;
}
 

tshuck

Joined Oct 18, 2012
3,534
You don't seen to be waiting for the ADC conversion to finish...you enable the ADC, turn on interrupts, then read the value returned from the last ADC conversion, which probably hadn't been updated. I would suggest polling (I wouldn't advise using interrupts at your level) the ADC status and wait until it's finished (I'm not at my computer, so I can't tell you specifics at the moment).

Also, please use code tags when posting code (the # button).
 

Thread Starter

ivaninspace

Joined Jul 28, 2013
10
Thanks a lot, I think I know where you going with this. I should remove the __enable_interrupt(); // Enable interrupts. routine and let the rest of the code poll the pins.
 

tshuck

Joined Oct 18, 2012
3,534
Thanks a lot, I think I know where you going with this. I should remove the __enable_interrupt(); // Enable interrupts. routine and let the rest of the code poll the pins.
The interrupt that is therejust toggles an LED, indicating a conversion - this one is fine to leave in. I was referring to using interrupts to do the ADC conversion.

You need to make your code sample the status the ADC and only get the converted value once the conversion is finished - your code now isn't polling...
 

Thread Starter

ivaninspace

Joined Jul 28, 2013
10
If you don't mind, could you give me an example of how to use the code I have to poll?

The following code has a lot of the interrupt code commented out but it still outputs the same value for both LM35's on the hyperterminal

Rich (BB code):
#include <msp430g2553.h>
#include <stdbool.h>
////////////////Defines////////////////
#define LED1        BIT6
#define LED0        BIT0
#define Error       BIT0
#define GND         BIT4
#define DAT         BIT5
#define DAT2	    BIT7////////////////////////////////////////////////////new
#define VCC         BIT0 //port P2.0
char buffer[4];
char buffer2[4];
float temp;
float temp2;
int r_temp,r_temp2;


////////////////Function Protos////////////////
void TX(char *tx_message);
static char *i2a(unsigned i, char *a, unsigned r);
char *itoa(int i, char *a, int r);

void ADC_init(void);
void ADC2_init(void);

static char *i2a(unsigned i, char *a, unsigned r)
{
    if (i/r > 0) a = i2a(i/r,a,r);
    *a = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[i%r];
    return a+1;
}

char *itoa(int i, char *a, int r)
{
    if ((r < 2) || (r > 36)) r = 10;
    if (i < 0)
    {
        *a = '-';
        *i2a(-(unsigned)i,a+1,r) = 0;
    }
    else *i2a(i,a,r) = 0;
    return a;
}

void TX(char *tx_message)
{
    unsigned int i=0; //Define end of string loop int
    char *message; // message variable
    unsigned int message_num; // define ascii int version variable
    message = tx_message; // move tx_message into message
    while(1)
    {
        if(message==0) // If end of input string is reached, break loop.
        {break;}
        message_num = (int)message; //Cast string char into a int variable
        UCA0TXBUF = message_num; // write INT to TX buffer
        i++; // increase string index
        __delay_cycles(10000); //transmission delay
        if(i>50) //prevent infinite transmit
        {
            P1OUT |= Error;
            break;
        }
    } // End TX Main While Loop
} // End TX Function

void TX2(char *tx_message2)
{
    unsigned int i=0; //Define end of string loop int
    char *message2; // message variable
    unsigned int message_num2; // define ascii int version variable
    message2 = tx_message2; // move tx_message into message
    while(1)
    {
        if(message2==0) // If end of input string is reached, break loop.
        {break;}
        message_num2 = (int)message2; //Cast string char into a int variable
        UCA0TXBUF = message_num2; // write INT to TX buffer
        i++; // increase string index
        __delay_cycles(10000); //transmission delay
        if(i>50) //prevent infinite transmit
        {
            P1OUT |= Error;
            break;
        }
    } // End TX Main While Loop
} // End TX Function



///////////////////////////////////////////////////////////////////////////////////////////////////
void ADC_init()
{
    /* Configure ADC  Channel */
    ADC10CTL1 = INCH_5 + ADC10DIV_3;         // Channel 5, ADC10CLK/4
    ADC10CTL0 = SREF_0 + ADC10SHT_3 + ADC10ON + ADC10IE;  //Vcc & Vss as reference
    ADC10AE0 |= BIT5;                         //P1.5 ADC option
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void ADC2_init()
{
    /* Configure ADC  Channel */
    ADC10CTL1 = INCH_7 + ADC10DIV_3;         // Channel 7, ADC10CLK/4
    ADC10CTL0 = SREF_0 + ADC10SHT_3 + ADC10ON + ADC10IE;  //Vcc & Vss as reference
    ADC10AE0 |= BIT7;                         //P1.7 ADC option
}
///////////////////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////MAIN PROGRAM LOOP//////////////////////////////////////////////////

void main(void)
{
	 	WDTCTL = WDTPW + WDTHOLD;         // Stop WDT
        BCSCTL1 = CALBC1_1MHZ;            // Set DCO to 1MHz
        DCOCTL = CALDCO_1MHZ;
        ////////////////USCI setup////////////////
        P1SEL = BIT1 + BIT2;            // Set P1.1 to RXD and P1.2 to TXD
        P1SEL2 = BIT1 + BIT2;            //
        UCA0CTL1 |= UCSSEL_2;            // Have USCI use SMCLK AKA 1MHz main CLK
        UCA0BR0 = 104;                  // Baud: 9600, N= CLK/Baud, N= 10^6 / 9600
        UCA0BR1 = 0;                  // Set upper half of baud select to 0
        UCA0MCTL = UCBRS_1;               // Modulation UCBRSx = 1
        UCA0CTL1 &= ~UCSWRST;             // Start USCI
        ////////////////General GPIO Defines////////////////
        P1DIR |= (LED1+GND+LED0);            //Define GPIOs as outputs else GPIOs are inputs
        P2DIR |=VCC;
        P1OUT =0;                     //All Outputs off except for Green_LED
        P2OUT|=VCC;
        P1OUT&=~GND;

while(1)
{
///////////////////SETUP ADC10 TO READ FROM CH A4 (P1.5)/////////////////////////////////////////////
	ADC_init();
//	__enable_interrupt();                     // Enable interrupts.
	int value=0;
///////////////////////////////Main Loop/////////////////////////////////////////////////////////////

	     	 __delay_cycles(1000);  // Wait for ADC Ref to settle
	         ADC10CTL0 |= ENC + ADC10SC;             // Sampling and conversion start
	         //__bis_SR_register(CPUOFF + GIE); //       // LPM0 with interrupts enabled
	         value = ADC10MEM;

	         temp=value*0.317;
	         r_temp=((temp*10)-10) * ((temp*10)/10);

	         itoa(temp, buffer, 10);
	         TX("External Temp:");
	         TX(buffer);
	         TX(".");
	         itoa(r_temp, buffer, 10);
	         TX(buffer);
	         TX(" Celsius\r\n");
	         P1OUT ^= LED0;

	     	 _delay_cycles(500000);
	     	 _delay_cycles(500000);
	     	 _delay_cycles(500000);
	     	 _delay_cycles(500000);

///////////////////SETUP ADC10 TO READ FROM CH A4 (P1.7)/////////////////////////////////////////////
	ADC2_init();
//	__enable_interrupt();                     // Enable interrupts.
	int value2=0;
///////////////////////////////Main Loop/////////////////////////////////////////////////////////////
	     				 __delay_cycles(1000);  // Wait for ADC Ref to settle
	     				 ADC10CTL0 |= ENC + ADC10SC;             // Sampling and conversion start
	     		        // __bis_SR_register(CPUOFF + GIE); //       // LPM0 with interrupts enabled
	     		         value2 = ADC10MEM;

	     		         temp2=value2*0.317;
	     		         r_temp2=((temp2*10)-10) * ((temp2*10)/10);

	     		         itoa(temp2, buffer2, 10);
	     		         TX2("Internal Temp:");
	     		         TX2(buffer2);
	     		         TX2(".");
	     		         itoa(r_temp2, buffer2, 10);
	     		         TX2(buffer2);
	     		         TX2(" Celsius\r\n");
	     		         P1OUT ^= LED0;

	     		     	_delay_cycles(500000);
	     		     	_delay_cycles(500000);



} //End while

} // End Main Program

// ADC10 interrupt service routine
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR (void)
{
  __bic_SR_register_on_exit(CPUOFF);        // Return to active mode
  P1OUT ^= LED1;
}
 

Thread Starter

ivaninspace

Joined Jul 28, 2013
10
Dear tshuck, I got my code to work by using these lines between each LM35 sampler block

ADC10CTL0 &= ~ENC; //disable so we can modify control bits
ADC10CTL1 &= 0x0FFF; //clear input source

Thank you very much for your time and knowledge, I really really really appropriate that man!!!!!!!!!!!!!!!!!!!
 
Top