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.

URGENT: SOFT UART-temperature sensor

Hi,
The code given below is to measure the value of internal temperature sensor of MSP430G2231 and communicate with the PC via software UART.
When I run the code I get the value of TXByte (highlighted in yellow)  on the terminal display window(PUTTY).
Please explain how and why only this value(TXByte) is transferred.
I am unable to understand how it is linked with P1.1 or P1.2.
what value is transferred in soft UART?
And moreover I am not getting the desired display.Its showing some random series of ascii symbols shown below: 
×
Ø

------------------------------------------------------------------------------------------------------
#include "msp430g2231.h"
#include "intrinsics.h"
#define TXD BIT1 // TXD on P1.1
#define RXD BIT2 // RXD on P1.2
#define Bitime 13*4 // 0x0D
unsigned int TXByte;
unsigned char BitCnt;
volatile long tempSet = 0;
volatile int i;
unsigned int TxHI[]={0x48,0x49};
unsigned int TxLO[]={0x4C,0x4F};
unsigned int TxIN[]={0x49,0x4E};

#ifndef TIMER0_A1_VECTOR
#define TIMER0_A1_VECTOR TIMERA1_VECTOR
#define TIMER0_A0_VECTOR TIMERA0_VECTOR
#endif

volatile long tempRaw;
void Transmit(void);

void FaultRoutine(void);
void ConfigWDT(void);
void ConfigClocks(void);
void ConfigPins(void);
void ConfigADC10(void);
void ConfigTimerA2(void);

void main(void)
{
ConfigWDT();
ConfigClocks();
ConfigPins();
ConfigADC10();
ConfigTimerA2();

while(1)
{
_bis_SR_register(LPM3_bits + GIE);
if (tempSet == 0)
{
tempSet = tempRaw; // Set reference temp
}
if (tempSet > tempRaw + 5) // test for lo
{
P1OUT = BIT6; // green LED on
P1OUT &= ~BIT0; // red LED off
for (i=0;i<2;i++)
{
TXByte = TxLO[i];
Transmit();
}
}
if (tempSet < tempRaw - 5) // test for hi
{
P1OUT = BIT0; // red LED on
P1OUT &= ~BIT6; // green LED off
for (i=0;i<2;i++)
{
TXByte = TxHI[i];
Transmit();
}
}
if (tempSet <= tempRaw + 2 & tempSet >= tempRaw - 2)
{ // test for in range
P1OUT &= ~(BIT0 + BIT6); // both LEDs off
for (i=0;i<2;i++)
{
TXByte = TxIN[i];
Transmit();
}
}
}
}

void ConfigWDT(void)
{
WDTCTL = WDT_ADLY_250; // <1 sec WDT interval
IE1 |= WDTIE; // Enable WDT interrupt
}


void ConfigClocks(void)
{
if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF)
FaultRoutine(); // If calibration data is erased
// run FaultRoutine()
BCSCTL1 = CALBC1_1MHZ; // Set range
DCOCTL = CALDCO_1MHZ; // Set DCO step + modulation
BCSCTL3 |= LFXT1S_2; // LFXT1 = VLO
IFG1 &= ~OFIFG; // Clear OSCFault flag
BCSCTL2 |= 0;
}

void FaultRoutine(void)
{
P1OUT = BIT0; // P1.0 on (red LED)
while(1); // TRAP
}

void ConfigPins(void)
{
P1SEL |= TXD + RXD; // P1.1 & 2 TA0, rest GPIO
P1DIR = ~(BIT3 + RXD); // P1.3 input, other outputs
P1OUT = 0; // clear outputs
P2SEL = ~(BIT6 + BIT7); // make P2.6 & 7 GPIO
P2DIR |= BIT6 + BIT7; // P2.6 & 7 outputs
P2OUT = 0; // clear outputs
}

void ConfigADC10(void)
{
ADC10CTL1 = INCH_10 + ADC10DIV_0; // Temp Sensor ADC10CLK
}

void ConfigTimerA2(void)
{
CCTL0 = OUT; // TXD Idle as Mark
TACTL = TASSEL_2 + MC_2 + ID_3; // SMCLK/8, continuous mode
}

#pragma vector=WDT_VECTOR
__interrupt void WDT(void)
{
ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON;
_delay_cycles(5); // Wait for ADC Ref to settle
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start

_delay_cycles(100);
ADC10CTL0 &= ~ENC; // Disable ADC conversion
ADC10CTL0 &= ~(REFON + ADC10ON); // Ref and ADC10 off
tempRaw = ADC10MEM; // Read conversion value


_bic_SR_register_on_exit(LPM3_bits);
}

void Transmit()
{
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
TXByte |= 0x100; // Add mark stop bit to TXByte
TXByte = TXByte << 1; // Add space start bit
CCTL0 = CCIS0 + OUTMOD0 + CCIE; // TXD = mark = idle
while ( CCTL0 & CCIE ); // Wait for TX completion
}

