cancel
Showing results for 
Search instead for 
Did you mean: 

Single byte transmission is not working in USART on nucleo-f411re

Prasannaraj
Associate

Hi Team,

Currently I am doing bare-metal programming in STM32F411 using Nucleo-F411RE board; pins PC6/PC7.

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.
4 REPLIES 4
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

Prasannaraj
Associate

Thanks the feedback.. But still i face issue with USART, i cant print properly

#include "stm32f411xe.h"
#include <stdio.h>
#include <string.h>

#define AN0         0
#define AN1         1
#define MAX         21

void rcc_config(void);
void uart_init(void);
void gpio_init(void);
void adc_init(void);
void adc_read(void);

void Uart_tx(char data);
void Uart_transmit_str(char *data);

volatile uint16_t an0_data = 0;
volatile uint16_t an1_data = 0;
char arr[MAX];

int main(void)
{
    char *buf;
    int len = MAX;
    rcc_config();
    uart_init();
    gpio_init();
    adc_init();
   
    Uart_transmit_str("ADC Testing!!!\n\r");
    while(1)
    {
        adc_read();
        Uart_transmit_str("ADC Values\n\r");
        snprintf(arr, MAX, "A0: %u\nA1: %u\n",an0_data, an1_data);
       
        buf = &arr;
        while(len--)
        {
            Uart_tx(*buf++);
        }
        // Simple delay
        for (volatile int i = 0; i < 1000000; i++);      
        Uart_transmit_str("End\n\r");
    }
}
 
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->BRR     |= 0x08B;               // 115200
    //   0010 0000 1110 1100 -> 0x20EC
    USART6->CR1 |= 0x200C;
}

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 adc_init(void)
{
    // Enable Scan, Interrupt disable @ EOC
    ADC1->CR1 |= 0x0100 ;  // 0b 0000 0001 0000 0000

    // EOC enable, CONT disable, ADC ON
    ADC1->CR2 |= 0x0401;   // 0b 0000 0100 0000 0001

    // Sample time - 56 cycles
    ADC1->SMPR2 |= 0x3 << 3 | 0x3 << 0;  // 0b 011 011

    // Regular sequence
    ADC1->SQR1 |= 1<<20;   // 2 Conversion
    ADC1->SQR3 |= 0<<0 | 1<<5;
}

void adc_read(void)
{
    // Start ADC Conversion
    ADC1->CR2 |= ADC_CR2_SWSTART;

    // Wait for conversion to finish (by checking EOC (End of Conversion) flag)
    while (!(ADC1->SR & ADC_SR_EOC));

    an0_data = (uint16_t)ADC1->DR;         // Read the data  - AN0
    an1_data = (uint16_t)ADC1->DR;         // Read the data  - AN1
}

void Uart_tx(char data)
{
   //int i = 50;
    while(!(USART6->SR & USART_SR_TXE))
    {
    }
    USART6->DR = data & 0x1FF;
    //while(!(USART6->SR & USART_SR_TC));       // with & without this its working

   // while(i){ i--;}
}

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

    while(size--)
    {
        Uart_tx(*data++);
    }
    while(!(USART6->SR & (1 << 6)));
}
 
/// ADC values are not printing 
Prasannaraj_0-1741187915876.png

 



Let me what is the problem in this..


Please use the '</>' icon at the top of editor, when posting code.

At the first glance, I don't see anything very wrong with your code, but that was the case with the first piece of code, too. Did you get it working as expected?

JW