0

I'm trying to exchange data between 2 stm32f407 boards through uart. The peripheral that I'm using is the USART2 (there are more of them on the board). I've configured it with a baud rate of 9600, 8 bit frame, no parity bits and only 1 stop bit. The strange thing that happens is that the receiver gets a lot of null bytes (to be more precise sometimes there are 9 consecutive null bytes, while in other cases 8 null bytes ended by a 0xFF byte) before the data that I'm actually sending. This seems to happen only when I turn on the sender or when I press its reset button, if I send the same data multiple times in a row everything is fine. This is the code that I use to setup the uart as described:

int uart_init ()
{
    unsigned int ra;

    ra=GET32(RCC_AHB1ENR);
    ra|=1<<0; //enable port A
    PUT32(RCC_AHB1ENR,ra);

    ra=GET32(RCC_APB1ENR);
    ra|=1<<17; //enable USART2
    PUT32(RCC_APB1ENR,ra);

    //PA2 USART2_TX
    //PA3 USART2_RX

    ra=GET32(GPIOA_MODER);
    ra|= (2<<4);
    ra|= (2<<6);
    PUT32(GPIOA_MODER,ra);
    ra=GET32(GPIOA_OTYPER);
    ra&=(1<<2);
    ra&=(1<<3);
    PUT32(GPIOA_OTYPER,ra);
    ra=GET32(GPIOA_AFRL);
    ra|=(7<<8);
    ra|=(7<<12);
    PUT32(GPIOA_AFRL,ra);

    // divisor 136 fractional divisor 11
    PUT32(USART2_BRR,(136<<4)|(11<<0));
    PUT32(USART2_CR1,(1<<13)|(1<<3)|(1<<2));
    return(0);
}

While this is my routine to send a byte through uart:

void uart_putc ( unsigned int x )
{
    while (( GET32(USART2_SR) & (1<<7)) == 0) continue;
    PUT32(USART2_DR,x);
}

My question is: is this a normal and reasonable behavior? In case it is, what is a good strategy to receive the stream of incoming bytes discarding those that are undesired? In case it is not, what am I doing wrong?

user3768186
  • 5
  • 1
  • 5

1 Answers1

2

It's because during the interval between reset and the pins being configured for AFIO they're in a high-impedance state so attempts to read will return undefined data. Your receiver is becoming ready before your transmitter.

To guard against this you need to indicate readiness through an out of band method or if your resets are electrically linked then a dumb method such as sleeping for a second on the receiver and 2 seconds on the transmitter upon startup and after the pins have been configured for AFIO should do it.

Andy Brown
  • 11,766
  • 2
  • 42
  • 61
  • Thank you for the answer. Even if what you say seems pretty reasonable, there's something not clear to me. Indeed I'm testing my transmitter using a RS232 adapter to connect it to a PC and see the output on a terminal (I use SerialMon to sniff the data). Well the strange thing is that when I use a different UART, for example UART1, this problem doesn't happen, it only affects UART2. It is, isn't it? What do you think? – user3768186 Oct 09 '14 at 15:01
  • Well, if you're using PA9/10 for USART1 on the discovery then you'll notice that those pins are also wired to other peripherals (LED, a USB pin). It's possible that they're being externally pulled to a fixed level by the board. – Andy Brown Oct 09 '14 at 15:57