cancel
Showing results for 
Search instead for 
Did you mean: 

Single byte transmission is not working in USART on STM32f411 nucleo-f411re board PC6/PC7 pin used

Prasannaraj
Visitor

Hi Team,

Currently I am doing bare-metal programming in STM32F411 using Nucleo-F411RE board.

For USART6, I am trying to transmit string and bytes, in this string is working fine, but for single byte transmission it is not working?

 

void rcc_config(void)
{
  RCC->CR     |= 1 << 0;                  // HSI on
  while(!(RCC->CR & (1 << 1)));           // wait until HSI on

  RCC->AHB1ENR |= (1 << 2) | (1 << 0); // Enable GPIO A & CFGR
  RCC->APB1ENR |= (1 << 28); // Power Interface clock enable
  RCC->APB2ENR |= (1 << 5) | (1 << 8); // Enable ADC and USART6
}

void uart_init(void)
{
  USART6->CR1 &= ~(1 << 12); // 1:8N1
  USART6->CR1     |= 1 << 9;              // Parity Selection
  USART6->CR1 |= 1 << 7; // TXE interrupt enable 
  USART6->CR1 |= 1 << 6; // TCIE enable 
  USART6->CR1 |= 1 << 5; // RXNE interrupt enable 
  USART6->CR1 |= 1 << 3; // TE enable 
  USART6->CR1 |= 1 << 2; // RE enable
  USART6->CR2     |= 0x00 << 12;          // 1 Stop bit
  USART6->CR2     &= ~(1 << 11);          // CLK disabled
  USART6->CR3     &= ~(1 << 3);           // FD is selected
  USART6->CR3     &= ~(1 << 9);           // CTS disable
  USART6->CR3     &= ~(1 << 8);           // RTS disable
  USART6->CR3     |= (1 << 11);           // One bit sample
  USART6->BRR |= 0x08B; // 115200
  USART6->CR1 |= 1 << 13; // Enable USART6 UE
}

void gpio_init(void)
{
  RCC->AHB1ENR |= (1 << 2); // PC6/7 - Tx/Rx
  GPIOC->MODER |= (2 << 12) | (2 << 14); // AF mode for PC6/7 
  GPIOC->OTYPER   &= ~(1 << 6);
  GPIOC->OTYPER   &= ~(1 << 7);
  GPIOA->MODER    |= ((0x3 << (AN0 * 2)) | (0x3 << (AN1 * 2)));      // set 0b11 for AN0 & AN1
  GPIOC->OSPEEDR |= (1 << 12) | (1 << 14); // Medium speed
  GPIOC->AFR[0] |= (8 << 24) | (8 << 28); // USART6 on AF8
}


void Uart_tx(int data)
{
    while(!(USART6->SR & (1 << 7)))
    {
    }
    USART6->DR = data & 0x1FF; 
    while(!(USART6->SR & USART_SR_TC));
}

void Uart_transmit_str(char *data)
{
  uint8_t size = strlen(data);

  while(size--)
  {
    Uart_tx(*data++);
  }

  while(!(USART6->SR & (1 << 6)));
}

int main(void)
{
    rcc_config();
    uart_init();
    gpio_init();
    Uart_transmit_str("ADC turned ON!!!\n\r");

    while(1)
    {
       Uart_tx('B');
    }
}

 

Let me the any correction needed in the code?

Edited to apply proper code formatting - please see How to insert source code for future reference.
2 REPLIES 2
gbm
Principal

1. Use bit names from MCU header file instead of magic numbers to avoid simple mistakes.

2. Set BRR before enabling UART in CR1. (ok, this one is actually correct, but it is enough to write the whole CR1 after BRR). Just assigne BRR, don't do |= on it.

3. Use single assignments instead of sequences of boolean operations on CR2 and CR1. For basic UART operation, you only need to write to BRR and then to CR1, no need to touch CR2, CR3.

4. Don't transmit a character without any pause in the main loop.

5. Don't enable interrupts if you don't plan to service them.

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice

While all items by @gbm  above are valid, I've just tried and it does transmit 'B' continuously.

However, whatever receiver you are using, it may be confused by a continuous stream with no gaps.

JW