Problem with USART receive and transmit data

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

Hi all, i was trying to do some practice with USART on a STK500, i have wrote a programme so that when i send a char 'a' in the terminal, the led on the stk500 will on, while i press the switch button 'SW0' on STK500 the terminal will give me an 'a'...

#include 
#include 

#define BAUD 9600

void USART_INIT(void)
{
	UCSRB |= (1<<RXEN) | (1<<TXEN) | (1<<RXCIE);
	UBRRL = (F_CPU/BAUD/16-1);
	UBRRH = (F_CPU/BAUD/16-1)>>8;
}

void receive_data(char rec_data)
{
 	while( (UCSRA & (1<<RXC))==0);
	
	switch(rec_data)
	{
	case 'a':
	PORTB ^= (1<<0);
	break;
	} 
}

void send_data(char send_data)
{		
	while( (UCSRA & (1<<UDRE))==0);
	UDR = send_data; 
}

void port_command(void)
{	
	if((PINA &(1<<0))==0)
	{
	PORTB ^= (1<<0);
	send_data('a');
	}
}

void system_init(void)
{
	DDRB = 0xff;
	DDRA = 0X00;
	PORTA = 0x00;
	sei();
}


int main(void)
{
	system_init();
	USART_INIT();
	
	while(1){
	port_command();
	}
}

volatile char rec_data;
SIGNAL(SIG_UART_RECV)
{
 rec_data = UDR;
 receive_data(rec_data);
}

I have found a problem that the program is not able to
transmit the char 'a' if the receive interrupt was called!! For example if i have send char 'a' to make the led on, then the switch button will not work again

can any1 help me with this?Thank You

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

Just step through in your own mind what you think will occur when the SIGNAL() is called (you shouldn't be using SIGNAL by the way - but the compiler already told you that and I presume you have some reason for ignoring what it told you?).

When a character arrives the RXC bit in the UART is set and as soon as it can the CPU will vector to SIG_UART_RECV which will lead to it entering the SIGNAL() you have provided above. At the top you read UDR which will then clear the RXC flag and then you call receive_data() where it does:

void receive_data(char rec_data) 
{ 
    while( (UCSRA & (1<<RXC))==0); 

so why are you blocking on the RXC bit when the receive has already occurred and you acknowledged it by reading UDR???

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

Thank you very much for answering my question, the problem have been solved by following your advise!

Regarding to the usage of SIGNAL .... can u tell me what is the problem? What should i use instead?

One last question, my original code is something like this, and it doesn't work! i don't understand why cant i do that (running the receive and transmit function in the same main)?

int main(void)
{
	system_init();
	USART_INIT();
	
	while(1){
	receive_data();
	port_command();
	}
}

void receive_data()
{
 	while( (UCSRA & (1<<RXC))==0);
	char rec_data = UDR;	

	switch(rec_data)
	{
	case 'a':
	PORTB ^= (1<<0);
	break;
	} 
}

Sorry for asking so many question! Thank You again!

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

Quote:

Regarding to the usage of SIGNAL .... can u tell me what is the problem? What should i use instead?

Use what the user manual tells you to use:

http://www.nongnu.org/avr-libc/u...

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

i really just started to learn AVR!So not very good as all!!Thank You very much for your help!!I learned one more thing today!

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

i have written a program to control 3 LED's using receive interrupt and here is my code:

#define F_CPU 8000000UL
#include <avr/io.h>
#include <avr/interrupt.h>

void usart_init();

int main(void)
{
    usart_init();
	DDRB=(1<<DDB0)|(1<<DDB1)|(1<<DDB2);
	sei();
    while (1);
}

ISR (USART_RXC_vect)
{
	PORTB^=(1<<PB2);

	uint8_t data=UDR;
	if (data==1)
		PORTB^=(1<<PB0);		

	if (data==2)
		PORTB^=(1<<PB1);
}

void usart_init(){
	UCSRB=(1<<RXCIE)|(1<<RXEN)|(1<<TXEN);//enable recieve & interrupt
	UCSRC=(1<<UCSZ0)|(1<<UCSZ1);//8N1
	UBRRH=0;
	UBRRL=12;//BAUD 38400
}

when i send '1' or '2' or any character PB2 blinks but PB0 and PB2 dont! 

what is the reason?

i use AtmelStudio Terminal window:

 

 

my second question is that why when "usart_init()" is executed, UCSZ0 & UCSZ1 remain zero?:

Last Edited: Wed. Nov 1, 2017 - 02:54 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

'1' does not equal 1;

try if (data == '1') ...

(google ASCII code)

David (aka frog_jr)

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

thanks

it worked!