software uart-msp430

Hello,

Using software uart can we get the data from gpsmodule to msp430?is it possible? how?could u please send me the example code?

by

naz

You can download software UART code (it uses Timer A) from the TI web site.

Leon

hello,

i tried,but i’m receiving first character of gps module why?i want to receive entire string of gps module.

by

naz

Probably a bug in your code.

Leon

could u please correct,because i tried so many times,as per my knowledge i coundn’t find andy issues and bugs,could u please help on this.this is the code which i have tried

#include <msp430x14x.h>

#include<stdio.h>

#include<stdlib.h>

#define RXD 0x04 // RXD on P2.2

#define TXD 0x02 // TXD on P1.1

#define Bitime_5 104 // ~ 0.5 bit length

#define Bitime 208 // ~ 9615 baud

#define DELTA 488 // Target DCO = DELTA*(4096) ~2MHz

//static unsigned int RXTXData;

unsigned char BitCnt;

//char RXTXData;;

char temp;

unsigned int RXTXData;

void TX_Byte (void);

void RX_Ready (void);

void Set_DCO (void);

void main (void)

{

WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer

BCSCTL1 |= DIVA_3; // ACLK = LFXT1CLK/8

Set_DCO(); // Set DCO

CCTL0 = OUT; // TXD Idle as Mark

TACTL = TASSEL_2 + MC_2; // SMCLK, continuous mode

P1SEL = TXD; // P1.1/TA0 for TXD function

P1DIR = TXD; // TXD output on P1

P2SEL = RXD; // P2.2/TA0 as RXD input*/

P1DIR |= 0x08; // Power MAX3221

P1OUT |= 0x08;

P1SEL = 0x0C; // P1.1/TA0 for TXD function

P1DIR = 0xFF; // TXD output on P1

P2SEL = RXD; // P2.2/TA0 as RXD input

P2DIR=0x00;

P6SEL = 0x00; // Select P6 port as I/O

P6DIR = 0xFF; // Set P6 port to Output direction

P6OUT = 0x10;

while(1)

{

RX_Ready();

_BIS_SR(LPM3_bits + GIE);

TX_Byte();

}

}

void TX_Byte (void)

{

BitCnt = 0xA; // Load Bit counter, 8data + ST/SP

CCR0 = TAR; // Current state of TA counter

CCR0 += Bitime; // Some time till first bit

//temp = char( RXTXData);

printf(“%c”,RXTXData);

RXTXData |= 0x100; // Add mark stop bit to RXTXData

RXTXData = RXTXData << 1; // Add space start bit

CCTL0 = OUTMOD0 + CCIE; // TXD = mark = idle

while ( CCTL0 & CCIE ); // Wait for TX completion

}

void RX_Ready (void)

{

BitCnt = 0x8; // Load Bit counter

CCTL0 = CM_3+ CCIS0 + OUTMOD0 + CAP + CCIE; // Neg Edge, Cap

}

void Set_DCO (void) // Set DCO to selected frequency

{

unsigned int Compare, Oldcapture = 0;

CCTL2 = CM_1 + CCIS_1 + CAP; // CAP, ACLK

TACTL = TASSEL_2 + MC_2 + TACLR; // SMCLK, cont-mode, clear

while (1)

{

while (!(CCIFG & CCTL2)); // Wait until capture occured

CCTL2 &= ~CCIFG; // Capture occured, clear flag

Compare = CCR2; // Get current captured SMCLK

Compare = Compare - Oldcapture; // SMCLK difference

Oldcapture = CCR2; // Save current captured SMCLK

if (DELTA == Compare) break; // If equal, leave “while(1)”

else if (DELTA < Compare)

{

DCOCTL–;

if (DCOCTL == 0xFF) // DCO is too fast, slow it down

{

if (!(BCSCTL1 == (XT2OFF + DIVA_3)))

BCSCTL1–; // Did DCO role under?, Sel lower RSEL

}

}

else

{

DCOCTL++; // DCO is too slow, speed it down

if (DCOCTL == 0x00)

{

if (!(BCSCTL1 == (XT2OFF + DIVA_3 + 0x07)))

BCSCTL1++; // Did DCO role over? Sel higher RSEL

}

}

}

CCTL2 = 0; // Stop CCR2

TACTL = 0; // Stop Timer_A

}

#pragma vector=TIMERA0_VECTOR

__interrupt void Timer_A (void)

