Friday, June 8, 2012

printf() for the MSP430

"The output function printf translates internal values to characters."
This simple definition comes from the book "C Programming Language" by Kernighan and Ritchie. I highly recommend this book to anyone who is interested in learning more about C, it is a must have for any embedded programmer.

The printf() function will allow us to display any value in your code so that it is human readable. What does this mean? Let's say you would like to tell the computer what temperature your MSP430 has measured; a typical output might be "Temperature: 71°F". We know how to read the internal temperature from a previous post, but how do we get our MSP430 to output the above string over UART? We use the printf() function.
printf("Temperature: %u°F\r\n", tempValue);
I will not be explaining how printf() actually works in this post. If you would like more information on how to use this function please see the above mentioned book, or this link. Due to the fact that the MSP430 has limited resources (e.g. memory), a compact version of the standard printf() function must be used.

Since the printf() included in Code Composed Studio is very large and will not fit on many of the value line MSP430s, we must add our own printf() function to our projects. oPossum on the forums has shared his printf() with the community and since reinventing the wheel is rarely a good idea, we will be using oPossum's code.
"This is a tiny printf() function that can be used with the chips that come with the Launchpad. Code size is about 640 bytes with CCS."
This is how oPossum describes his function. While this function does not support all of the standard printf() features, it is more than sufficient for use on an MSP430. Using this function, we can format 7 separate data types: character, string, integer, unsigned integer, long, unsigned long, and hexadecimal (16-bit) formatting.

I want to thank oPossum for sharing his code with the community. The code is very well written and works great! Thanks again!


Please scroll down for the rest of the post. One of these days I will figure out how to limit the height of my embedded code.

Customizing the Output

Depending on your project, you will want to have printf() output differently. For this example, printf() will send the formatted string out over the UART to a computer. For a different project, you might want to output the string to an LCD, or through USB. The code provided from oPossum allows you to define two functions, puts() and putc() which determines how printf() will output the formatted string. Without defining these two functions, the printf() will actually not do a thing. printf() uses puts(char *) to send out a string value, and uses putc(unsigned) to send out a character.

In the code above, my puts(char *) and putc(unsigned) functions sends the string and character out over UART using another of my functions, sendByte(unsigned char). The code in these functions is fairly straight forward, and will not be discussed here. If you would like to another output for printf(), you would create your own puts(char *) and putc(unsigned) functions as I have done in the code above.

Testing the printf() Function

I will be using a very similar setup as oPossum for testing the printf() function. The code above will send a test sequence to the computer when the MSP430 receives the character 't' over UART. I recommend using Realterm for interfacing with the MSP430 over UART. To connect, select the correct COM port and set the baud rate to 9600. Once connected, send the character 't' by clicking on the blank window and typing 't'. You should see the following response from the MSP430.

Test sequence from the MSP430

Use this code in your projects! It really is a great piece of code. To use this printf() function to your own CCS projects, just add printf.c to your project and create your own puts(char *) and putc(unsigned) in your main c file as I have done in this example.

In the next post, I will expand on the previous post by creating a real-time clock using the MSP430. Stay tuned!