Could it be that UCSZ02
bit in UCSR0B
is set? This would give you 9-bit character size... It also could be a matter of incorrect baud selection, including the cases where your MCU does not run at the speed you are expecting: the set baud rate is sensitive to MCU clock speed.
In general, I would recommend using |
, &
and <<
operators to set your register bits: it looks cleaner, and much easier to understand what is going on. Thus, personally, I would rewrite your register assignment as:
UCSR0C = 0
| (0<<UMSEL01) | (0<<UMSEL00) // Asynchronous USART
| (0<<UPM01) | (0<<UPM00) // Parity Disabled
| (0<<USBS0) // 1 stop bit
| (1<<UCSZ01) | (1<<UCSZ00) // 8-bit character size
| (0<<UCPOL) // Rising TX, falling RX
;
But this is not what you asked about, and this is clearly a matter of taste.
No, there is no standard or even generally accepted common practise.
If you are really sure all you will ever send over this link is a stream of 12 bit values, then you can put 6 bits in each byte and use the remaining 2 bits to identify whether this byte contains the high or low 6 bits of the 12 bit word. That leaves two more codes for a little expansion.
However, that's not what I'd, and certainly not what I usually do. No matter how much you think to the contrary now, chances are good that sooner or later you'll wish you could send something else over the link, even if just for debugging. Since you say bandwidth is not a problem, do it right now so that expanding the protocol will be easy.
What I usually do is send data in packets that start with a opcode byte, which is then followed by whatever data goes along with that opcode. I have done this many times. For clarity of documentation, I call packets from the host to the micro commands, and from the micro to the host responses, but that doesn't mean responses must be only a result of commands.
This scheme is easy to implement in firmware. It's easy on the host too, but that doesn't matter. With the infinite processing power and memory of a PC, any protocol you cook up that is tractable on the micro will be easy on the host. The point is to keep it simple on the small resource-limited system and have the other system adapts as necessary.
On receiving, I use a jump table for the opcode byte. That dispatches to the routine unique for that command, which knows how many more input stream bytes to read and what to do with them. When done, command routines jump back to a common return point, which fetches the next opcode, dispatches thru the table, which runs the next command routine, etc.
Once you have this mechanism set up and a test program on the host to read and write this protocol, it is really simple to add another command or response. Being so simple, you'll start to use this facility in ways you might not have envisioned at the start. For example, you can make a command that sets a debug bit in the firmware which causes other code to do something special. Or you realize there are some options you would like to control, maybe read back data memory, a special command that does something one-off for testing, etc, etc. This sort of stuff comes in really handy a lot.
To solve the particular case you asked about, you'd have a response that is followed by 2 bytes which contain the 12 bit number. In the micro, that's as simple as sending the response opcode byte followed by the two data bytes periodically. Meanwhile it leaves open the option of sending other things without messing up the stream of 12 bit values.
Best Answer
In the past Baudot code was popular 5-bit code used with telegraph machines. The idea of being able to shift between letters and figures gave it coverage of uppercase letters, numeric and other common punctuation symbols above the usual total of 32 you'd expect from a 5-bit number.
ASCII is a 7-bit code (although often now transmitted as 8 bits regardless) so that explains why that was common. I'd never heard of six bits being used but presumably in the past if it was worthwhile to cover five, seven and eight bits handling six bits added no additional complexity, but more likely is Michael Karas' answer in that regard that six bit encoding was also popular as well.