USB to RS485 converter

Summary of USB to RS485 converter


This article details a DIY USB to RS485 converter project using an STM32F0 microcontroller. It explains how to interface modern PCs with legacy RS485 devices by converting USB signals via UART, utilizing the hardware driver enable feature of the STM32F0. The guide covers hardware design files, PCB layouts for toner transfer, and C code logic for bidirectional data transmission and dynamic serial line coding configuration (baud rate, parity, stop bits).

Parts used in the USB to RS485 Converter:

  • STM32F0 microcontroller
  • FTDI interfaces or assembled USB to RS485 modules
  • RS485 driver chip
  • Altium project files
  • PDF documentation
  • Mirrored PCB layout for toner transfer
  • Assembling sheet

USB to RS485 converter

g PC without proper interface is not possible. Since RS232 interfaces are very rare, the interface should be hooked to USB. The interface between USB and RS485 can be soldered with one of the many FTDI interfaces with added RS485 driver, or bought as assembled module. There is always the third option. I made it from scratch.

I took smallest STM32F0 with USB and UART interface. The best thing with UART in the STM32F0 is that signal for driver enable is provided within hardware. The complete pinout of the microcontroller is:

Here is complete altium project: USB-RS485

The documentation in PDF file: USB2RS485-doc

For all who want to produce the PCB with the toner transfer technology is here the PCB, mirrored and with 1:1 scale: USB2RS232-tonertransfer

And the most useful sheet of documentation for assembling:

The project, generated from the MX cube is almost all we need. There are few things to add:

  • retransmit bytes received from USB to UART
  • forward bytes received via UART to USB
  • add serial line coding interpretation and reflect it in the hardware UART

The code for sending bytes from UART to USB is within main endless loop:

if (HAL_UART_Receive_IT(&huart2, &aRxBuffer, 1) == HAL_OK) 
   CDC_Transmit_FS(&aRxBuffer,1)

Code to send data from USB to UART is within CDC_Receive_FS() function:

static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len)
{
 /* USER CODE BEGIN 6 */
 USBD_CDC_SetRxBuffer(hUsbDevice_0, &Buf[0]);
 USBD_CDC_ReceivePacket(hUsbDevice_0);
 HAL_UART_Transmit(&huart2, Buf, *Len, 100);
 return (USBD_OK);
 /* USER CODE END 6 */ 
}

And finally, the code to set the UART line parameters are within USB CDC_Control_FS() function:

  /*******************************************************************************/
 /* Line Coding Structure */
 /*-----------------------------------------------------------------------------*/
 /* Offset | Field | Size | Value | Description */
 /* 0 | dwDTERate | 4 | Number |Data terminal rate, in bits per second*/
 /* 4 | bCharFormat | 1 | Number | Stop bits */
 /* 0 - 1 Stop bit */
 /* 1 - 1.5 Stop bits */
 /* 2 - 2 Stop bits */
 /* 5 | bParityType | 1 | Number | Parity */
 /* 0 - None */
 /* 1 - Odd */ 
 /* 2 - Even */
 /* 3 - Mark */
 /* 4 - Space */
 /* 6 | bDataBits | 1 | Number Data bits (5, 6, 7, 8 or 16). */
 /*******************************************************************************/
 case CDC_SET_LINE_CODING: 
 linecoding.bitrate = (uint32_t)(pbuf[0] | (pbuf[1] << 8) | (pbuf[2] << 16) | (pbuf[3] << 24));
 linecoding.format = pbuf[4];
 linecoding.paritytype = pbuf[5];
 linecoding.datatype = pbuf[6];
 huart2.Init.BaudRate = linecoding.bitrate;
 switch (linecoding.format)
 {
 case 0 : huart2.Init.StopBits = UART_STOPBITS_1; break;
 case 1 : huart2.Init.StopBits = UART_STOPBITS_1_5; break;
 case 2 : huart2.Init.StopBits = UART_STOPBITS_2; break;
 }
 switch (linecoding.paritytype)
 {
 case 0 : huart2.Init.Parity = UART_PARITY_NONE; break;
 case 1 : huart2.Init.Parity = UART_PARITY_ODD; break;
 case 2 : huart2.Init.Parity = UART_PARITY_EVEN; break;
 }
 //UART_WORDLENGTH_7B
 switch (linecoding.datatype)
 {
 case 7 : huart2.Init.WordLength = UART_WORDLENGTH_7B; break;
 case 8 : huart2.Init.WordLength = UART_WORDLENGTH_8B; break;
 }
 HAL_RS485Ex_Init(&huart2, UART_DE_POLARITY_HIGH, 0, 0);
 
 break;

The complete project is hosted on GitHub>>> https://github.com/s54mtb/USB2RS485

The driver for the USB/CDC device class can be downloaded from: http://www.st.com/content/st_com/en/products/development-tools/software-development-tools/stm32-software-development-tools/stm32-utilities/stsw-stm32102.html  or local copy: VCP_V1.4.0_Setup

I will use this small module for testing sensors, which I have under development for my vineyard weather station: humidity, air pressure, temperature, wind, illumination, soil parameters, etc…

For more detail: USB to RS485 converter

Quick Solutions to Questions related to USB to RS485 Converter:

  • Why is a custom interface necessary for this project?
    RS232 interfaces are rare on modern PCs, so the connection must be hooked to USB.
  • What makes the STM32F0 suitable for this design?
    The best feature is that the signal for the driver enable is provided within the hardware.
  • How does the code handle bytes received from the UART?
    The main endless loop uses HAL_UART_Receive_IT to receive one byte and CDC_Transmit_FS to send it to USB.
  • Where is the code for sending data from USB to UART located?
    This code is within the CDC_Receive_FS function which calls HAL_UART_Transmit.
  • How are serial line parameters configured dynamically?
    The USB CDC_Control_FS function parses the Line Coding Structure to set bitrate, stop bits, parity, and data bits.
  • What specific serial parameters can be adjusted via the software?
    Users can adjust Data terminal rate, Stop bits, Parity type, and Data bits.
  • Where can the complete project source code be found?
    The project is hosted on GitHub at the link provided by s54mtb.
  • Which driver should be downloaded for the USB/CDC device class?
    The VCP_V1.4.0_Setup driver from STMicroelectronics should be downloaded.

About The Author

Ibrar Ayyub

I am an experienced technical writer holding a Master's degree in computer science from BZU Multan, Pakistan University. With a background spanning various industries, particularly in home automation and engineering, I have honed my skills in crafting clear and concise content. Proficient in leveraging infographics and diagrams, I strive to simplify complex concepts for readers. My strength lies in thorough research and presenting information in a structured and logical format.

Follow Us:
LinkedinTwitter