UART HARDWARE CONNECTION PROBLEM

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

I am trying to serial communicate between Arduino and atmega8, in this code, I transmit 'a' from Arduino continuously and if I receive 'a' on atmega8 led will turn. I checked this program on Proteus it works fine but when I performed it on hardware it was not running. I used usbasp to program chip. Most simple Arduino code

void setup() {
  // put your setup code here, to run once:
  Serial.begin(4800);
}

void loop() {
 Serial.write('a');
 delay(100);
}

and this is atemga8 code

#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#define is_bit_set(byte,bit) (byte & (1<<bit))
#define is_bit_clr(byte,bit) (!(byte & (1<<bit)))
#define BUAD	4800
#define BRC		((F_CPU/16/BUAD) - 1)

int main(void)
{
	DDRD |= (1<<5);
	UBRRH = (BRC >> 8);
	UBRRL =  BRC;

	UCSRA &= ~(1 << U2X);
	UCSRB |= (1<<RXEN) | (1<<RXCIE);
	UCSRC |= (1<<UCSZ0) | (1<<UCSZ1);
	sei();
	while (1)
	{

	}
}
ISR(USART_RXC_vect)
{
	unsigned char x;
	x=UDR;
	if (x=='a')
	{
		PORTD |=(1<<5);
	}
	if (x=='b')
	{
		PORTD &= ~(1<<5);
	}
}

in hardware, I have connected pin 1 (tx) of Arduino to pin 2 (rx) of atmega8 apart from usbasp connections

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

Tips 2 & 3 ... ?

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

I bet your atmega8 does not have any Xal, making UART communications shaky, in the very best case (Proteus cannot simulate such things).

 

BTW, you should begin, with a new UART, by sending , say, 'a'(a PC terminal can display what it receives and is fully debugged), not by receiving

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

Hassan6432 wrote:
in hardware, I have connected pin 1 (tx) of Arduino to pin 2 (rx) of atmega8 apart from usbasp connections

Do they also have a common GND connection?

 

Your code looks right at first glance.  Note the default config for the usart is 8N1, to no need to configure UCSRC.

 

 

Mission: Improving the readiness of hams world wide : flinthillsradioinc.com

Interests: Ham Radio, Solar power, futures & currency trading - whats yours?

 

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

Further stuff on debugging serial comms:

 

https://www.avrfreaks.net/commen...

 

https://www.avrfreaks.net/commen...

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Internal RC clock is not accurate or stable enough for serial comms, you will need to connect an external xtal, caps and set the fuses for external xtal operation.

I would suggest one of the baud rate friendly xtal frequencies such as:   1.8432,  3.6864,  7.3728,  11.0592,  14.7456, or 18.4320 MHz

Mission: Improving the readiness of hams world wide : flinthillsradioinc.com

Interests: Ham Radio, Solar power, futures & currency trading - whats yours?

 

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

There is only 0.2% error on 4800 on 1Mhz

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

Yeah , i have common arduino gnd

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

Yeah your right i am not using external oscilater. But there is only 0.2% error . Between proteus show that kind of error (if i change my buad ratr to 9600 which cause 8.5% i will not get right character displayed on virtual terminal ).

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

Hassan6432 wrote:
There is only 0.2% error on 4800 on 1Mhz

You're missing the point.

 

That 0.2% error assumes that there is no error at all in the 1MHz.

 

The problem with using the internal RC is that there is quite likely to be a rather large error in the 1MHz - and that error will change quite a lot over temperature & voltage.

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Thu. Jun 14, 2018 - 01:43 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"Yeah your right i am not using external oscilater. "

