EmbeddedRelated.com
Forums

UART question

Started by hragsarkissian March 27, 2009
Hi guys,

I need some help. I am implementing a UART where i receive some bits from an RF receiver. The msp430 goes in LPM interrupt and waits until RXBUF receives something. Once it gets something, it will then proceed and follow the code. I would like to implement some sort of time out so that after, say 5 seconds if nothing happens then exit the interrupt and resume with the rest of the code. However, i am not sure on how to do this. Should I be using Timer A? If so, how would I implement this. Please help.
-------------Header File--------------------------
int receiveRF()
{
__bis_SR_register(LPM3_bits + GIE); // Enter LPM3, interrupts enabled
return UCA0RXBUF;

}

#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR()
{
_BIC_SR_IRQ(LPM3_bits + GIE); // Clear LPM3 bits from 0(SR)
}
--------------
-----------------Main File-------------------------
rcv = receiveRF();
-----------------------

Thanks,

Hrag

Beginning Microcontrollers with the MSP430

Considering your current code, it could look like this using TimerA;
-------------Initialiaziations--------------------------
//global data
unsigned char TimeoutCounter;

//Initialize TimerA0 to 1 second interrupt considering you have a ACLK
running at 32768khz on LFXT1
void InitTimerA (void)
{
//set CCR0 trigger
TACCCR0 = 32767;
//select timer A clock sourceACLK,
//and Upmode (Counts up to TACCR0 and gives an interrupt)
TACTL = TASSEL_1 | MC_1 ;
}
-------------Header File--------------------------
int receiveRF()
{
//reset counter
TimeoutCounter=0;
//enable TimerA interrupt
TACCTL0 |= (CCIE);
__bis_SR_register(LPM3_bits + GIE); // Enter LPM3, interrupts
enabled
//disable TimerA interrupt
TACCTL0 &= ~(CCIE);
//something different to return when timeout
if(TimeoutCounter>=5)
{
return 0xFFFF;
}
else
{
return UCA0RXBUF;
}
}

#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR()
{
//why are you disabling GIE after return?
_BIC_SR_IRQ(LPM3_bits + GIE); // Clear LPM3 bits from
0(SR)
}

#pragma vector=TIMERA0_VECTOR
__interrupt void TIMERA0_ISR(void)
{
if(++TimeoutCounter>=5)
{
//exit LPM after return
_BIC_SR_IRQ(LPM3_bits);
}
}
--------------
-----------------Main File-------------------------
rcv = receiveRF();
-----------------------

--


Thank you so much it worked! now what if i want to use with a 1 Mhz internal clock(no crystal), what would the parameters be?

--- In m..., Kaan Mertol wrote:
> Considering your current code, it could look like this using TimerA;
> -------------Initialiaziations--------------------------
> //global data
> unsigned char TimeoutCounter;
>
> //Initialize TimerA0 to 1 second interrupt considering you have a ACLK
> running at 32768khz on LFXT1
> void InitTimerA (void)
> {
> //set CCR0 trigger
> TACCCR0 = 32767;
> //select timer A clock sourceACLK,
> //and Upmode (Counts up to TACCR0 and gives an interrupt)
> TACTL = TASSEL_1 | MC_1 ;
> }
> -------------Header File--------------------------
> int receiveRF()
> {
> //reset counter
> TimeoutCounter=0;
> //enable TimerA interrupt
> TACCTL0 |= (CCIE);
> __bis_SR_register(LPM3_bits + GIE); // Enter LPM3, interrupts
> enabled
> //disable TimerA interrupt
> TACCTL0 &= ~(CCIE);
> //something different to return when timeout
> if(TimeoutCounter>=5)
> {
> return 0xFFFF;
> }
> else
> {
> return UCA0RXBUF;
> }
> }
>
>
> #pragma vector=USCIAB0RX_VECTOR
> __interrupt void USCI0RX_ISR()
> {
> //why are you disabling GIE after return?
> _BIC_SR_IRQ(LPM3_bits + GIE); // Clear LPM3 bits from
> 0(SR)
> }
>
> #pragma vector=TIMERA0_VECTOR
> __interrupt void TIMERA0_ISR(void)
> {
> if(++TimeoutCounter>=5)
> {
> //exit LPM after return
> _BIC_SR_IRQ(LPM3_bits);
> }
> }
> --------------
> -----------------Main File-------------------------
> rcv = receiveRF();
> -----------------------
>
> --
>
>

Hi

In a previous post I had the link to TI MSP4302xx UART library, it has the values for using different clocks and baud rates in the assembly code. I found the name of it: slaa307a.zip and pdf.

Regards,

- Tom



--- On Thu, 4/2/09, hragsarkissian wrote:
From: hragsarkissian
Subject: [msp430] Re: UART question
To: m...
Date: Thursday, April 2, 2009, 10:47 PM


Thank you so much it worked! now what if i want to use with a 1 Mhz internal clock(no crystal), what would the parameters be?

--- In msp430@yahoogroups. com, Kaan Mertol wrote:

