NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Microcontroller Programming » Interrupt driven USART comms, problem when passing received char

April 03, 2011
by jeuhrn
jeuhrn's Avatar

This is how I have my interrupt routine set up:

ISR(USART_RX_vect) 
{ 
   y++;
   char ReceivedByte; 
   ReceivedByte = UDR0; // Fetch the recieved byte value into the variable "ByteReceived" 
   ctrl_chr(ReceivedByte);
   lcd_goto_position(3,0);
   lcd_write_int16(y);
   //lcd_write_data(ReceivedByte);
   //UDR0 = ReceivedByte; // Echo back the received byte back to the computer 
}

y is basically just a counter that lets me know the connection is alive. ctrl_chr() is supposed to check for certain control characters I know are in the strings I'm passing, the basics of it looks like this:

int ctrl_chr(char ctrlchr){
lcd_goto_position(2,0);
lcd_write_data(ctrlchr);
return 0;
}

And the ctrlchr character is just junk.

Am I missing something fundamental here?

April 04, 2011
by Ralphxyz
Ralphxyz's Avatar

I think you need to give us more detail. What exactly is your problem. What is not happening, when, where?

Is it a problem compiling or running or what.

Hopefully with more details you will get an answer.

Ralph

April 04, 2011
by bretm
bretm's Avatar

If you're saying you're receiving garbage characters, first I'd strip down the interrupt routine to the minimum--just echo back and do nothing else. Until you get that working, everything else just confuses the issue.

I definitely wouldn't do anything with the LCD inside a USART interrupt routine. You need the interrupt to get in and out very fast, and the LCD routines are relatively slow. If the ISR doesn't go fast enough you will lose data. I would just have the interrupt put the data somewhere where the main routine could get to it and have the main routine do the LCD stuff.

April 05, 2011
by jeuhrn
jeuhrn's Avatar

It echo's back, that works fine. I've taken it all out and started trying to implement some ring buffer routines from Dean on avrfreaks forums. Babysteps. =)

April 05, 2011
by jeuhrn
jeuhrn's Avatar

Ok, I think I'm on to something here. There's nothing junky about the USART, there is however something funky about writing to the LCD.

These are my control characters

static uint8_t ctrlchars[] = { 'T', 'G', 'D', 'R', 'P', '#' };

This is just a sample function that i have looping while(1) in my main() right now to test this

int ctrl_chr(uint8_t data){
int i=0;
lcd_goto_position(3,0);
lcd_write_data(ctrlchars[i]);
for (i=0;i <5;i++){
        lcd_goto_position(1,i);
        lcd_write_data(ctrlchars[i]);
        lcd_goto_position(2,i);
        lcd_write_data(ctrlchars[1]);
    }
return 0;
}

This generates the output

$$$$$ (the signs are square black ASCII blocks on the LCD)
GGGGG
T (this is produced by the lcd_write_data() outside the for loop.)

Meaning that outside the loop I can read the i'th position of my array and write it to the LCD, inside the loop this produces junk, meanwhile the lcd_goto_position() function manages to make sense of the incrementing variable.

Is there any reason why using the incrementing variable in the for loop should produce garbage characters, while directly referencing the char array with an integer works?

April 05, 2011
by bretm
bretm's Avatar

Yes, there is a reason. See this thread for the background.

Post a Reply

Please log in to post a reply.

Did you know that you need to think about wires differently when you're transmitting signals more than a few inches? Learn more...