Jump to content
Sign in to follow this  
qwert

MSP 430 Launchpad Timer UART

Recommended Posts

hey everyone,

 

so i have created a new topic so as to get my problem solved. here first of all i am writing down my previous post.....

here it is:

 

 

 

hey bluehash and NJC,

 

this is the same person that commented on your post on your forum QWERT. hey i am posting my code here.... kindly all do have a look and let me know the changes that i can made for reception and transmission using software UART (timer).

 

hey, i want to echo a character on the screen after inputting it from the keboard, thereafter i wanna use it to generate a morse code for the characters using a piezo electric buzzer. i am quite done with the morse code part , only thing that is screwing me up is this reception so as to make different operations on individual characters .kindly help me....

here is the code :

 

#include "msp430g2231.h"

#define TXD BIT1 // TXD on P1.1
#define RXD BIT2 // RXD on P1.2

// Conditions for 9600/4=2400 Baud SW UART, SMCLK = 1MHz
#define Bitime_5 0x05*4 // ~ 0.5 bit length + small adjustment
#define Bitime 13*4//0x0D 

unsigned int RXTXData;
unsigned char BitCnt;

void TX_Byte (void);
void RX_Ready (void);
void InitializeClocks(void);



void main (void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
CCTL0 = OUT; // TXD Idle as Mark
TACTL = TASSEL_2 + MC_2 + ID_3; // SMCLK/8, continuous mode// ACLK, continuous mode
P1SEL = TXD + RXD; //
P1DIR = TXD;
__enable_interrupt(); //
InitializeClocks();
// Mainloop
while (1)
{
// InitializeClocks();
RX_Ready(); // UART ready to RX one Byte
_BIS_SR(LPM3_bits + GIE); // Enter LPM3 w/ interr until char RXed
// RXTXData = (unsigned char)(75);

TX_Byte(); // TX Back RXed Byte Received
}
}


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


// Function Readies UART to Receive Character into RXTXData Buffer
void RX_Ready (void)
{
BitCnt = 0x8; // Load Bit counter
CCTL0 = SCS + OUTMOD0 + CM1 + CAP + CCIE; // Sync, Neg Edge, Cap
}
// Timer A0 interrupt service routine
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
CCR0 += Bitime; // Add Offset to CCR0

// TX
if (CCTL0 & CCIS0) // TX on CCI0B?
{
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 --;
}
}
// RX
else
{
if( CCTL0 & CAP ) // Capture mode = start bit edge
{
CCTL0 &= ~ CAP; // Switch from capture to compare mode
CCR0 += Bitime_5;
}
else
{
RXTXData = RXTXData >> 1;
if (CCTL0 & SCCI) // Get bit waiting in receive latch
RXTXData |= 0x80;
BitCnt --; // All bits RXed?
if ( BitCnt == 0)
{
CCTL0 &= ~ CCIE; // All bits RXed, disable interrupt
_BIC_SR_IRQ(LPM3_bits); // Clear LPM3 bits from 0(SR)
}
}
}
}


void InitializeClocks(void)
{

BCSCTL1 = CALBC1_1MHZ; // Set range
DCOCTL = CALDCO_1MHZ;
BCSCTL2 &= ~(DIVS_3); // SMCLK = DCO / 8 = 1MHz 
}

waiting for a positive response....

 

regards

qwert

Share this post


Link to post
Share on other sites

now, to answer some of my friends.....

 

Yes i am being very much successful in transmitting a character from launch pad to PC , even using interrupts .....

 

but in this case i want to get an input from keyboard to launchpad and retransmit that character from launchpad to make it display on screen using realterm or putty, what so ever.

 

so now , NJC, bluehash and my other friends kindly help me out doing this.

 

regards

QWERT

Share this post


Link to post
Share on other sites

Good. You made a new topic.

One more thing to learn is to choose a better section. This is for user introductions. Maybe the forum moderator can move this thread to a better section.

 

You can set echo on the terminal. Then you see what you type.

 

Also look into terminal escape sequenses. With those you can make all kind on nice stuff. Like UI or even games :)

Share this post


Link to post
Share on other sites

plazma,

 

i want to do a different task of producing morse code corresponding to each character when it is transferred from keyboard to microcontroller.....

 

so this is the basic concern, and character is not getting transferred to the microcontroller. this is the basic problem i am facing...

 

what say ?

Share this post


Link to post
Share on other sites

- Are your baud rates correct on both ends correct?

Try strating with a lower baud rate.

 

- Also try receiving characters only from PC to Launchpad first. Use your debugger breakpoints, to look at the RX registers.

 

- As plazma said, you can always use the echo on hyperterminal to look at the character last typed instead of transmitting it from Launchpad to PC.

Share this post


Link to post
Share on other sites

QWERT,

 

First make sure that your timing is correct when you check the pin to receive the bit. I haven't gotten a chance to look at your code in detail yet, but here is how I would debug it if I had more time.

 

First I would check your clock, make sure its at the frequency you expect. some multimeters can do a frequency measurement, oscilloscopes can, so can logic analyzers. if you dont have the tools, thats fine, lets hope your clock is correct.

 

second i would do your math on paper. make sure that you calculated the delay correctly for your clock frequency. how many counts does the timer need to do in order for the correct delay to happen? dont forget that your dividing the clock by 8 for the timer, which is already divided by 8 from the DCO. also, i recommend initializing the clocks right after you stop your WDT. its not good programming practice to do that after you set up your peripherals.

 

