2020-11-20 10:25 AM
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
2020-11-20 04:49 PM
> 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
2020-11-23 12:21 PM
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++;
}
}