2
\$\begingroup\$

I need to develop a controller board for some peripherals which communicate at 9600 baud with 1 start bit, 9 data bits, no parity and one stop bit.

I am not sure that I am up to coding a serial port driver or even modifying an existing 8 data bit driver to handle 9, so - does anyone know of an MCU which comes, off the shelf, with a serial port driver which can handle 9 data bits?

I strongly prefer SD card support, and Ethernet / Wifi would be nice (I don't care too much about BlueTooth or USB, so long as they don't significantly increase price).

Needs to be able to run 24/7 in an embedded device.

I prefer something with FreeRTOS or similar and a good development IDE including debug facilities.

Am I asking too much or does such a beast exist?

\$\endgroup\$
6
  • \$\begingroup\$ Is there a reason you need to have 9 data bits? A little bit more info about what you are doing might help someone give you the best solution. \$\endgroup\$
    – Kellenjb
    Commented Jan 4, 2012 at 15:16
  • 4
    \$\begingroup\$ @Kellenjb - it's not an unheard of requirement, some devices want to use a 9th bit for out-of-band signaling, to be able to pass 8-bit data without having to worry about state or escaping special codes. \$\endgroup\$ Commented Jan 4, 2012 at 15:40
  • \$\begingroup\$ Many microcontroller UARTs have a optional 9 bit mode. Have you looked around at all? \$\endgroup\$ Commented Jan 4, 2012 at 16:03
  • 2
    \$\begingroup\$ Developing for 24/7 WiFi operation on a RTOS is quite a bit more involved than soft-coding a UART. \$\endgroup\$
    – tyblu
    Commented Jan 4, 2012 at 18:09
  • 1
    \$\begingroup\$ @tyblu: Yes, but you have to actually know a bit about the hardware for the latter. \$\endgroup\$ Commented Jan 4, 2012 at 18:46

5 Answers 5

7
\$\begingroup\$

The ATmega series has a 9-bit UART

The ATmega series of microcontrollers (datasheet) has the ability to use 9 data bits without messing with the parity bit. This functionality is described in the timing diagram:

timing diagram

Note that the bits are numbered in the figure from 0-8, which is a total of 9 bits. The caption refers to this numbering, it does not indicate that you can use 0-8 data bits. The minimum number of bits in a character is 5, and the maximum is 9, not 0-8.

You can set the width of the data section by the UCSZ bits. The settings are described in table 19-7, pictured below:

table 19-7

To set this in C using AVR Libc, you would need to execute the code:

#include <avr/io.h>  // _BV() macro, register definitions

// Set the Uart Character SiZe to 9 bits as described in table 19-7
UCSR1B |= _BV(UCSZ12 );
UCSR1C |= _BV(UCSZ11) | _BV(UCSZ10 );

Note that you'll probably want to specify the other bits in these registers while you're at it.

Many other processors also have this

There are almost certainly other processors which support this feature set. Atmel's ATtiny processors have the same USART as the ATmega, and are code-compatible, their AVR32 processors have the same true 9-bit support, but a different programming interface, the dsPIC processors support it, but without a proper parity bit (see page 243 of this datasheet; set bits 1 and 2, PDSEL of the UxMODE register)...the list goes on. The first processor that I checked which did not support it was a Stellaris Cortex-M3 part, which supports 5-8 data bits, but not 8 bits.

But you should use your other constraints to narrow the options first.

In the end, though, you should do your processor selection based on other factors first. You wrote:

I strongly prefer SD card support, and Ethernet / Wifi would be nice (I don't care too much about BlueTooth or USB, so long as they don't significantly increase price).

Most people will access the SD card in SPI mode, and almost everything has an SPI port or two. Ethernet/WiFi is too generic a spec and a much harder requirement to meet - Do you want an integrated MAC with an MII interface? Integrated PHY? Would you prefer to do all the TCP/IP stuff on-chip, or offload practically everything to something like a WIZnet W5100 or Lantronix XPort. You can also use components like the Microchip ENC28J60 to move the MAC and PHY to an external chip, accessed over SPI. Your other requirements are much more exacting than a 9-bit UART.

In fact, you could probably use a $1.50 ATtiny as an SPI'/I2C<->9-bit UART converter if you wanted to. That would be much less expensive than choosing a sub-optimal processor for your other requirements.

\$\endgroup\$
3
  • \$\begingroup\$ +1 Thank you very much for such an informative and detailed reply. I am the software guy and will have to discuss it further with my hardware friend, but I think that I see an answer here. Thanks again! \$\endgroup\$
    – Mawg
    Commented Jan 5, 2012 at 1:28
  • \$\begingroup\$ As to Wifi/Ethernet etc, I want a single board solution with device drivers for all peripherals, an o/s such as FreeTOS and an integrated TCP/IP stack. I am a s/w guy of 30 years experience with little or no h/w knowledge and would like to be protected from the h/w as far as possible (picked a great site to post to, huh? ;-) Ideally I would like a board that I can program just as I might a Windows or Linux PC, although I am aware that that is only a dream, not a reality. \$\endgroup\$
    – Mawg
    Commented Jan 5, 2012 at 3:00
  • 1
    \$\begingroup\$ @Mawg - In that case, you're probably better off buying a USB<-> serial dongle that's capable of 9-bit data, or finding a motherboard that can do it, and just using a normal PC. \$\endgroup\$ Commented Jan 5, 2012 at 4:19
