usart question/problem

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have been working thru the tutorials on Usart with and without interrupts.

I have the following code:

#include 
#include 
#include  

#define USART_BAUDRATE 4800
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1) 

int uart_initiate(void);
int uart_putc(char c, FILE *stream);

unsigned char uart_rec;

FILE uart_str = FDEV_SETUP_STREAM(uart_putc, NULL, _FDEV_SETUP_WRITE);

int main (void)
{
	//Initiate Port A for output and set to high (on stk500 led's are "active low")
	DDRA = 0xff;
	PORTA = 0x00;
	

	uart_initiate();

	stdout = &uart_str;
	
	UCSRB |= (1 << RXCIE);
	sei();
	
	uart_rec = '2';

	for (;;) // Loop forever
	{
		if(uart_rec == '1')
		{
			printf("%:c \n", uart_rec);
			printf("Hello world!\n"); 
			uart_rec = '2';
		}
	}   
}
//Initiate uart
int uart_initiate(void)
{
	UCSRB |= (1 << RXEN) | (1 << TXEN);   // Turn on the transmission and reception circuitry
	UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1); // Use 8-bit character sizes

	UBRRH = (BAUD_PRESCALE >> 8); // Load upper 8-bits of the baud rate value into the high byte of the UBRR register
	UBRRL = BAUD_PRESCALE; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register
	return 0;
}
/*
***************************
*/
//Put function
int uart_putc(char c, FILE *stream)
{

   if(c == '\n')
   {
   
      uart_putc('\r', stream);
      
   } //end if

   loop_until_bit_is_set(UCSRA, UDRE);

   UDR = c;
   
   return 0;

} 

//Receive interrupt
ISR(USART_RXC_vect)
{
	char ByteRec;
	uart_rec = UDR; // Fetch the received byte value into the variable "uart_rec"
	ByteRec = uart_rec;
	UDR = ByteRec; //echo the caracter received
	PORTA ^= 0xff; // Toggle all leds on Port A
} 

When I connect my stk500 to a serial port and send any character (including a "1" (without quotes)), the LEDs toggles on and off and the character echos (as would be expected based on the code in the interrupt routine). But if I enter "1" (again, without quotes), neither of the "printf" statements in the if block execute.

However if I modify the code to add an "else" block after the "if" block as follows:

	for (;;) // Loop forever
	{
		if(uart_rec == '1')
		{
			printf("%:c \n", uart_rec);
			printf("Hello world!\n"); 
			uart_rec = '2';
		}
		else
		{
			printf("%:c \n", uart_rec);
		}
	}   

Then the terminal on my laptop will print a continuous stream of "2"s until I enter another character, in which case it prints that character. If I enter a "1", both "printf" statements are executed, after which the continuous stream of "2"s returns.

Why does the "else" block cause the code in the "if" block to execute? What am I missing?

Russ

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

gatoruss wrote:
What am I missing?
A "volatile".

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

More specifically, uart_rec must be declared volatile.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the quick replies.

Cliff, your link was very helpful...not sure I understood all of it, but I think that I at least followed the portion relevant to my issue.

Looking at the first FAQ in Cliff's signature reminds me that I should have looked thru the FAQs before posting. :oops:

Russ