{"id":683,"date":"2012-09-04T21:38:00","date_gmt":"2012-09-04T19:38:00","guid":{"rendered":"https:\/\/www.fussylogic.co.uk\/blog\/?p=683"},"modified":"2012-10-08T17:52:52","modified_gmt":"2012-10-08T16:52:52","slug":"avr-uart-transmit-and-stdio","status":"publish","type":"post","link":"https:\/\/www.fussylogic.co.uk\/blog\/?p=683","title":{"rendered":"AVR UART Transmit and stdio"},"content":{"rendered":"<p>The setup for a UART on AVR is such common code that I wonder if possibly it\u00e2\u20ac\u2122s just assumed to be understood and explained. This is a quick article to fill in the gaps. First let\u00e2\u20ac\u2122s talk initialisation. This is often the most important part of using any hardware peripheral on an embedded processor. In the case of the AVR UARTs, <code>avr-libc<\/code> includes the very convenient <code>setbaud.h<\/code> to help us (I\u00e2\u20ac\u2122m using \u00e2\u20ac\u02dcatmega8\u00e2\u20ac\u2122 register names here, but the principle is the same whatever member of the family you use)<sup><a href=\"#fn1\" class=\"footnoteRef\" id=\"fnref1\">1<\/a><\/sup>:<\/p>\n<pre class=\"sourceCode C\"><code class=\"sourceCode c\"><span class=\"dt\">static<\/span> <span class=\"dt\">void<\/span> initUART()\n{\n    <span class=\"co\">\/\/ UCSRA    RXC   TXC   UDRE  FE   DOR  PE    U2X   MPCM<\/span>\n    <span class=\"co\">\/\/ UCSRB    RXCIE TXCIE UDRIE RXEN TXEN UCSZ2 RXB8  TXB8<\/span>\n    <span class=\"co\">\/\/ UCSRC    URSEL UMSEL UPM1  UPM0 USBS UCSZ1 UCSZ0 UCPOL<\/span>\n    <span class=\"co\">\/\/ UDR      ------------ UART Data Register -------------<\/span>\n    <span class=\"co\">\/\/ UBRRH    URSEL -     -     -    ----- UBRR[11:8] -----<\/span>\n    <span class=\"co\">\/\/ UBRRL    ---------------- UBRR[7:0] ------------------<\/span>\n    <span class=\"co\">\/\/<\/span>\n\n    <span class=\"co\">\/\/ Assume F_CPU has been set to CPU frequency<\/span>\n\n    <span class=\"co\">\/\/ Use setbaud.h to calculate the registers for us<\/span>\n<span class=\"ot\">#   define BAUD 9600<\/span>\n<span class=\"ot\">#   include &lt;util\/setbaud.h&gt;<\/span>\n    <span class=\"co\">\/\/ Set baud rate before enabling the UART<\/span>\n    UBRRH = UBRRH_VALUE;\n    UBRRL = UBRRL_VALUE;\n<span class=\"ot\">#   if USE_2X<\/span>\n    UCSRA |= _BV(U2X);\n<span class=\"ot\">#   else<\/span>\n    UCSRA &amp;= ~_BV(U2X);\n<span class=\"ot\">#   endif<\/span>\n\n    <span class=\"co\">\/\/ Enable receiver and transmitter<\/span>\n    UCSRB |= _BV(TXEN) | _BV(RXEN);\n    <span class=\"co\">\/\/ Set frame format: 8 data; 0 stop bits<\/span>\n    <span class=\"co\">\/\/ Note: UCSRC and UBRRH share the same I\/O address.  The URSEL bit<\/span>\n    <span class=\"co\">\/\/ is used to choose which of the registers the lower 7 bits are<\/span>\n    <span class=\"co\">\/\/ written to.  For URSRC, include URSEL in the set, otherwise don&#39;t<\/span>\n    UCSRC |= _BV(URSEL) | (<span class=\"dv\">0<\/span> &lt;&lt; USBS) | (<span class=\"dv\">3<\/span> &lt;&lt; UCSZ0);\n}<\/code><\/pre>\n<p>Outputting a byte is then very simple. We need only trigger the UART peripheral.<\/p>\n<pre class=\"sourceCode C\"><code class=\"sourceCode c\">UDR = <span class=\"ch\">&#39;\\n&#39;<\/span>;<\/code><\/pre>\n<p>We should be a little careful though. The <code>UDR<\/code> register might be in use sending an earlier byte. We should check for that before overwriting it.<\/p>\n<pre class=\"sourceCode C\"><code class=\"sourceCode c\"><span class=\"dt\">static<\/span> <span class=\"dt\">void<\/span> uart_putchar( <span class=\"dt\">char<\/span> c )\n{\n    <span class=\"co\">\/\/ Wait for data register empty flag<\/span>\n    <span class=\"kw\">while<\/span>( !( UCSRA &amp; _BV(UDRE) ) )\n        ;\n    <span class=\"co\">\/\/ Begin next transmit<\/span>\n    UDR = c;\n}<\/code><\/pre>\n<p>Now you want to be able to use <code>printf()<\/code>. What do you do?<\/p>\n<p>Conveniently, <code>avr-libc<\/code> is pretty excellent. It includes a <code>stdio<\/code> implementation that is retargettable. Here\u00e2\u20ac\u2122s the magic line\u00e2\u20ac\u00a6<\/p>\n<pre class=\"sourceCode C\"><code class=\"sourceCode c\"><span class=\"dt\">static<\/span> FILE UARTstdout = FDEV_SETUP_STREAM(\n    uart_putchar,\n    NULL,\n    _FDEV_SETUP_WRITE );<\/code><\/pre>\n<p>Then to use this structure in <code>printf()<\/code> and all the other <code>stdio<\/code> functions, we simply add the following to our initialisation:<\/p>\n<pre class=\"sourceCode C\"><code class=\"sourceCode c\">stdout = &amp;UARTstdout;<\/code><\/pre>\n<p>The <code>_FDEV_SETUP_WRITE<\/code> flag makes <code>UARTstdout<\/code> a write-only handle, which is what we\u00e2\u20ac\u2122d expect for <code>stdout<\/code>. We need to slightly modify our <code>uart_putchar()<\/code> to match what <code>FDEV_SETUP_STREAM()<\/code> expects:<\/p>\n<pre class=\"sourceCode C\"><code class=\"sourceCode c\"><span class=\"dt\">static<\/span> <span class=\"dt\">int<\/span> uart_putchar( <span class=\"dt\">char<\/span> c, FILE *stream )\n{\n    <span class=\"co\">\/\/ Wait for data register empty flag<\/span>\n    <span class=\"kw\">while<\/span>( !( UCSRA &amp; _BV(UDRE) ) )\n        ;\n    <span class=\"co\">\/\/ Begin next transmit<\/span>\n    UDR = c;\n}<\/code><\/pre>\n<p>Now we\u00e2\u20ac\u2122ve got a <code>FILE<\/code> variable, we need to tell <code>stdio<\/code> to use it.<\/p>\n<pre class=\"sourceCode C\"><code class=\"sourceCode c\"><span class=\"dt\">int<\/span> main(<span class=\"dt\">void<\/span>)\n{\n    initUART();\n    stdout = &amp;UARTstdout;\n\n    <span class=\"co\">\/\/ ... other initialisation<\/span>\n\n    printf( <span class=\"st\">&quot;Hello, World!<\/span><span class=\"ch\">\\r\\n<\/span><span class=\"st\">&quot;<\/span> );\n\n    <span class=\"kw\">while<\/span>(<span class=\"dv\">1<\/span>)\n        ;\n    \n    <span class=\"kw\">return<\/span> <span class=\"dv\">0<\/span>;\n}<\/code><\/pre>\n<p>It\u00e2\u20ac\u2122s pretty wasteful to force the inclusion of <code>printf()<\/code> just to write an unformatted string of course; but I presume you\u00e2\u20ac\u2122ll have better uses for your <code>printf()<\/code>.<\/p>\n<p>We\u00e2\u20ac\u2122ve not discussed interrupts at all here; and for good reason: interrupts often complicate matters considerably, but once under your control they make your program much more reactive and responsive. They\u00e2\u20ac\u2122re also vital for power control, since you can put your processor to sleep and only wake up when an event occurs. I\u00e2\u20ac\u2122ll cover interrupt handling in embedded systems in a future article.<\/p>\n<div class=\"footnotes\">\n<hr \/>\n<ol>\n<li id=\"fn1\">\n<p>The <code>_BV()<\/code> macro is another handy one provided by <code>avr-libc<\/code>, it\u00e2\u20ac\u2122s simply<\/p>\n<pre class=\"sourceCode C\"><code class=\"sourceCode c\"><span class=\"ot\">#define _BV(bit) (1 &lt;&lt; (bit))<\/span><\/code><\/pre>\n<p><a href=\"#fnref1\">\u00e2\u2020\u00a9<\/a><\/li>\n<\/ol>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>The setup for a UART on AVR is such common code that I wonder if possibly it\u00e2\u20ac\u2122s just assumed to be understood and explained. This is a quick article to fill in the gaps. First let\u00e2\u20ac\u2122s talk initialisation. This is often the most important part of using any hardware peripheral on an embedded processor. In\u2026 <span class=\"read-more\"><a href=\"https:\/\/www.fussylogic.co.uk\/blog\/?p=683\">Read More &raquo;<\/a><\/span><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[39,37,38,6],"_links":{"self":[{"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/683"}],"collection":[{"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=683"}],"version-history":[{"count":8,"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/683\/revisions"}],"predecessor-version":[{"id":809,"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/683\/revisions\/809"}],"wp:attachment":[{"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=683"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=683"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.fussylogic.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=683"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}