UART new line issue

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

HI,

I have a simple code that receives and transmits string through UART. I use ATMEGA 168.

So according to my code I transmit a string using cool term and the controller receives it.The controller the compares the string .If the strings match then the controller sends back  "K" , which will be displayed in the cool term.

If the strings don't match the controller sends back"AT" followed by  carriage return and new line.

But when I execute the code and if the strings don't match it returns back "AT";but I do not get a new line.It prints "AT" continuously.

#include <avr/io.h>
#include <string.h>
#include <util/delay.h>

#define F_CPU 8000000UL
#define BAUD 9600
#define MYUBBR F_CPU/16/BAUD-1

void uart_init(unsigned int ubrr)
{
	// Setting the baud rate to ubrr
	UCSR0A = 0<<U2X0;
	UBRR0H = (unsigned char)(ubrr >> 8);
	UBRR0L = (unsigned char)ubrr;
	//Setting the frame format to 8 data bit, no parity bit, 1 stop bit
	UCSR0C = 3<<UCSZ00;
	UCSR0B = (1<<TXEN0)|(1<<RXEN0);
}

void USART_Transmit( unsigned char data )
{
	while (!(UCSR0A & (1<<UDRE0)));
	UDR0 = data;
}

unsigned char USART_Receive()
{
	while (!(UCSR0A & (1<<RXC0)));
	return UDR0;
}

void transmit_string(char* data)
{
	int i;
	for (i=0;data[i] != '\0';i++)
	{
		USART_Transmit(data[i]);
	}
}

void receive_string(char* dat)
{
	char command[4];
	command[0] = '\0';
	command[1] = '\0';
	command[2] = '\0';
	command[3] = '\0';
	int index = 0;
	while ((command[2] != 0x0D) && (command[3] != 0x0A))
	{
		dat
= USART_Receive(); index += 1; if (index > 3) { command[0] = dat[index - 4]; command[1] = dat[index - 3]; command[2] = dat[index - 2]; command[3] = dat[index - 1]; } } dat[index-2] = '\0'; } int main(void) { // Setting system clock to 8MHz CLKPR = (1 << CLKPCE); CLKPR = 0; uart_init(MYUBBR); while(1==1) { char dat[10]; receive_string(dat); if(strcmp(dat,"OK")==0) { UDR0='k'; } else { char data[]="AT"; transmit_string(data); UDR0='\r'; UDR0='\n'; _delay_ms(1000); } } }

Kindly point out the mistake .

This topic has a solution.
Last Edited: Fri. Sep 15, 2017 - 08:23 AM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

When transmitting the '\r' and '\n' you are not waiting for UDRE0 to clear. Fix by calling USART_Transmit() rather than explicitly assigning UDR0 in main(). 

Happy 75th anniversary to one of the best movies ever made! Rick Blane [Bogart]: "Of all the gin joints, in all the towns, in all the world, she walks into mine."

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

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

Have you checked what your terminal actually transmits for "newline" ?

 

Most terminals are configurable as to what they send when you press the "enter" or "return" key - CR, LF, CRLF, etc ...

 

Also, some implementations of stdio will do similar translations.

 

Also, most terminals are configurable as to how they will handle incoming CR and LF ...

 

The ATMEGA 168 has on-chip debug - use it to step through the code and see what's actually happening

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

@awneil: I believe this is a case of overrunning UDR0, ie a timing problem. If I'm right then debugging and single-stepping will alter/diguise the faulty behaviour. Agree? 

Happy 75th anniversary to one of the best movies ever made! Rick Blane [Bogart]: "Of all the gin joints, in all the towns, in all the world, she walks into mine."

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

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

JohanEkdahl wrote:
 If I'm right then debugging and single-stepping will alter/diguise the faulty behaviour. Agree? 

Agree!

 

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

Geeth wrote:

			char data[]="AT";
			transmit_string(data);
			UDR0='\r';
			UDR0='\n';

 

Apart from the error that Johan's already pointed out,  why would you not simply do

			char data[]="AT\r\n";
			transmit_string(data);

 

(someone will be along soon to explain about putting constant strings in Flash...)

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

Thank you that worked.It was overrunning  problem .

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

A note on style.

 

You have:

void uart_init(unsigned int ubrr)

void USART_Transmit( unsigned char data )

unsigned char USART_Receive()

void transmit_string(char* data)

 

The key to good programming style - whatever style you choose - is to Be Consistent!

 

You have four USART-related functions:

 

  • two of them are prefixed "USART_"
  • one of them is prefixed "uart_"
  • one of them has no prefix at all!

 

EDIT

 

typo

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

Thank you for sharing this knowledge :-)

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

You're welcome.

 

Did you get the point about including the "\r\n" in your string - rather that sending them as separate individual characters?

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

yes it would optimize my code 

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

Hi,

In the above mentioned code if I make a slight change that is add transmit(commented it below) before receive , the program does not transmit when I connect it to cool term.It waits until it receives a message and then transmits.Why doesn't it transmit first and receive next as it is the flow in my program?Kindly point out the mistake

int main(void)
{
	
	// Setting system clock to 8MHz
	CLKPR = (1 << CLKPCE);
	CLKPR = 0;
	uart_init(MYUBBR);
	while(1==1)
	{
		char dat[10];
		transmit_string("AVR");//transmit AVR
		receive_string(dat);

		if(strcmp(dat,"OK")==0)
		{
			UDR0='k';
		}
		else
		{
			char data[]="AT";
			transmit_string(data);
			UDR0='\r';
			UDR0='\n';
			_delay_ms(1000);
		}
	}
}

 

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

New question = new thread.

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

Oh OK , I will create a new topic:-)

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

Give a link once you've created it.

 

If you need to reference this thread in the new one, you can also include a link there.

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

link  for the new thread:   http://www.avrfreaks.net/forum/u...