now for the RX_Ready , what do you want it to do? why do you call it in your main loop. what i think you are missing, is an interrupt on the RX pin. your RX pin should throw an interrupt on a downward slope change in state, (when it goes from 1 to 0), this would then start your timer to poll the RX pin at the correct interval.

 

I would recommend rewriting your receive code all together. make a new project where you are not transmitting anything. i recommend writing a project that receives one byte. once the byte is received turn on an LED, and set your debugger to break when that LED turns on, or your receiving is complete so you can check manually which byte was received.

 

hope that all made sense.

 

good luck.

 

-NJC

________________________________

http://msp430launchpad.blogspot.com

Share this post


Link to post
Share on other sites

HEY NJC,

 

i am using the following code now for only reception and the results are:

 

if i check a signal on the transmission line, it gives me a signal (toggle led) on the board. but if i try to identify the character, it is not helping me do that or it is not giving any signal.

 

Can you tell me what is the wrong that i am doing and how should i get it corrected.

 

here is the code:

 

#include "msp430g2231.h"

 

#define RXD BIT2 // TXD on P1.1

#define Bitime 104 //9600 Baud, SMCLK=1MHz (1MHz/9600)=104

#define Bitime_5 0x05*4

unsigned char BitCnt; // Bit count, used when transmitting byte

unsigned int RXByte; // Value sent over UART when Transmit() is called

 

// Function Definitions

void Receive(void);

 

void main(void)

{

WDTCTL = WDTPW + WDTHOLD; // Stop WDT

 

BCSCTL1 = CALBC1_1MHZ; // Set range,,,,,,,,,

DCOCTL = CALDCO_1MHZ; // SMCLK = DCO = 1MHz

 

P1SEL |= RXD; //

P1DIR |= RXD; //

 

__bis_SR_register(GIE); // interrupts enabled

 

while(1)

{

unsigned int a = RXByte;

Receive();

if(a == 0x80)

{P1DIR = 0x40;

P1OUT ^= 0x40;

}

 

if(P1IN & 0X04)

{}

else

{P1DIR = 0x01;

P1OUT ^= 0x01;

}}}

void Receive()

{

BitCnt = 0x8; // Load Bit counter

CCTL0 = SCS + OUTMOD0 + CM1 + CAP + CCIE; // Sync, Neg Edge, Cap

}

#pragma vector=TIMERA0_VECTOR

__interrupt void Timer_A (void)

{

 

CCR0 += Bitime; // Add Offset to CCR0

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

{

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

CCR0 += Bitime_5;

}

else

{

RXByte = RXByte >> 1;

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

{ RXByte |= 0x80;

BitCnt --; // All bits RXed?

}}}

 

 

regards

qwert

Share this post


Link to post
Share on other sites

Here's a complete stab in the dark... I noticed you're using P1.2, which is set to do TA0.1 mode. Does TA0.1 work off of CCR0, or CCR1? I'm still working out the details on Timer_A, but as I understand it, OUTx is changed when the timer hits TACCRx. Since you're timing with CCR0, it should change TA0.0, which is on P1.1. What happens if you try receiving on P1.1 instead? (That way you only need to change the header definition of RXD instead of changing the rest of the code.)

 

I'm also thinking that you might be having trouble with changing the P1 configurations; it looks like you use the two LEDs on P1.0 and P1.6 to signal Rx/Tx modes; setting P1DIR = 0x40 or 0x01 in those if statements resets your P1DIR on P1.2 set at the beginning of main(). I would set the P1 directions to their intended values right at the start, and then only toggle the output value in the if statements. You shouldn't ever have to change P1DIR in the middle of your code unless you really intend to change the function of a pin mid-run. Since these pins seem to never be used for anything else, just set them as outputs once at the beginning of the code.

Share this post


Link to post
Share on other sites

Another thought; 9600 isn't an even multiple of 1 MHz-- you might try a different baud rate with more accuracy at your calibrated frequency, say 10 kbps (or even 1kbps to start!). If the timings get off it can mess things up pretty well, and your actual timing frequency is more like 9615 baud (10 bits puts you out of sync by about 2 us). Maybe not much, but it might be enough to cause problems. If you have a terminal that can do non-conventional rates (like RealTerm) it may be better to get moving and debugged at an even multiple of your DCO frequency before figuring it out on a standard rate.

 

Edit: As I think about it, you need more than just the terminal to output the right rate if you're connecting through USB; I believe the FT232R handles non-standard rates just fine, but I'm not sure about the CP2102. How are you interfacing to your computer?

Share this post


Link to post
Share on other sites
CCR0 += Bitime; // Add Offset to CCR0
if( CCTL0 & CAP ) // Capture mode = start bit edge
{
CCTL0 &= ~ CAP; // Switch from capture to compare mode
CCR0 += Bitime_5;
}

 

Based on the code above, it looks like you are automatically adding Bitime to the counter, even if it is the first bit. In the case where it is the first bit you add Bitime and Bitime_5 to CCRO, I'm not sure if this is what you intended, but it could be causing some problems.

 

Keep updating us on your progress.

 

-NJC

_____________________________

http://www.msp430launchpad.com

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×