Need some advise.. go printf or not ?

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

Hey
I have a bit of a problem right now..
I have 2 mega32 with a serial connection between..
One uC is the master, the other is a display driver for my 32x16 LED display...
but I can't figure out if it would be smartest to use printf or just write my own serial function with buffer..

The data I'm gonna send from uC to driver is:
a control char followed by 2 to 64 data bytes
or
a control char followed by a string of text with variable length.

I've never used printf before.. so right now it sound kinda scary... how much space will it use ? how do I use it?

uC's: Atmega16, 32, 64, 128 and Attiny13
Lang.: C
Interests: Small scale robots AND sensor monitoring system

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

printf() will "cost" about 1K..2K with most C compilers. On a 32K flash device this is generally a fairly small cost to pay for a lot of functionality. Most C compilers have several variants of printf() with only the big version supporting floating point numbers - don't bother with it unless you have some reason to use float. That should keep you under 1K in fact.

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

Quote:
to use printf or just write my own serial function with buffer..

Printf really won't help you with that aspect of it. You still need your own buffer to pass to printf, and you still need a routine that printf can use to output characters to the UART (though it does do the string handling to send to that function). What printf gives you is formatting capabilities.

Regards,
Steve A.

The Board helps those that help themselves.

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

32x16 chars? How far away? What speed will you send the chars? The easy brute force method would be to make the receiver recognize ansi 3.64 'clear screen' and 'position cursor' escape sequences, also carriage return and line feed, and just send 512 ascii chars.

Imagecraft compiler user

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

I don't see the point of using printf() for this communication between two AVRs via USART. There is nothing inherently in the communication requiring printf():

The sender just sends one character after the other over the USART. No need for printf() formating on this level. The receiver gets the control character and the data, interprets the control character (no need for printf() here), and handles the following text data according to the control data - e.g. position the text on the LCD. Again no need for printf() here.

Completely independent of this communication function is how an application on top creates the strings to be send. An application might need printf() formatting to prepare a string. If that makes sense for the application, then go for printf() on application level. And either link printf() to the low-level USART transmit function sketched above, or use sprintf() instead.

Stealing Proteus doesn't make you an engineer.

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

Okay, thanks for the answers.. I'll use my own buffer routine to this project.
But if printf dosn't do all the sending.. what is the function then for? I thought it where a "communication" function.. like printf("Hello World") in a console program written in C# ?

uC's: Atmega16, 32, 64, 128 and Attiny13
Lang.: C
Interests: Small scale robots AND sensor monitoring system

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

puts()
itoa() and puts()

these send output to a UART driver that YOU supply and hook in using names and so on that are documented in the library of whatever C compiler/runtime library you've chosen.

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

B4Me wrote:
Okay, thanks for the answers.. I'll use my own buffer routine to this project.
But if printf dosn't do all the sending.. what is the function then for? I thought it where a "communication" function.. like printf("Hello World") in a console program written in C# ?

printf simply parses the format string, and composes the final output, and then repetitively calls putc() [or equivalent] until the string has been output. Printf is so large, simply due to all the data formats that it must support.

now putc is where your buffering comes in. Most (if not all) AVR C compilers allow you to define your own putc function to replace the built in one (if there even is a built in one). So you could implement buffering using your own putc, and then use printf.

Having said that.. in my 20+ years of embedded development, I have never used printf on a small micro like the AVR [non hosted envirnments]. I have always chosen to use my own hand rolled, specialized, output routines. In fact I tend to use very few, if any, of the standard library functions in my apps.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

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

Okay that gave a better insight in what this Printf actually are.. :)
Use my own Use my own Use my own Use my own Use my own Use my own Use my own Use my own Use my own Use my own :P

uC's: Atmega16, 32, 64, 128 and Attiny13
Lang.: C
Interests: Small scale robots AND sensor monitoring system

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

Quote:

Use my own Use my own Use my own Use my own Use my own Use my own Use my own Use my own Use my own Use my own

Do that - but here's a challenge - print out the decimal value 12345678 as a hex number (using A..F, not a..f) with 0 padding to 8 digits prefixed "0x". That is "0x0BC614E". I'd do it with:

printf("0x%08X", 12345678);

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

clawson wrote:

Do that - but here's a challenge - print out the decimal value 12345678 as a hex number (using A..F, not a..f) with 0 padding to 8 digits prefixed "0x". That is "0x0BC614E". I'd do it with:

printf("0x%08X", 12345678);

I would do it with something like

void print_ulong_hex(unsigned long n)
{
	unsigned char i, j;
	putchar('0'); putchar('x');
	for (i = 7; i != 255; i--) {
		j = (unsigned char) (n>>(i<<2)) & 0xF;
		if (j<10)
			putchar(j+'0');
		else
			putchar(j+'A'-10);
	}
}

That will save 1280 bytes on a tiny44.

(By the way, the answer is 0x00BC614E. You missed a leading zero :-))
/Joakim