// Timer A0 interrupt service routine
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A (void)
{
CCR0 += Bitime; // Add Offset to CCR0
if (CCTL0 & CCIS0) // TX on CCI0B?
{
if ( BitCnt == 0)
{
CCTL0 &= ~ CCIE ; // All bits TXed, disable interrupt
}
else
{
CCTL0 |= OUTMOD2; // TX Space
if (TXByte & 0x01)
CCTL0 &= ~ OUTMOD2; // TX Mark
TXByte = TXByte >> 1;
BitCnt --;
}
}
}

Thanks
  • Salony,

    TXByte is the vairable container that holds the value to transmit and that is currently being transmitted. The reason you cant read what it being sent is that ascii is a very limited character set.

    Lets say for example the value you want to transmit is 0x01. If you look at the ascii table, 0x01 does not relate to a readable character. If you add a '0' to your value, then you will receive the expected results.

    Look at this table here: http://www.asciitable.com/

    If you look at the table, the ascii value of '1' is 0x31, and not 0x01. So by adding either 0x30 or '0' to your value, you will get the expected result in your window.

    Also, you may find it beneficial to add a carrage return/new line feed to your array so that you dont get the a continious string of data.  You can do this by adding a '\r' and the na '\n' to your array.

    Or add some sort of deliminator charactor so that you can tell the samples apart.

     -Jason

  • Thanks Jason

    How will I know that the value to be transmitted is stored in TXByte??

    I am not writing anything in the code which tells that the value to be transmitted is stored in TXByte.I am just transferring the data to TXByte variable but I dont know how this value is actually transmitted.Can you please tell me how  does soft UART  actually works?

    unsigned int TxHI[]={0x48,0x49};
    unsigned int TxLO[]={0x4C,0x4F};
    unsigned int TxIN[]={0x49,0x4E};
    I have written the hex code for the ascii value to be transmitted but I am not getting the required output.Instead I am getting random symbols.
    Please Help.
    Thanks
  • Salony,

    Once you load a value into TXByte, and then call the transmit function, that value gets sent out via the software UART.

    TXByte = TxIN[i];

    Transmit();

    In this case you are loading TXByte with the vlaue that is in the Array index of i.

    I am not sure I follow what you mean when you say:

    "I am not writing anything in the code which tells that the value to be transmitted is stored in TXByte"

    You are loading a value into TXByte in the statement that I copied:

    TXByte = TxIN[i];

    A much simpler test would be to break down the project and get a clear under standing of how ths Software UART works. Why not create a new project, and in the main do something like tthis:

    TXByte = 'a';

    Transmit();

    Work with this project until you get consistant letter a's comming over the software UART. also, make sure you are setting the com port to 9600 when you establish connection on the PC side of things.

    -Jason

     

  • Hi Jason,

    I understand this part that after trasferring the value to TXByte and calling the transmit function.

    But, in the transmit function,  I don't  understand how TXByte is connected to P1.1(TXD pin).

    For example if I take another variable Txb and give a value to it say txb='a' in the transmit function then will this value be transmitted?

    I am not understanding the connection.

    Thanks

  •  Hi Salony, you need a basic course on programming and interrupt service theory.

     When transmit add the start and stop bit on TX byte then program the timer to compare, this generate interrupt at regular interval, on that interrupt txbyte decide to seto timer output mode to set pin to 0 or 1 following the last bit of txbyte. This code is transmitter and no explicit link to pin exist than setting output mode on timer.

    CCTL0 |= OUTMOD2; // TX Space
    if (TXByte & 0x01)
    CCTL0 &= ~ OUTMOD2; // TX Mark
    TXByte = TXByte >> 1;
    BitCnt --;

    Regards
  • If you cunsult the familiy-manual from your chip, you can see the description of all regeisters in timer module. be careful only to consult descriptions that apply to your chip. so you always need both documents. Chip-related and family-related. but with this information, you can see, that the timer-module can perform actions on some of the ports. there is no POUT needed as long the pin's state is ruled by timer. every time the interrupt is fired, a new pin action can take place on the output. in interrupt, you prepare the next action that will take place on TX pin in next interupt. this way, data is serialized bit by bit, every time the interrupt occurs. of course, it is also possible to change the pin manually in interrupt. this is the solution if you want to use other pins for tx, not included in the set of pins which timer can handle with its OUTMODE-feature.  in this case, your tx is not that accurate because c-code can give a non-constant delay which is seen as jitter on your tx-pin. (slow down baudrate in this case may help.) so best solution is always let the timer change out-Pin for tx itself. tx byte set in main is shifted bit by bit, each time interrupt occurs. only when whole byte is transmitted, tx is ready to accept next byte. if you change value of tx too fast (when still in use by tranmitter), you get unexpected results. may this be the case in your code?

    hope that helps a little.

    cheers, Matthias

     

**Attention** This is a public forum