"REAL" hello world program wanted or how to setup comport

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

Hi all...

I am looking for a "real" hello world tutorial for the Mega32 running at 8mhz.  I've my port setup as thus:

 

void set_comport(void)
{
//UART0 initialize
// desired baud rate: 38400
// actual: baud rate:38462 (0.2%)

 UCSRB = 0x00; //disable while setting baud rate
 UCSRA = 0x00;
 UCSRC = 0x06;
 UBRRL = 0x0C; //set baud rate lo
 UBRRH = 0x00; //set baud rate hi
 UCSRB = 0x08;
}

   After calling the set_comport() from main, I want to be able to simply :

printf("Hello World");

and have it stream out the comport at 38400baud.  What am I doing wrong?

 

This topic has a solution.
Last Edited: Mon. Apr 16, 2018 - 01:06 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

1)
The UCSRC register is shared with the UBRRH register (I do not know why).
To write to the UCSRC register you need to set the URSEL bit (bit-7) when you do a UCSRC=

2)
On many AVR8s the internal 16-bit baud rate divisor is updated when UBRRL is written.
In your case it doesn't matter because the high-byte of the divisor is zero but do get into the habit of writing to UBRRH first and UBRRL last.

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

aa9gg wrote:
   After calling the set_comport() from main, I want to be able to simply : printf("Hello World"); and have it stream out the comport at 38400baud.  What am I doing wrong?  

 

For starters post your code.  That little blip above shows nothing on how you have the initializations done. 

 

Do you have your code set up to support PrintF?

 

Post the minimum code showing what you have done.

 

JIm

 

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

Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

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

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

The following is the complete code I'm trying to run:

 

#include <avr/io.h>
#include <stdio.h>

#include"CFG.h"


int main (void)
{

   config();

   while(1) // Loop forever
   {

       printf("Hello World/n/r");
       printf("This is a test/n/r");
   }   
}
//----------------------------------------
void config(void)
{
	DDRA = 0xFE;
	PORTA = 0x01;

	DDRB = 0x09;
	PORTB = 0x06;

	DDRC = 0x07;
	PORTC = 0x00;

	DDRD = 0x95;
	PORTD = 0x68;

	set_comport();
}
//----------------------------------------
void set_comport(void)
{
//UART0 initialize
// desired baud rate: 38400
// actual: baud rate:38462 (0.2%)

 UCSRB = 0x00; //disable while setting baud rate
 UCSRA = 0x00;
 UCSRC = URSEL << 1 |0x06;
 UBRRL = 0x0C; //set baud rate lo
 UBRRH = 0x00; //set baud rate hi
 UCSRB = 0x08;
}

Do you have your code set up to support PrintF?

How so?  Isn't it a part of stdio.h?

 

What am I missing here???

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

UCSRC = URSEL << 1 |0x06; should be UCSRC = ( 1 << URSEL ) | 0x06;

and now that you've discovered the predefined bit values it will assist furure debugging if you do
UCSRC = ( 1 << URSEL ) | ( 1 << UCZS1 ) | ( 1 << UCZS0 );
and
UCSRB = ( 1 << TXEN );

Last Edited: Mon. Apr 16, 2018 - 12:07 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

UCSRC = URSEL << 1 |0x06; should be UCSRC = ( 1 << URSEL ) | 0x06;

and now that you've discovered the predefined bit values it will assist furure debugging if you do
UCSRC = ( 1 << URSEL ) | ( 1 << UCZS1 ) | ( 1 << UCZS0 );
and
UCSRB = ( 1 << TXEN );

I fixed that (also it is UCSZ0/UCSZ1), but it still doesn't respond.   BTW, I am using the Br@y terminal program...

 

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

I am assuming you are using Atmel Studio.

 

YOu need to set up File Stream in order to use the PrintF command.  Are you getting any errors or warnings in your build?

 

Jim

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

Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

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

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Found my solution here:  https://www.sparkfun.com/tutoria...

 

thanks guys....

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

Upvoted jgmdesign.

printf() is a generic C function used in a lot of different programs from small uC's to normal PC's.

In a PC printf() is normally "connected" to the standard output stream.

But there is no such thing in a small AVR.

To be able to use printf() in a small uC you have to provide a function which is capable to write a single character to some output device (in your case the UsART.

Then printf() formats the data in a buffer and calls that output function for each character in the buffer.

The error / warning that jgm is expecting is for that function to be missing.

 

As an alternative you can use the "arduino" framework. arduino is a more "sophisticated" system where prinf() alike functions are already connected to streams for input/ouput.

If you load an "arduino" project in a decent IDE (Not arduino's Java contraption) you can easily follow the stack of function calls from a printf() function to the uart output.

 

When I started with uC's, functions like printf() were considered unacceptable "bloat". printf() is a pretty complicated function and a dumbed down version for AVR's is still between 2kB and 3kB (A complete version with floating point support kan be > 20kB). The solution used to be to format data in a string yourself and then have a simple uart function to write that string one character at a time in a loop to the hardware (More sophisticated version does the same with interrupts).

 

I started with the AT90S2313, which has only 2kB of flash. printf() would not even fit in that small AVR. But now uC's such as the atmega328 with 32kB flash are much more common and that makes it much more tempting to use "big" library functions such as printf().

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

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

aa9gg wrote:

Found my solution here:  https://www.sparkfun.com/tutoria...

 

thanks guys....

 

From that link:

static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);

Was what I was looking for, hence why I asked you to post your code, and did not see that line.  There is also a little more involved that is probably in that C file mentioned in the article.

 

Well anyway, you found your solution.  Be well.

 

JIm

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

Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

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

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

Documentation for the Standard IO features - including printf() - is here:

 

https://www.nongnu.org/avr-libc/user-manual/group__avr__stdio.html

 

It includes an example of how to do the FDEV_SETUP_STREAM stuff...

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

aa9gg wrote:
Isn't it a part of stdio.h?
As the documentation confirms there is no assumption made in stdio.h (for avr-gcc / AVR-LibC) as to the destination of the stdin, stdout and stderr streams (printf() is really just fprintf() using stdout). The C library can't initially know whether you want your output to go to UART or LCD or something else and even if it made the assumption of UART on a micro that has four UARTs say (0,1,2,3) how could it know which of the four should be used by default?

 

That's why FDEV_SETUP_STREAM exists (File Device setup Stream) so you can tell it where you want the file streams to get/send their output to/from. Once you have created input/output (or both) channels you can then assign then to stdin, stdout or stderr and that's where the characters will then go or come from.

 

Other AVR compilers may well make the assumption of UART0 as a default but even if they do that you still need to configure the baud rate for printf() etc to be used.

Last Edited: Mon. Apr 16, 2018 - 08:40 AM