STM32F0使用LL庫實現Modbus通信

  在本次項目中,限於空間要求咱們選用了STM32F030F4做爲控制芯片。這款MCU不但封裝緊湊,並且自帶的Flash空間也很是有限,因此咱們選擇了LL庫實現。本篇將說明基於LL實現USART通信。編程

1、概述函數

  咱們想要實現基於RS485Modbus通信實際就是基於USART的通信。USART使用可編程波特率發生器提供很是普遍的波特率範圍。根據不一樣配置能夠實現咱們不一樣的串行通信應用需求。其結構圖以下:測試

 

  咱們在USART基礎上實現一個Modbus的從站應用,因此咱們對於接收採用中斷接收,而對於發送則根據接收到的信息作出反饋。因此咱們要根據接收狀態和發送狀態來肯定咱們的操做。ui

2USART配置spa

  在實現以前,咱們來了解一下知足前述的需求,咱們應該作哪些配置。主要有2個寄存器須要注意:控制寄存器1USART_CR1和波特率寄存器(USART_BRR)。調試

  首先咱們仍是來看一看控制寄存器1USART_CR1)。其中RXNEIERXNE中斷使能)、TE(發送使能)、RE(接收使能)、UEUSART使能)等位是須要咱們注意的。該寄存器的結構以下:blog

 

  在控制寄存器1USART_CR1中,RXNEIERXNE中斷使能)被置位後,只要USART_ISRORE=1或者RXNE=1就會產生該中斷。接下來咱們看一看波特率寄存器(USART_BRR),其結構以下:it

 

  對於波特率寄存器(USART_BRR),顧名思義就是設置波特率。但波特率的值不是隨意設置,有一套計算方法,能夠查看STM的手冊。io

3、軟件實現監控

  接下來咱們在軟件上實現咱們的應用。咱們先看USART配置,咱們將其配置爲咱們須要的參數,並將其配置爲中斷接收模式。具體代碼以下:

/*配置上位通信串口*/

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);   

}

  大部分配置均可經過初始化函數來實現,有一些需同過專門的LL庫函數實現。配置完成後寄存器的狀態以下圖所示。

 

  咱們配置的波特率是115200,其在寄存器中的配置爲1A1,關於波特率的配置問題能夠查看相關資料。另外咱們還須要編寫一個接收中斷的服務函數。

/*數據接收中斷處理函數,添加到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);

  }

}

  須要注意的是須要添加ORE溢出標誌的檢測,確保每次的接收中斷都是有效的。

4、總結

  最後咱們來測試一下咱們的代碼。將相關項目下載到目標板並採用兩種監測方式查看結果。首先接到PC機的串口,在上位中使用Modscan來查看,其結果以下:

 

  而後經過J-Link在線調試監控數據通信,其結果以下:

 

  上圖中,上部是咱們的物理量數據,而下面是接收到的上位下發的讀取保持寄存器的Modbus報文。結合前一張圖,很明顯收發都是正確的。

歡迎關注:

相關文章
相關標籤/搜索