>

>

> Considering your current code, it could look like this using TimerA;

>

>

> ------------ -Initialiaziatio ns------- --------- --------- -

> //global data

> unsigned char TimeoutCounter;

>

> //Initialize TimerA0 to 1 second interrupt considering you have a ACLK

> running at 32768khz on LFXT1

> void InitTimerA (void)

> {

> //set CCR0 trigger

> TACCCR0 = 32767;

> //select timer A clock sourceACLK,

> //and Upmode (Counts up to TACCR0 and gives an interrupt)

> TACTL = TASSEL_1 | MC_1 ;

> }

> ------------ -Header File-------- --------- ---------

> int receiveRF()

> {

> //reset counter

> TimeoutCounter= 0;

> //enable TimerA interrupt

> TACCTL0 |= (CCIE);

> __bis_SR_register( LPM3_bits + GIE); // Enter LPM3, interrupts

> enabled

> //disable TimerA interrupt

> TACCTL0 &= ~(CCIE);

> //something different to return when timeout

> if(TimeoutCounter> =5)

> {

> return 0xFFFF;

> }

> else

> {

> return UCA0RXBUF;

> }

> }

>

>

>

>

> #pragma vector=USCIAB0RX_ VECTOR

> __interrupt void USCI0RX_ISR( )

> {

> //why are you disabling GIE after return?

> _BIC_SR_IRQ( LPM3_bits + GIE); // Clear LPM3 bits from

> 0(SR)

> }

>

> #pragma vector=TIMERA0_ VECTOR

> __interrupt void TIMERA0_ISR( void)

> {

> if(++TimeoutCounter >=5)

> {

> //exit LPM after return

> _BIC_SR_IRQ( LPM3_bits) ;

> }

> }

> ------------ --------- --------- --------- --------- --

> ------------ -----Main File-------- --------- --------

> rcv = receiveRF();

> ------------ --------- --

>

>

>

>

>

> --

>

>



















Actually there are lots of possibilities to do this. What you use will change
according the implementation
of the whole program and others use of timers. So for our example we have
timer timerA free for our
operation, here is one way of doing this the actual logic is this:

-We change our clock source to SMCLK instead of ACLK using TASSEL_2
You have a clock at 1MHZ(1.048), so you can count at each clock tick 1
million times a second.
-Setting the clock divider to its maximum value 8 with ID_3 you can get a
125kHz clock input for TimerA
Now with your TACCRO setting at 32767 you roll over it ~4 times in a second.
125000/32678.
So you are getting interrupts at every 250 msecs. So for 5 seconds you
should set your count limit to
20 instead of 5.

Alternatively you can set TACCRO to 0xFFFF (65535) which is the maximum for
a 16bit register so now you can get 500msec interrupts.

----------------------
void InitTimerA (void)
{
TACCCR0 = 0xFFFF;
TACTL = TASSEL_2 | MC_1 | ID_3 ;
}
#pragma vector=TIMERA0_VECTOR
__interrupt void TIMERA0_ISR(void)
{
if(++TimeoutCounter>)
{
//exit LPM after return
_BIC_SR_IRQ(LPM3_bits);
}
}
---------------------

OR
you can set mode to up/down with MC_3 and set TACCRO to 0xFFFF so you have
a counter that
counts like 0->1->...->65535->65534->...->0->1->... , so you have doubled
your interval and with this you can get 1sec interrupts (65000x2~5000).
----------------------
void InitTimerA (void)
{
TACCCR0 = 0xFFFF;
TACTL = TASSEL_2 | MC_3 | ID_3 ;
}
#pragma vector=TIMERA0_VECTOR
__interrupt void TIMERA0_ISR(void)
{
if(++TimeoutCounter>=5)
{
//exit LPM after return
_BIC_SR_IRQ(LPM3_bits);
}
}
---------------------

--


hragsarkissian wrote:
> Hi guys,
>
> I need some help. I am implementing a UART where i receive some bits from an RF receiver. The msp430 goes in LPM interrupt and waits until RXBUF receives something. Once it gets something, it will then proceed and follow the code. I would like to implement some sort of time out so that after, say 5 seconds if nothing happens then exit the interrupt and resume with the rest of the code. However, i am not sure on how to do this. Should I be using Timer A? If so, how would I implement this.

Here is another thought.
Everything I've been doing is with a real time clock, or at the least,
clicks since the last time it talked to the box. And I don't think I
would trust SMCLK without using a 'Set_DCO' with a UART.

Anyway, I don't use the watchdog in a watchdog mode. I:
WDTCTL= WDT_ADLY_250; //One second/4 interrupts using watch crystal.
IE1= WDTIE; //enable the WD interrupt
~~~

And watch over counters in the interrupt for all my code. Right now I'm
bit banging a UART on an 1121 and kinda left it a hack while I wait for
some 2132s. I have this in the wd_interrupt:
(You may want to use WDT_ADLY_1000 and count to five? But...)

~~~
if( uart_wd_check )//there must be trouble
reset_uart( );

