cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F404VG USART 9 bit communication

Tcubells
Associate II

I am working on a system where I send HEX commands through the USART3 of the STM32F407VG to the COM machine with its corresponding PC.

The particularity of this communication is that in each sending of frames, the first byte of the frame must be sent with the wake up bit activated. (9 bits - 9n1), the rest of the bytes must be sent with the wake up deactivated (8 bits - 8N1)

I have used this code in the CUBE ID but it doesn't work

    void EnviarComando(uint8_t cmdEnTx[], int lenEnTx)
      {
                    int InterByte = 5; // Tiempo Interbyte
           int i = 1;
        /*Envío del primer byte (address) en 9 bits */
           huart3.Init.WordLength = UART_WORDLENGTH_9B;
        
           HAL_UART_Transmit(&huart3, cmdEnTx, 1, InterByte);
        /*Envío del resto de bytes en 8 bits */
        huart3.Init.WordLength = UART_WORDLENGTH_8B;
        
        while (i< lenEnTx)
        {
         
        HAL_UART_Transmit(&huart3, &cmdEnTx[i], 1, InterByte);
        i++;
        
        }
      }

The initial configuration of the USART 3 is this:

    static void MX_USART3_UART_Init(void)
    {
     
      huart3.Instance = USART3;
      huart3.Init.BaudRate = 19200;
      huart3.Init.WordLength = UART_WORDLENGTH_8B;
      huart3.Init.StopBits = UART_STOPBITS_1;
      huart3.Init.Parity = UART_PARITY_NONE;
      huart3.Init.Mode = UART_MODE_TX_RX;
      huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
      huart3.Init.OverSampling = UART_OVERSAMPLING_16;
      if (HAL_UART_Init(&huart3) != HAL_OK)
      {
        Error_Handler();
      }
     
    } 

The same I did with Arduino Mega and it works perfectly acting on the bits of the UART register.

This is the code I used for the Mega 2560

    void sendCommand(byte temp[], int len) //Envío de trama a EGM 
    {
      UCSR1B = 0b10011101; //9 bits on 
      serEgm.write(temp[0]); //envía primer byte( address máquina )
      delay(5); //Default 1
      UCSR1B = 0b10011100; //9 bits off
      for (int i=1; i<len;i++)
      {
        serEgm.write(temp[i]); //envía el resto de bytes de la trama
        delay(5);//Default 1
      }
    } 

I am blocked with this matter, so I appreciate in advance any ideas or contributions that allow me to solve this problem

Regards

11 REPLIES 11
Pavel A.
Evangelist III

> I am working on a system where I send HEX commands through the USART3 of the STM32F407VG to the COM machine with its corresponding PC.

A PC likely will have a problem with 9-bit characters where the 9th bit is not used for parity or set permanently to 0/1 (aka "mark"/"space").

Unless there is a specialized UART adapter on the PC side, such as FTDI in "advanced" mode or another microcontroller with USB interface.

-- pa

Tcubells
Associate II

Hello everyone

I've finally gotten it to work,

I have followed the suggestion from waclawek.jan to enable 9 bits

The problem was how to insert these statements in my code with the HAL library format.

Finally I have found the way to do it and with the help of the reference manual I have added two more sentences, activate the parity control (PCE - bit 10) and activate the Wake Up (WAKE - bit 11)

huart3.Instance-> CR1 | = USART_CR1_M

huart3.Instance-> CR1 | = USART_CR1_WAKE

huart3.Instance-> CR1 | = USART_CR1_PCE

With this temporary configuration I can send the first byte of the frame as recommended by the specifications of the protocol I use, for the rest of the frame you just have to disable wake up and parity control.

Initially the USART must be set to 8 bits, once it makes the first activation to 9 bits, only when this function is called will it activate the WAKE UP (11) and Parity Control (10) bits, the rest of the program flow will work with these bits off.

I tried setting to 9 bit from the start and it doesn't work, I don't know why.

I attach the final code of the function that is working

Thank you all

void EnviarComando(uint8_t cmdEnTx[], int lenEnTx)
		{
 
                int InterByte = 1;//Tiempo Interbyte
			    int i = 1;
			    
				/*Envío del primer byte (address) en 9 bits M=1; WakeUP=1; PCE=1*/
 
			    huart3.Instance->CR1 |= USART_CR1_M; // 9 bits on
			    huart3.Instance->CR1 |= USART_CR1_PCE; // parity control enable
			    huart3.Instance->CR1 |= USART_CR1_WAKE; // wake up on*/
 
 
				HAL_UART_Transmit(&huart3, (uint16_t*)&cmdEnTx[0], 1, InterByte);
 
 
 
				/*Envío del resto de bytes WakeUp=0 and PCE=0 */
 
				huart3.Instance->CR1 &= ~USART_CR1_PCE; // parity control disable
				huart3.Instance->CR1 &= ~USART_CR1_WAKE; // wake up off*/
 
 
				while (i< lenEnTx)
				{
				HAL_UART_Transmit(&huart3, &cmdEnTx[i], 1, InterByte);
				i++;
				}
		}