0
votes

I have a weight cell which replies to specific frames over RS485 (cell contains its own communication protocol). Manufacturer has a software to test the cell so I connect it to my pc using a RS485 to USB converter and I am able to connect to the cell and send/receive frames. Here are the parameters I use and you can see TX-RX frames below:

enter image description here enter image description here

Now I want to manage this protocol with a STM32 board but I am not receiving frames properly. I am using NUCLEO-F401RE and RS485 CAN Shield from Waveshare (https://www.waveshare.com/wiki/RS485_CAN_Shield). Here is what I do and my UART configuration:

Main program

int main(void)
{
  HAL_Init();

  SystemClock_Config();

  MX_GPIO_Init();

  GPIO_InitStruct.Pin = GPIO_PIN_8;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  MX_USART1_UART_Init();
  MX_USART2_UART_Init();

  printf("NUCLEOF401RE - RS485 RX\r\n");

  while (1)
  {
        // Activate sending status
        HAL_GPIO_WritePin (GPIOA, GPIO_PIN_8, 1);

        txBuffer[0] = 0x44; // SOF
        txBuffer[1] = 0x01; // DIR
        txBuffer[2] = 0x00; // ERR
        txBuffer[3] = 0x25; // CMD
        txBuffer[4] = 0x00; // DATOS0
        txBuffer[5] = 0x00; // DATOS1
        txBuffer[6] = 0x00; // DATOS2
        txBuffer[7] = 0x00; // DATOS3
        txBuffer[8] = txBuffer[1] ^ txBuffer[2] ^ txBuffer[3] ^ txBuffer[4] ^ txBuffer[5] ^ txBuffer[6] ^ txBuffer[7]; // CRC
        txBuffer[9] = 0x0A; // EOF

        printf("TX - Sending frame\r\n");
        HAL_UART_Transmit(&UART_RS485, txBuffer, framelength, 1000);

        // Activate receiving status
        HAL_GPIO_WritePin (GPIOA, GPIO_PIN_8, 0);

        HAL_UART_Receive(&UART_RS485, rxBuffer, framelength, 1000);
        printf("RX - Reception Completed:\r\n");
        for(int j=0; j<framelength; j++)
        {
            printf("Byte %d: %02X\r\n", j, rxBuffer[j]);
        }
        HAL_Delay(3000);
  }

UART Configuration

static void MX_USART1_UART_Init(void)
{
    UART_RS485.Instance = USART1;
    UART_RS485.Init.BaudRate = 115200;
    UART_RS485.Init.WordLength = UART_WORDLENGTH_8B;
    UART_RS485.Init.StopBits = UART_STOPBITS_1;
    UART_RS485.Init.Parity = UART_PARITY_NONE;
    UART_RS485.Init.Mode = UART_MODE_TX_RX;
    UART_RS485.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    UART_RS485.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&UART_RS485) != HAL_OK)
  {
    Error_Handler();
  }
}
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(huart->Instance==USART1)
  {
      __HAL_RCC_USART1_CLK_ENABLE();

      __HAL_RCC_GPIOA_CLK_ENABLE();

      GPIO_InitStruct.Pin = GPIO_PIN_9;
      GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
      GPIO_InitStruct.Pull = GPIO_NOPULL;
      GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
      GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
      HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

      GPIO_InitStruct.Pin = GPIO_PIN_10;
      GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
      GPIO_InitStruct.Pull = GPIO_PULLUP;
      GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
      GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
      HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  }

I should be receiving a frame starting with 0x44 and ending with 0x0A based on the cell protocol. However, this is what I receive:

enter image description here

I have tried many different UART parameters, many different pin configurations and tried using a 120 ohm and 220 ohm resistors between A and B lines but nothing works. What am I missing?

1

1 Answers

0
votes

I suggest you to see: Uart Status Register of you STM32 uc (because you could see UART errors like parity error, frame error and buffer overflow). In my work UART errors very often were related to buffer overflow because uc usually have a very small buffer (for ATmega 32 - 2 bytes).

Also i suggest you to use mode with parity bit, because it a data check in any case.

Also have you calculate you UART error (depends on you clock frequency and UART speed). You also could select UART speed with 0 % of errors.

You could see article about status register and baud rate here: http://www.micromouseonline.com/2009/12/31/stm32-usart-basics/