else if( ustate || TACTL & MC_1 )
++uart_wd_check;

~~~
My uart code keeps uart_wd_check reset and I should never have to hit
reset_uart( ). (And for several days I don't seem to have hit it!) But
if something goes wrong it will be less than a half second before I'm
back in business. And, I can only do that TACTL & MC_1 because I'm only
using the timer for the uart. If I were sharing the timer with MC_1 I
would have to do something else. But this chip is just 'for now' while I
develop other code.

Point being, by using the watchdog you don't have to give up your timer
resource. Also, you should never wait in an interrupt handler for
something to happen, you will regret it down the line. Do as little as
possible in the handler, set flags and handle stuff in your main loop. I
haven't used the USCI yet so don't know the right way.

Best, Dan.

--
email: y...@lakeweb.net but drop the 'x'.

Hi

I found these values for setting the bit counts for different baud rates and
clock frequencies.

//2Mhz
#define _2MHz_SMCLK_19200_Bitime 104
#define _2MHz_SMCLK_09600_Bitime 208
#define _2MHz_SMCLK_04800_Bitime 416
#define _2MHz_SMCLK_02400_Bitime 833

//1Mhz
#define _1MHz_SMCLK_19200_Bitime 52
#define _1MHz_SMCLK_09600_Bitime 104
#define _1MHz_SMCLK_04800_Bitime 208
#define _1MHz_SMCLK_02400_Bitime 416

#define Bitime _1MHz_SMCLK_02400_Bitime // bit length
#define Bitime_5 Bitime/2 // ~ 0.5 bit

I don't remember where I found these values, I thought it was from the TI
library code for TA_UART but couldn't find it when I looked again.

Hope these help.

- Tom

Nanoguy wrote:
>
> Hi
>
> In a previous post I had the link to TI MSP4302xx UART library, it has the
> values for using different clocks and baud rates in the assembly code.  I
> found the name of it: slaa307a.zip and pdf.
>
> Regards,
>
> - Tom
>
>  
>
> --- On Thu, 4/2/09, hragsarkissian wrote:
> From: hragsarkissian
> Subject: [msp430] Re: UART question
> To: m...
> Date: Thursday, April 2, 2009, 10:47 PM
>
>
>
>
>
>
>
>
>
>
>
>
> Thank you so much it worked! now what if i want to use with a
> 1 Mhz internal clock(no crystal), what would the parameters be?
>
>
>
> --- In msp430@yahoogroups. com, Kaan Mertol wrote:
>
>>
>
>>
>
>> Considering your current code, it could look like this using TimerA;
>
>>
>
>>
>
>> ------------ -Initialiaziatio ns------- --------- --------- -
>
>> //global data
>
>> unsigned char TimeoutCounter;
>
>>
>
>> //Initialize TimerA0 to 1 second interrupt considering you have a ACLK
>
>> running at 32768khz on LFXT1
>
>> void InitTimerA (void)
>
>> {
>
>> //set CCR0 trigger
>
>> TACCCR0 = 32767;
>
>> //select timer A clock sourceACLK,
>
>> //and Upmode (Counts up to TACCR0 and gives an interrupt)
>
>> TACTL = TASSEL_1 | MC_1 ;
>
>> }
>
>> ------------ -Header File-------- --------- ---------
>
>> int receiveRF()
>
>> {
>
>> //reset counter
>
>> TimeoutCounter= 0;
>
>> //enable TimerA interrupt
>
>> TACCTL0 |= (CCIE);
>
>> __bis_SR_register( LPM3_bits + GIE); // Enter LPM3, interrupts
>
>> enabled
>
>> //disable TimerA interrupt
>
>> TACCTL0 &= ~(CCIE);
>
>> //something different to return when timeout
>
>> if(TimeoutCounter> =5)
>
>> {
>
>> return 0xFFFF;
>
>> }
>
>> else
>
>> {
>
>> return UCA0RXBUF;
>
>> }
>
>> }
>
>>
>
>>
>
>>
>
>>
>
>> #pragma vector=USCIAB0RX_ VECTOR
>
>> __interrupt void USCI0RX_ISR( )
>
>> {
>
>> //why are you disabling GIE after return?
>
>> _BIC_SR_IRQ( LPM3_bits + GIE); // Clear LPM3 bits
>> from
>
>> 0(SR)
>
>> }
>
>>
>
>> #pragma vector=TIMERA0_ VECTOR
>
>> __interrupt void TIMERA0_ISR( void)
>
>> {
>
>> if(++TimeoutCounter >=5)
>
>> {
>
>> //exit LPM after return
>
>> _BIC_SR_IRQ( LPM3_bits) ;
>
>> }
>
>> }
>
>> ------------ --------- --------- --------- --------- --
>
>> ------------ -----Main File-------- --------- --------
>
>> rcv = receiveRF();
>
>> ------------ --------- --
>
>>
>
>>
>
>>
>
>>
>
>>
>
>> --
>
>>
>
>>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

--