Xal oscillator are inside (except for the Xal+ condensators) MCUS. OTOH, stable external oscillators are very expensive (can have a very pure Xal, be at constant temperature), more than a Xal/resonator (which is , anyway, more stable than an RC oscillator, avr's default).

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

The internal RC oscillator of the Mega8 series is perfectly fine for use with 4800 baud, especially if the devices are run at room temperature on a desktop.  I've never found internal variations of the RC oscillator in the AVR mega series to be great enough to distort UART communication at low baud rates.  I have had to adjust the OSCCAL register for the internal RC oscillator only when using 31.25K baud and receiving data blocks of a hundred-plus bytes that are being transmitted with no break or interval between the stop bit and the start bit of the next data byte. 

 

   We are too quick to blame internal RC variations for major problems in simple UART test programs. This is rarely the cause of the errors.  Most of the time, these errors are caused by UART mis-configuration or having the DIV/8 fuse set inadvertently.   And interrupts.   Don't use interrupts in your simple test code until you verify that your UART is sending and receiving correctly. 

 

  Configure the TX UART first by constantly sending 0x55 and verifying that a square wave is being output at 1/2 the baud rate.  Then verify that the TX from one AVR is going into the RX of the other AVR. Send the alphabet at one character per second from the TX AVR and verify with the serial monitor on the RX AVR that the alphabet characters are being received and processed correctly.  When the hardware works with the simplest possible test, then implement your TX and RX interrupts using ring buffers and head/tail pointers.

 

   And stop wasting your time on low-level AVR hardware interfacing.  Get a few $3 Arduino Nanos, and use the standard Arduino Serial.h, Wire.h, and SPI.h libraries.  Study the .ino application code, then study the library C++ code.  View the signals with a digital storage oscilloscope.  Get a $8 USB logic analyzer from eBay and download the operating code.  Practice using all these tools. 

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

Now I am using external oscillator of 11.0592MHz but it's not working. here's the code.

#define F_CPU 11059200UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>


#define is_bit_set(byte,bit) (byte & (1<<bit))
#define is_bit_clr(byte,bit) (!(byte & (1<<bit)))
#define BUAD	4800
#define BRC		((F_CPU/16/BUAD) - 1)


int main(void)
{
	DDRD |= (1<<5);
	UBRRH = (BRC >> 8);
	UBRRL =  BRC;
	
	UCSRA &= ~(1 << U2X);
	UCSRB |= (1<<RXEN) | (1<<RXCIE);
	UCSRC |= (1<<UCSZ0) | (1<<UCSZ1);
	sei();
	while (1)
	{
		
		
	}
}
ISR(USART_RXC_vect)
{
	unsigned char x;
	x=UDR;
	if (x=='a')
	{
		PORTD |=(1<<5);
	}
	if (x=='b')
	{
		PORTD &= ~(1<<5);
	}
}

 

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

Hassan6432 wrote:
but it's not working.
That's not a lot to go on!

 

If I were you I would forget interrupts and I would forget trying to receive until you have proven that the basic link is working OK. To do that simply try transmitting a repeated character with something like:

int main(void)
{
	UBRR =  BRC;

	UCSRB = (1 << TXEN);
	while (1)
	{
           while (!(UCSRA & (1 << UDRE))); // wait until we can send
           UDR = 'U';
	}
}

Some notes:

 

+ As the PD5 LED is not involved I removed the DDR setting

+ You don't need to split the write of UBRR as the compiler defines the symbol "UBRR" to access all 15 bits in one go.

+ UCSRA defaults to 0x00 so U2X is already 0 - no need to clear

+ In UCSRB I only set TXEN, to transmit nothing more is needed and I use '=' not '|='

+ There is no write to UCSRC for two reasons

    1) one you were doing it wrong, you HAVE to set the URSEL bit to access UCSRC otherwise you over-write UBRRH at the same address

    2) there is absolutely no need to write UCSRC anyway, datasheet says it powers on holding 0x06 (ignoring URSEL) so that is UCSZ1 and UCSZ0 already set anyway, 8N1 is the default

+ In the loop I just sit and wait while UDRE in UCSRA is not set, once it is then a character can be sent

+ I deliberately use 'U' to send. It has a useful property that with 8N1 framing it will give a constant 0101010101010101010 signal which is easily measured on scope, analyzer or frequency meter

 

PS in this whole thread:

UCSRC |= (1<<UCSZ0) | (1<<UCSZ1);

was always the problem. As I say UBRRH and UCSRC are at the same address so if you write to it and the top bit (URSEL) is not set the other 7 bits go into the top of UBRR. If you had wanted to write it then it had to be:

UCSRC = (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1);

and note that uses = not |=. Because of this URSEL thing you never want to do a "read modify write" to this register as the read actually reads back UBRRH first (it is actually very difficult to read UCSRC!)

Last Edited: Wed. Jun 20, 2018 - 02:34 PM