STM32F0 LL library implementation using Modbus communication

In this project, we chose the limited space requirements STM32F030F4 as a control chip. The MCU is not only a compact package comes with Flash and space is very limited, so we chose LL library implementation. This article deals explanation based on LL achieve USART communication.

1 Overview

We want to achieve communication based on Modbus RS485 is based on the actual communication of USART. USART programmable baud rate generator provides a very wide range of baud rates. We can implement different serial communications application requirements depending on the configuration. Its structure is as follows:

We achieve USART application on the basis of a Modbus slave, so we use for receiving interrupt reception, and for the transmission is made to the received feedback information. So we have to be determined according to our reception state and transmission operating status.

2, USART configuration

Before implementation, we look at the previous meet demand, we should do what the configuration. There are two registers Note: control register 1 (USART_CR1) and baud rate register (USART_BRR).

First we take a look at the control register 1 (USART_CR1). Which RXNEIE (RXNE interrupt enable), TE (Transmit Enable), RE (Receive Enable), UE (USART enable) allelic need our attention. The structure of the register is as follows:

In the control register 1 (USART_CR1) in, RXNEIE (RXNE interrupt enable) after being set, as long as USART_ISRORE = 1 or RXNE = 1 will generate the interrupt. Next we look at the baud rate register (USART_BRR), the following structure:

For Baud Rate Register (USART_BRR), the name suggests is set the baud rate. But the value is not free to set the baud rate, a set of calculation methods, you can view the STM's manual.

3, software

Next we implement our application on the software. We look at the configuration of the USART, we will configure it as an argument that we need, and configure it to interrupt reception mode. Specific code as follows:

/*配置上位通讯串口*/
static void Comm_UART_Configuration(void)
{
  LL_USART_InitTypeDef USART_InitStruct = {0};

  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* 使能相关外设时钟 */
  LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_USART1);
  LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA);
  
  /* USART1 GPIO 配置:PA2   ------> USART1_TX
                       PA3   ------> USART1_RX  */
  GPIO_InitStruct.Pin = LL_GPIO_PIN_2;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
  GPIO_InitStruct.Alternate = LL_GPIO_AF_1;
  LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = LL_GPIO_PIN_3;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
  GPIO_InitStruct.Alternate = LL_GPIO_AF_1;
  LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /* USART1中断初始化 */
  NVIC_SetPriority(USART1_IRQn, 1);
  NVIC_EnableIRQ(USART1_IRQn);

  /* USART1端口配置 */
  USART_InitStruct.BaudRate = 115200;
  USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B;
  USART_InitStruct.StopBits = LL_USART_STOPBITS_1;
  USART_InitStruct.Parity = LL_USART_PARITY_NONE;
  USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX;
  USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;
  USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16;
  LL_USART_Init(USART1, &USART_InitStruct);
  LL_USART_DisableIT_CTS(USART1);
  LL_USART_ConfigAsyncMode(USART1);
  LL_USART_Enable(USART1);

  LL_USART_EnableIT_RXNE(USART1);   
}

Most of the configuration can be achieved through the initialization function, there are too special to be with LL library routines. After the configuration status register is shown below.

We configure the baud rate is 115200, which is disposed register as 1A1, on configuration issues baud rate can review data. In addition, we also need to write a function to receive uninterrupted service.

/*数据接收中断处理函数,添加到USART1中断响应函数中*/
void USART1_ReceiveDataHandle(void)
{
  if(rxLength>=RECEIVEDATALENGTH)
  {
    rxLength=0;
  }

  /*接收寄存器为空,等待字节被对应的串口完全接收*/
  if(LL_USART_IsActiveFlag_RXNE(USART1))
  {
    uint8_t rData;
    /*获取接收到的字节*/
    rData=LL_USART_ReceiveData8(USART1);
    rxBuffer[rxLength++] = rData;
  }
  
  if(LL_USART_IsActiveFlag_ORE(USART1))
  {
    LL_USART_ClearFlag_ORE(USART1);
  }
}

Note that you need to add overflow detection ORE logo, to ensure that each receive interrupt is valid.

4, summary

Finally, we have to test our code. Related items downloaded to the target board and monitor in two ways to view the results. First, to the serial port of the PC, use Modscan in the upper view with the following results:

Then debug monitor traffic through the J-Link line with the following results:

Figure above, the upper portion of our physical quantity data, the following is issued by the host to read the received Modbus registers holding packets. Ago combine a map, it is clear that the transceiver is correct.

Welcome concern:

Published 77 original articles · won praise 277 · Views 140,000 +

Guess you like

Origin blog.csdn.net/foxclever/article/details/88935376