The Atmega supports 9 bit data, but the Arduino library doesn’t. Your only option using it (at least currently) is odd or even parity for the 9th data bit, there is no mark of space parity made available in via the library. This is a problem when communicating on say RS485 busses where mark and space parity is used as an address byte marker for instance, so that all the slaves on the bus can be interrupted check the address byte to see if its them and if not then ignore the remainder of the packet on the bus with the 9th bit set to the alternative state. The Atmega, like many microcontrollers, supports this, but the Arduino library doesn’t.
Ways to create 9 bit transmit data
Manipulate parity setting to give parity bit state you need
Transmit using flush() to wait while each byte is sent, and then altering the odd/even parity setting ahead of each byte to cause the parity to be the state you require for the 9th data bit you want. For mark parity you can also set parity to off and the number of stop bits to 2 (8N2). For space parity you must calculate the required odd/even parity setting to cause a space bit.
Bit bash
Bit bash your own transmit by disabling interrupts and manipulating the transmit pin at the required BAUD rate.
Change the microcontroller UART port setup
//Atmeag2560 9 bit tx and receive example using Serial2. Change every occurance of "2" to 0, 1 or 3 to use one of the other ports
Serial2.begin(250000, SERIAL_8N1);
while(!Serial2)
;
//Change 8bit mode to 9bit mode (UCSZn1|UCSZn0 will already have been set to 11 by selecting 8N1, we just need to set UCSZn2 to change it to become 9N1
UCSR2B |= 0x04; //Bit4 of UCSR2B is the UCSZn2 bit
//How to transmit a 9 bit byte
Serial2.flush(); //Wait for last byte to have been sent
UCSR2B |= 0x01; //Write 9th bit. Bit0 of UCSR2B is the 9th data bit (TXB8n), must be set or cleared before each byte is transmitted
//UCSR2B &= ~0x01;
Serial2.write(0x55); //Write bits 7:0
//Receiving 9 bit data will just occur as normal, but using this approach you simply won't be able to read the 9th bit (the 9th byte is written to RXB8n but it has to be read before each byte is read from UDRn, if you need to read it then you'll have to write your own receive handler).
Ways to create 9 bit receive data
Using standard library
There doesn’t seem to be a way to do this using the library without hacking it to access the ATmega registers directly. This has been done by people in the past but it seems there has never been enough demand to cause it to become a feature of the main library. If you use one of the odd/even parity settings you will miss all bytes which fail the parity setting as these will simply be dumped by the serial library.
Bit bash
Bit bash your own receive by disabling interrupts and monitoring the receive pin looking for the start bit and then timing and capturing each bit up to the stop bit.
Change the microcontroller UART port setup
See example in transmit section above
2 years ago
super util la informacion