Search code examples
cavratmelusart9-bit-serial

AVR 9 bit Usart not working (MPCM)


So there is Master and Slave Attiny2313. The Master sends the 9 bits of data(the 9th bit TXB8 is set to 1), but the slave doesn't detect the 9th bit(RXB8 is still 0). I think if the TXB8 bit is set in the Master the RXB8 bit on the Slave should be set automatically, or not? (In the code i check if RXB8 in UCSRB is set to 1. And it isn't, that is the problem)

void USART_Init(void)
{
    /* Set baud rate */
    UBRRH = (unsigned char)(BAUDRATE>>8);
    UBRRL = (unsigned char)BAUDRATE;

    /* Enable receiver and transmitter */
    UCSRB = (1<<RXEN)|(1<<TXEN);

    /* Set frame format: 9data, 1stop bit */
    UCSRC = (7<<UCSZ0);
}

void USART_Transmit(unsigned int data)
{
    /* Wait for empty transmit buffer */
    while ( !( UCSRA & (1<<UDRE)) );

    /* Copy 9th bit to TXB8 */
    UCSRB &= ~(1<<TXB8);
    if ( data & 0x0100 )
        UCSRB |= (1<<TXB8);

    /* Put data into buffer, sends the data */

    UDR = data;

//Slave Receive Code

gned int USART_Receive( void )
{
    unsigned char status, resh, resl;

    /* Wait for data to be received */
    while ( !(UCSRA & (1<<RXC)) );



    /* Get status and 9th bit, then data from buffer */
    status = UCSRA; 
    resh = UCSRB;
    resl = UDR;
        return resh; ///test
    /* If error, return -1 */
    if ( status & ((1<<FE)|(1<<DOR)|(1<<UPE)) )
    return -1;

    /* Filter the 9th bit, then return */
    resh = (resh >> 1) & 0x01;  
    return ((resh << 8) | resl);

}

Solution

  • I found what was the problem, the USART was initialised like this:

    /* Enable receiver and transmitter */
        UCSRB = (1<<RXEN)|(1<<TXEN);
    
        /* Set frame format: 9data, 1stop bit */
        UCSRC = (7<<UCSZ0);
    

    But the UCSZ2 bit is in the USCRB register and not in UCSRC, so the right code will be:

    UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<UCSZ2);
    UCSRC  = (1<<UCSZ0)|(1<<UCSZ1);