FreeModbus开源协议栈的移植和详解(四)
概述
在前面几篇文章中,对FreeModbus文件的源码进行了分析,还剩下与平台相关的接口部分,在这里通过对FreeModbus在STM32上的移植过程为例来介绍FreeModbus的接口部分。
一、移植前的准备
移植FreeModbus之前需要准备好FreeModbus源码,关于源码的获取方式,参考我之前的文章:
https://blog.youkuaiyun.com/u014100102/article/details/90453930
STM32的工程,这个在此不做说明,只要之前做过STM32的对STM32工程的建立都比较熟悉了。
总结:
移植前需要准备:
1、FreeModbus源码
2、STM32基础工程
二、将FreeModbus文件源码添加到STM32工程中
1、在工程中新建FreeModbus文件夹,将Modbus文件夹中的所有文件及文件夹复制进来。
2、将FreeModbus-v1.6->demo->AVR->port文件夹复制到STM32工程中的FreeModbus文件夹中。并将文件添加到工程中。
3、文件添加好之后,来开始看port文件夹下的文件。里面的文件需要修改,移植到STM32平台上,就可以使用了。
三、PORT文件夹修改
1、port.h文件
port.h文件主要定义了FreeModbus使用到的数据类型定义,这里和平台相关的有一个,就是进出临界区的定义,不同的MCU的定义不同,STM32修改如下:
#define ENTER_CRITICAL_SECTION() __set_PRIMASK(1) //关总中断
#define EXIT_CRITICAL_SECTION() __set_PRIMASK(0) //开总中断
此外,头文件也需要修改,包含stm32的头文件
#include "stm32f10x.h"
2、portserial.c
port serial.c文件夹中是实现底层串口的相关函数。这里先贴出代码。
#include "port.h"
/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mbport.h"
/**控制串口发送和接收中断**/
void
vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable )
{
if(xRxEnable == TRUE)
{
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //接收非空中断
}
else
{
USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
}
if(xTxEnable == TRUE)
{
USART_ITConfig(USART1, USART_IT_TXE, ENABLE); //发送中断空
}
else
{
USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
}
}
BOOL
xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity )
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* prevent compiler warning. */
(void)ucPORT;
//USART1端口配置
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟
//USART1_TX PA.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA9
//USART1_RX PA.10
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA10
USART_InitStructure.USART_BaudRate = ulBaudRate;
if(ucDataBits == 9)
USART_InitStructure.USART_WordLength = USART_WordLength_9b; // 9位数据 ;
else
USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 8位数据 ;
if(eParity == MB_PAR_ODD)
USART_InitStructure.USART_Parity = USART_Parity_Odd; // 奇校验;
else if(eParity == MB_PAR_EVEN)
USART_InitStructure.USART_Parity = USART_Parity_Even; // 偶校验;
else
USART_InitStructure.USART_Parity = USART_Parity_No; // 无校验位;
USART_InitStructure.USART_StopBits = USART_StopBits_1; // 在帧结尾传输1个停止位 ;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 硬件流控制失能 ;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // 接收发送使能 ;
USART_Init(USART1, &USART_InitStructure);
// USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);