USART0 on atmega328

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

Hello guys, i know i'm not the first to have problems with getting infromation over from the AVR to a computer but i stil cant seem to get it right.

I'v already read through the torturial but sadly it was of little help. I guess its proberbly just a small misunderstanding somwere but i'm starting to run out of ideas.

 

 

 

 

For the hardware i'm actually programming through the Arduino Uno(16Mhz and atmega 328p), and the code i as showne.

 

 

#include <avr/io.h>

#include <util/delay.h>

 

 #define F_CPU 16000000

 #define BAUD 9600

 #define BRC ((F_CPU/(16*BAUD)) - 1)

 

 char TXbyte;

 char RXbyte;

 

 void initz_transmitter(){

 

UBRR0H = (BRC >> 8);

UBRR0L = BRC;

 

UCSR0B |= (1 << TXEN0);

UCSR0C |= (1 << UCSZ00) | (1 << UCSZ01);

 }

 

 void initz_transmitter2(){

UBRR0H = (BRC >> 8);

UBRR0L = BRC;

 

UCSR0B |= (1<<TXEN0)|(1<<RXEN0);

UCSR0C |= (1<<UCSZ00)|(1<<UCSZ01);

 }

 

 void loop_back(){

  while(UCSR0A & (1 << RXC0)){

  RXbyte = UDR0;

  }

 

  while((UCSR0A & (1 << UDRE0))==0){

  UDR0 = TXbyte;

}

 

RXbyte =TXbyte;

 }

 

 void send_char(){

UDR0 = 'g';

_delay_ms(10000);

 }

 

int main(void)

{

initz_transmitter2();

 

    /* Replace with your application code */

    while (1) 

    {

send_char();

    }

}

Last Edited: Sat. Jul 29, 2017 - 02:53 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What does the datasheet say about 1MHz and 9600 baud?  IIRC it shows an 8% error, too much for reliable comms.

In order for serial usart comms to work, you should have an accurate and stable clock source, most of us use a xtal for that, as the internal RC wanders too much with voltage and temperature.

BTW, this is the number one question about serial comms we get here. 

How are you connecting the tx/rx pins from the MPU to your computer?  USB-ttl adapter, or USB-RS232?

 

Jim

 

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

Oletl wrote:
For the hardware i'm actually programming through the Arduino Uno(16Mhz and atmega 328p),
What do you mean with "programming through"? Is the Arduino used as a programming adapter, or is it the hardware the program is running on?

#define BAUD 9600
#define BRC ((F_CPU/(16*BAUD)) - 1)

The 16*BAUD will overflow. Change it into 16UL*BAUD.

 

Stefan Ernst

