添加文件

  1. 获取原始free modbus library(官网
  2. 将...\freemodbus-v1.5.0\demo\BARE中的所有文件复制到...\freemodbus-v1.5.0\modbus中,修改demo.c文件名为user_mb_app.c
  3. 将...\freemodbus-v1.5.0\modbus中的所有.c文件全部添加到项目中
  4. 在项目路径中添加所有.c、.h文件路径

添加完成后项目结构图:

stm32--free modbus 1.5.0移植(作为从机)

移植修改

需要修改的文件:

  1. port.h:补全开关总中断的宏定义、宏定义串口和定时器
    #define ENTER_CRITICAL_SECTION( )   __set_PRIMASK(1); //关闭中断
    #define EXIT_CRITICAL_SECTION( )    __set_PRIMASK(0); //开启中断
  2. portserial.c:补全串口相关函数(串口中断使能选择、串口初始化、发送1字节、接收1字节、串口中断服务函数)
    • 注意事项:
      1. 使能中断:发送中断应使用TC而非TXE,否则可能会出现最后一个字节不能成功发送的情况。此外由于是用485发送,所以在使能中断时,应同时转换485收发转换引脚。使能中断前,应判断对应的标志位是否为1,为1则清除该标志位。
      2. 串口初始化:初始化前用USART_DeInit重置寄存器;引脚初始化(GPIO)->串口初始化(USART)->中断初始化(NVIC);参数中的ucPORT和eParity都应该忽略。
      3. 发送1字节:不用循环等待发送完成,因为已经有发送完成中断了
      4. 串口中断服务函数:在stm32f0xx_it.c中添加USART3_4_IRQHandler函数,跳转到本文件中的prvvModbusUARTISR函数。
    •   1 /*
        2  * FreeModbus Libary: BARE Port
        3  * Copyright (C) 2006 Christian Walter <wolti@sil.at>
        4  *
        5  * This library is free software; you can redistribute it and/or
        6  * modify it under the terms of the GNU Lesser General Public
        7  * License as published by the Free Software Foundation; either
        8  * version 2.1 of the License, or (at your option) any later version.
        9  *
       10  * This library is distributed in the hope that it will be useful,
       11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       13  * Lesser General Public License for more details.
       14  *
       15  * You should have received a copy of the GNU Lesser General Public
       16  * License along with this library; if not, write to the Free Software
       17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
       18  *
       19  * File: $Id: portserial.c,v 1.1 2006/08/22 21:35:13 wolti Exp $
       20  */
       21 
       22 #include "port.h"
       23 
       24 /* ----------------------- Modbus includes ----------------------------------*/
       25 #include "mb.h"
       26 #include "mbport.h"
       27 
       28 /* ----------------------- static functions ---------------------------------*/
       29 static void prvvUARTTxReadyISR( void );
       30 static void prvvUARTRxISR( void );
       31 
       32 #define MODBUS_SEND()     (GPIO_SetBits(MODBUS_USART_CTRL_PORT, MODBUS_USART_CTRL_PIN))
       33 #define MODBUS_RECIEVE()  (GPIO_ResetBits(MODBUS_USART_CTRL_PORT, MODBUS_USART_CTRL_PIN))
       34 
       35 /* ----------------------- Start implementation -----------------------------*/
       36 void
       37 vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable )
       38 {
       39   /* If xRXEnable enable serial receive interrupts. If xTxENable enable
       40    * transmitter empty interrupts.
       41    */
       42   if(xRxEnable==TRUE) {
       43     MODBUS_RECIEVE();
       44     if(USART_GetFlagStatus(MODBUS_USART, USART_FLAG_RXNE) == SET) {
       45       USART_ClearFlag(MODBUS_USART, USART_FLAG_RXNE);
       46     }
       47     USART_ITConfig(MODBUS_USART, USART_IT_RXNE, ENABLE);
       48   } else if(xRxEnable == FALSE) {
       49     MODBUS_SEND();
       50     USART_ITConfig(MODBUS_USART, USART_IT_RXNE, DISABLE);
       51   }
       52   
       53   if(xTxEnable==TRUE) {
       54     MODBUS_SEND();
       55     if(USART_GetFlagStatus(MODBUS_USART, USART_FLAG_TC) == SET) {
       56       USART_ClearFlag(MODBUS_USART, USART_FLAG_TC);
       57     }
       58     USART_ITConfig(MODBUS_USART, USART_IT_TC, ENABLE);
       59   } else if(xTxEnable == FALSE) {
       60     MODBUS_RECIEVE();
       61     USART_ITConfig(MODBUS_USART, USART_IT_TC, DISABLE);
       62   }
       63 }
       64 
       65 BOOL
       66 xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity )
       67 {
       68   /*****************************引脚初始化*************************************/
       69   GPIO_InitTypeDef  GPIO_InitStructure;
       70   
       71   //时钟使能
       72   RCC_AHBPeriphClockCmd(MODBUS_USART_TX_CLK | MODBUS_USART_RX_CLK | MODBUS_USART_CTRL_CLK, ENABLE);
       73   MODBUS_USART_CLK_INIT(MODBUS_USART_CLK, ENABLE);
       74   
       75   //复用功能定义
       76   GPIO_PinAFConfig(MODBUS_USART_TX_PORT, MODBUS_USART_TX_SOURCE, MODBUS_USART_TX_AF);
       77   GPIO_PinAFConfig(MODBUS_USART_RX_PORT, MODBUS_USART_RX_SOURCE, MODBUS_USART_RX_AF);
       78   
       79   //引脚功能定义
       80   GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
       81   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
       82   GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_DOWN;
       83   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3; //50MHz
       84   
       85   //TX
       86   GPIO_InitStructure.GPIO_Pin = MODBUS_USART_TX_PIN;
       87   GPIO_Init(MODBUS_USART_TX_PORT, &GPIO_InitStructure);
       88   
       89   //RX
       90   GPIO_InitStructure.GPIO_Pin = MODBUS_USART_RX_PIN;
       91   GPIO_Init(MODBUS_USART_RX_PORT, &GPIO_InitStructure);
       92   
       93   //CTRL
       94   GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;
       95   GPIO_InitStructure.GPIO_Pin   = MODBUS_USART_CTRL_PIN;
       96   GPIO_Init(MODBUS_USART_CTRL_PORT, &GPIO_InitStructure);
       97   MODBUS_RECIEVE(); //接收模式
       98   
       99   /*****************************串口初始化*************************************/
      100   USART_InitTypeDef USART_InitStructure;
      101   
      102   USART_InitStructure.USART_BaudRate    = ulBaudRate;
      103   USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
      104   USART_InitStructure.USART_Mode        = USART_Mode_Rx|USART_Mode_Tx;
      105   USART_InitStructure.USART_Parity      = USART_Parity_No;
      106   USART_InitStructure.USART_StopBits    = USART_StopBits_1;
      107   USART_InitStructure.USART_WordLength  = USART_WordLength_8b;
      108   
      109   USART_Init(MODBUS_USART, &USART_InitStructure);
      110   USART_Cmd(MODBUS_USART, ENABLE);
      111   vMBPortSerialEnable(FALSE, FALSE);
      112   
      113   /*****************************中断初始化*************************************/
      114   NVIC_InitTypeDef  NVIC_InitStructure;
      115   
      116   NVIC_InitStructure.NVIC_IRQChannel          = USART3_4_IRQn;
      117   NVIC_InitStructure.NVIC_IRQChannelCmd       = ENABLE;
      118   NVIC_InitStructure.NVIC_IRQChannelPriority  = 1;
      119   
      120   NVIC_Init(&NVIC_InitStructure);
      121   
      122   return TRUE;
      123 }
      124 
      125 BOOL
      126 xMBPortSerialPutByte( CHAR ucByte )
      127 {
      128   /* Put a byte in the UARTs transmit buffer. This function is called
      129    * by the protocol stack if pxMBFrameCBTransmitterEmpty( ) has been
      130    * called. */
      131   MODBUS_USART->TDR = ucByte; //此处不用等待发送完毕(TC),因为有发送完成中断
      132   return TRUE;
      133 }
      134 
      135 BOOL
      136 xMBPortSerialGetByte( CHAR * pucByte )
      137 {
      138   /* Return the byte in the UARTs receive buffer. This function is called
      139    * by the protocol stack after pxMBFrameCBByteReceived( ) has been called.
      140    */
      141   *pucByte = MODBUS_USART->RDR;
      142   return TRUE;
      143 }
      144 
      145 /* Create an interrupt handler for the transmit buffer empty interrupt
      146  * (or an equivalent) for your target processor. This function should then
      147  * call pxMBFrameCBTransmitterEmpty( ) which tells the protocol stack that
      148  * a new character can be sent. The protocol stack will then call 
      149  * xMBPortSerialPutByte( ) to send the character.
      150  */
      151 static void prvvUARTTxReadyISR( void )
      152 {
      153     pxMBFrameCBTransmitterEmpty(  );
      154 }
      155 
      156 /* Create an interrupt handler for the receive interrupt for your target
      157  * processor. This function should then call pxMBFrameCBByteReceived( ). The
      158  * protocol stack will then call xMBPortSerialGetByte( ) to retrieve the
      159  * character.
      160  */
      161 static void prvvUARTRxISR( void )
      162 {
      163     pxMBFrameCBByteReceived(  );
      164 }
      165 
      166 void  prvvModbusUARTISR( void )
      167 {
      168   if(USART_GetITStatus(MODBUS_USART, USART_IT_TC) == SET) {
      169     prvvUARTTxReadyISR();
      170     USART_ClearITPendingBit(MODBUS_USART, USART_IT_TC);
      171   }
      172 
      173   if(USART_GetITStatus(MODBUS_USART, USART_IT_RXNE) == SET) {
      174     prvvUARTRxISR();
      175     USART_ClearITPendingBit(MODBUS_USART, USART_IT_RXNE);
      176   }
      177 }
      portserial.c

相关文章:

  • 2021-10-18
  • 2022-12-23
  • 2021-04-22
  • 2021-06-07
  • 2022-12-23
  • 2021-05-09
  • 2021-12-27
  • 2022-01-20
猜你喜欢
  • 2022-12-23
  • 2021-05-25
  • 2021-07-01
  • 2021-06-04
  • 2021-12-30
  • 2022-12-23
  • 2021-12-02
相关资源
相似解决方案