5
\$\begingroup\$

Some web searching indicates that the following families may have a hardware 9-bit capability: ATMEGA, dsPIC, 8051, STM32 and of course many others - but then there are also a lot of 7/8-bit only UART peripherals too.

At the cost of greater driver overhead, an 8-bit UART with parity support can be made to transmit 9-bit characters by determining the parity of the 8-bit value to be transmitted and then setting the UART mode to even or odd parity as required to achieve the desired value of the 9th bit. On receive the parity error flag is read and the 9th bit determined from that and the calculated parity of the 8-bit value.

A software UART can of course implement an arbitrary character width.

\$\endgroup\$
1
  • \$\begingroup\$ +1 Thanks very much. I will be googling those and sending off enquirers. Btw, I am new to this area and am unfamiliar with the term "software UART" - does it simply mean device driver? \$\endgroup\$
    – Mawg
    Commented Jan 5, 2012 at 1:34
4
\$\begingroup\$

I've observed UARTs offering varied levels of support for "nine-bit data"; one sometimes has to read data sheets carefully to see how things will really work.

  1. Some UARTs can be configured to transmit and receive eight bits of data plus an extra bit, and have full 9-bit transmit and receive buffers. It is thus possible to send and receive 9-bit data fluidly and reliably.
  2. Some UARTs can be configured to transmit and receive 9-bit data, but have no transmit buffer outside the shifter, and only a single-byte receive buffer. Such UARTs require baby-sitting with every byte of 9-bit data, but can send and receive it just as reliably as 8-bit data.
  3. Some UARTs can be configured to transmit and receive eight bits of data along with a ninth bit that can be configured for marking or spacing, and can report the state of the ninth bit on the last received byte, but they must inspect the state of the ninth bit of each received byte before the next byte is received. Provided they can inspect incoming data in a timely fashion, however, communications may be reliable. If, after processing a byte, the receive interrupt observes that another byte is already pending, the ninth bit of the just-processed byte should be presumed unreliable.
  4. Some UARTs might be like the above, but set the state of a received byte's party before the byte itself is considered available; I'm not sure if any actually work this way, but it should be noted that it would not prevent reliable transmission and reception with interrupts that were were always handled in timely fashion, but might not reliably provide notice when late interrupts caused data loss.
  5. Some UARTs can be configured to transmit and receive eight bits along with a configurable ninth bit, but for various reasons cannot reliably do both simultaneously and asynchronously using any reasonable interrupt structure. For example, a part might use the same configuration control bits to set outgoing parity and "expected" incoming parity, and might record whether the last received byte's parity was "correct" or "incorrect". If a byte is received while the parity setting is changed, it may be impossible to know whether the "correct" or "incorrect" designation was relative to the old or new setting.

In some ways, it would seem that using nine-bit data should be simple. Too bad it seldom is.

\$\endgroup\$
1
  • \$\begingroup\$ +1 and again, a great reply. Thank you very much for such an informative and detailed reply. I am the software guy and will have to discuss it further with my hardware friend, but this has helped greatly. Thanks again! \$\endgroup\$
    – Mawg
    Commented Jan 5, 2012 at 1:29
3
\$\begingroup\$

In most cases 9-bit UART can be emulated with 8 data bits and an explicitly set parity bit. Check this thread for some discussion.

\$\endgroup\$
1
  • \$\begingroup\$ +1 Thanks for a great link. If I can't get something off the shelf then that gives me some hints as to coding the driver. As a bonus it discusses the LPC series and I have been recommended to use an LPC 1769 (although I am not sure why). \$\endgroup\$
    – Mawg
    Commented Jan 5, 2012 at 1:30
1
\$\begingroup\$

There was a request just yesterday on the Arduino-Developers mailing list to add support to the Serial library to allow users to specify data bits, stop bits, and parity. The Mega328 UART (which the Arduino hardware is based on) can indeed be configured for 9 data bits, so if this patch/feature request gets adopted it could make it quite easy to set up and code. The software is not implemented today, but it's certainly plausible.

\$\endgroup\$
2
  • \$\begingroup\$ +1 thanks a bunch for that. Do you have a URL where I can track progress? \$\endgroup\$
    – Mawg
    Commented Jan 5, 2012 at 1:35
  • 1
    \$\begingroup\$ @Mawg you can either subscribe to the developers mailing list at arduino.cc/mailman/listinfo/developers_arduino.cc or you can just read the archives periodically - the thread of interest is titled "serial port support for parity and stop bits" \$\endgroup\$
    – vicatcu
    Commented Jan 5, 2012 at 17:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.