Last Edited: Sat. Jul 29, 2017 - 01:41 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry people the F_CPU is 16 000 000(i'v been messing with it when it dident work)!

 

ki0bk

The 16MHz should make it a little more accurrate and i was expecting atleast some ok transferes even if it's got 8% error rate.

Sadly my terminology is not the best and i proberbly cant awnser your question werry good, but its connected from the computer to the arduino with a usb B.

 

 

sternst

I'm not realy sure of the difference but i'm using the arduino as harwere and atmel stuidos as an IDE.(Do it awnser the question?)

Dose it matter if the 16*BAUD exeeds the 16 bit register when its just a part of the equation? (16*9600=153600, (16000000/(16*9600)) - 1= 103.17, 2^16=65536)

And which difference would it acctualy make to write 16UL insted of 16??

 

 

 

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

Oletl wrote:
I'm not realy sure of the difference but i'm using the arduino as harwere and atmel stuidos as an IDE.(Do it awnser the question?)

Then how are you programming the Arduino?  Meaning are you using two Arduinos...one as the target device and one configured as a programmer?

 

Jim

 

I will move this to the Mega/Tiny forum

 

 

If you want a career with a known path - become an undertaker. Dead people don't sue! - Kartman

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB user

Last Edited: Sat. Jul 29, 2017 - 02:54 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oletl wrote:

Dose it matter if the 16*BAUD exeeds the 16 bit register when its just a part of the equation?

Yes, it does. That part is calculated first, and then the (overflowed) result (22528) goes into the rest of the equation.

Oletl wrote:
And which difference would it acctualy make to write 16UL insted of 16??
That part is calculated within unsigned 32 bit then.

Stefan Ernst

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

Oletl:

 

Your code worked after adding UL  (#3). 

But why not to use uart functions from the datasheet?

#include <avr/io.h>
#include <util/delay.h>
 
#define F_CPU 16000000UL
#define BAUD  9600UL
#define BRC   ((F_CPU / (16*BAUD)) - 1)
 
char RXbyte;

//---------------------------------------- 
void USART_Init(void)
{
   UBRR0 = BRC;
   UCSR0B = (1<<TXEN0)|(1<<RXEN0);
   // UCSR0C = (1 << UCSZ00) | (1 << UCSZ01);   // not needed, this is the default value
}

//---------------------------------------- 
unsigned char USART_Receive( void )
{
   while ( !(UCSR0A & (1<<RXC0)) ) ;    /* Wait for data to be received - note ";" */
   return UDR0;                         /* Get and return received data from buffer */
}

//----------------------------------------
void USART_Transmit( unsigned char data )
{
   while ( !( UCSR0A & (1<<UDRE0)) ) ;  /* Wait for empty transmit buffer */
   UDR0 = data;                         /* Put data into buffer, sends the data */
}
 
//=======================================
int main(void)
{
   USART_Init();

   for(int i=0;i<5;i++)
   {
      USART_Transmit('g');
      _delay_ms(1000);
   }
   USART_Transmit('\n');   // empty line

   while (1) 
   {
      // repeat chars
      RXbyte = USART_Receive();
      USART_Transmit(RXbyte);
   }
}

You can name this file as "test.ino" and compile, flash and test it in Arduino IDE. 

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

Tanks a lot sternst, you were compleatly correct and realy helpt me a lot!

 

For visovian i dident even know they existed, hehe.

I'm realy new to the UART and have simply started out based on videos and torturials, but i also beleve that the basics is the best way to start out.

They can surely be grate later on and i'l look up on them.

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

Wonder if anyone will ever stumble upon <util/setbaud.h>?

Last Edited: Sun. Jul 30, 2017 - 12:07 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Wonder if anyone will ever stumble upon <util/setbaud.h>?

I use it every day :)

 

The first line always makes me smile:

/* Copyright (c) 2007  Cliff Lawson
   Copyright (c) 2007  Carlos Lamas
   All rights reserved.

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

It's the one bit of AVR-LibC I have contributed. I did it early after starting with AVR after noticing that every 5th thread on Freaks seemed to be about getting baud rate setting wrong. My original proposal basically encoded the entire "examples of baud rate settings" table from AVR datasheets to preprocessor macros but Carlos then (rightly) tore that to shreds and we ended up with what you see now. At least the general idea was mine ;-)
.
Evidence of posted threads here seem to show no one ever really spots that it exists anyway (like so much in LibC). Ho hum.

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

clawson wrote:
Wonder if anyone will ever stumble upon <util/setbaud.h>?

And here I have been using AVRCALC to figure out the settings.....

 

 

Rather than derail the thread I am going to examine this and possibly start a new thread with a question or two I have....but I want to experiment on my own first.

 

Nice show Cliff

JIm

If you want a career with a known path - become an undertaker. Dead people don't sue! - Kartman

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB user

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

This is also a perfect job for a USD 5 logic analyser.

Within 2 minutes it will tell you:

- Whether your AVR is really outputting uart data or not.

- Whether the baud rate is ok, or even a little off (Can measure with 24Msps resolution, but that's overkill here).

- Whether you are outputting the right data 5 to 9 bit data, parity, etc.

 

And it will transform a lot of guess work into knowing while working with all kinds of other serial protocols.

Believe me. Such a USD5 tool is about the best investment you can make while learning uC related stuff.

http://sigrok.org/

http://hackaday.com/?s=sigrok

https://www.aliexpress.com/whole...

 

Paul van der Hoeven.
Bunch of old projects with AVR's:
http://www.hoevendesign.com

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

clawson wrote:
I did it early after starting with AVR after noticing that every 5th thread on Freaks seemed to be about getting baud rate setting wrong.

How has that worked out for you? ;)

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

theusch wrote:
How has that worked out for you? ;)
Quite:

clawson wrote:
seem to show no one ever really spots that it exists anyway (like so much in LibC)

Adding library code or writing tutorials is all pretty pointless because the "hand it to me on a plate" generation never both searching for solutions. They just start how with the "how do you do this?" post on some forum with no research. So providing potted solutions is never going to help much :-(

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

jgmdesign wrote:
clawson wrote: Wonder if anyone will ever stumble upon ?

I noticed it quite some time ago.

Auto baud detection sure can save some time in some cases, but it can also hide problems.

So I use my own macro's which does not try to guess and which throws out an warning if something is wrong.

//==================================================== F_CPU related define's.
// Baudrate must be 115200 as defined in the network specifications
#if F_CPU==3686400
#define UART_BAUD_SELECT		1
#elif F_CPU==5529600
#define UART_BAUD_SELECT		2
#elif F_CPU==7372800
#define UART_BAUD_SELECT		3
#elif F_CPU==9216000
#define UART_BAUD_SELECT		4
#elif F_CPU==11059200
#define UART_BAUD_SELECT		5
#elif F_CPU==12902400
#define UART_BAUD_SELECT		6
#elif F_CPU==14745600
#define UART_BAUD_SELECT		7
#elif F_CPU==16588888
#define UART_BAUD_SELECT		8
#elif F_CPU==18432000
#define UART_BAUD_SELECT		9
#elif F_CPU==20275200
#define UART_BAUD_SELECT		10
#elif F_CPU==22118400
#define UART_BAUD_SELECT		11
#elif F_CPU==23961600
#define UART_BAUD_SELECT		12
#elif F_CPU==25804800
#define UART_BAUD_SELECT		13

#else
	#ifdef __linux__
	// No error. Linux does not understand nor need this stuff.
	#else
	// This is why we list all baudrate chrystals separately:
	#warning F_CPU not usable for network protocol.
	#endif
#endif

But for a general lib which can be used with different baudrates this approach is not really practical.

But the baud calculations could have some sanity checks on over/ underflow or throw a warning if the baud rate is off by > 2% of waht it should be.

Paul van der Hoeven.
Bunch of old projects with AVR's:
http://www.hoevendesign.com

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

Auto baud detection

But that's not what <util/setbaud.h> does.

 

What it does is calculate the correct values for UBRR (and separately UBRRH/UBRRL as well) and U2X for a specified baud rate and F_CPU, constrained by the user-supplied BAUD_TOL in percent.  Pretty much what your macros do, only more generally.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]