{

// unsigned int Compare, Oldcapture = 0;

CCR0 += Bitime; // Add Offset to CCR0

// RX

if (CCTL0 & CCIS0) // RX on CCI0B?

{

if( CCTL0 & CAP ) // Capture mode = start bit edge

{

CCTL0 &= ~ CAP; // Switch from capture to compare mode

CCR0 += Bitime_5;

_BIC_SR_IRQ(SCG1 + SCG0); // DCO reamins on after reti

}

else

{

RXTXData = RXTXData >> 1;

if (CCTL0 & SCCI) // Get bit waiting in receive latch

// RXTXData = RXTXData >> 1;

RXTXData |= 0x80;

BitCnt --;

if ( BitCnt == 0)

{

CCTL0 &= ~ CCIE; // All bits RXed, disable interrupt

_BIC_SR_IRQ(CPUOFF); // Clear LPM3 bits from 0(SR)

}

}

}

// TX

else

{

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

CCTL0 |= OUTMOD2;

}

/* else

{

CCTL0 &= ~ OUTMOD2;

RXTXData = RXTXData >> 1;

if (RXTXData & 0x01)

BitCnt --;

CCTL0 |= OUTMOD2;

}*/

}

}

hope i'll get good feedback.

by

naz

It depends on how good is your c-compiler and your hardware, this might work.

Add:

 char buffer[100], index;

And replace your existing code:

 while(1)
 {
  RX_Ready();
  _BIS_SR(LPM3_bits + GIE);
  TX_Byte();
 }

with the code:

 for (index=0; index<100, index++) 
 {
  RX_Ready();
  _BIS_SR(LPM3_bits + GIE);
  buffer[index] = RXTXData;
 }
 for (index=0; index<100, index++) 
 {
   RXTXDATA=buffer[index];
   TX_Byte();
 }

Just to elaborate on what Oldcow posted, that TI sample code is set up to receive one byte, then transmit it again. It can only handle receiving, or transmitting at one time, not both.

So, the code receives the first byte, but immediately goes on to transmit it back out the software UART, and as such can’t receive anymore characters until the transmit process is complete.

What you need to do is set up the code such that it receives all the data into an array, as Oldcow’s code does. Then once the entire array is received, you can start to process that data.

i tried what ever oldcow told,but it won’t enter into interrupt routine.As Roko said,i didn’t do anything to receive entire string from gps module.Any specifice settings is there to receive the string?

by

naz

Naz, the code OldCow posted was set up to receive a string 100 byte long string into an buffer array.

You may need to tweak the code to receive only a set number of characters in your GPS packet. Try reducing the number in “index<100” to the number of bytes you are expeting in the packet from your GPS.

Or, Maybe instead of a for loop as OldCow posted, you could try a loop that will receive bytes into the buffer until you get an end of packet character (e.g. a Carriage Return/Line Feed if you’re trying to receive NMEA data).

It’s not a very difficult task, but it does require a little bit of familiarity with C programming.

Thank you very much oldcow,leon_heller and Roko.Now my project is working fine.thank you for your’s guidance.i did small modication, which oldcow told and comapre mode settings that’s all.

some issues

main program:


while(1)

{

for (index=0;index<76;index++)

{

RX_Ready();

_BIS_SR(LPM3_bits+GIE);

buffer[index] = RXTXData;

}

for (index=0; index<76;index++)

{

RXTXData =buffer[index];

TX_Byte();

}

}

}

}

1.Here 76 indicates number of characters in one string (one line)

(ex:$GPGGA,084033.99,1257.5942,N,07738.7581,E,1,05,01.7,00913.4,M,-088.4,M,*4E )

2.The problem is ,now the stringlength is known by user,but in real time we dosen’t know how many strings will come.

3.so i think we have to write a code to carriage return or line feed or EOF.

4.could u please send me the example code to carriage return or line feed

or EOF but don’t use UART,because we are using Software UART only .could you please guide on this?

by

naz

Roko:
Naz, the code OldCow posted was set up to receive a string 100 byte long string into an buffer array.

You may need to tweak the code to receive only a set number of characters in your GPS packet. Try reducing the number in “index<100” to the number of bytes you are expeting in the packet from your GPS.

Or, Maybe instead of a for loop as OldCow posted, you could try a loop that will receive bytes into the buffer until you get an end of packet character (e.g. a Carriage Return/Line Feed if you’re trying to receive NMEA data).

It’s not a very difficult task, but it does require a little bit of familiarity with C programming.

how to write a code to carriage return without using UART,because here we are using software uart.

Hello. I’m ORHAN. I live in TURKEY. I am sorry bad my English

I making now this project for MCU-TURKEY.

This application can be found here.

GPS with Global Position

http://www.mcu-turkey.com/?p=1938

Good days…

www.veriloghdl-fpga.blogspot.com