freemodbus移植
基于freemodbus1.6
使用HAL库
软件:stm32cubemx stm32cubeide后续会更新标准库的移植。以及rtos下的移植(尽量)
下载freemodbus1.6
这个获取方法网上到处都是,不细说了。
cubemx新建工程
新建工程只列出了与移植freemodbus相关的设置
这里我使用的是485通信,所以额外使能了一个引脚
使能一个定时器,这里我用的是tim2。并且开始定时器2中断
其他设置如下图,参数其实设什么无所谓,因为后面要改的,我们并不用系统的初始化函数。
然后使能一个串口,我这里用的串口1,参数其实设什么无所谓,因为后面要改的,
这里可以把串口1和定时器2的最前面的取消勾选,就不会生成他们的初始化函数,不勾也没有太大关系,因为我们的函数在他之后,会覆盖掉系统的设置。
另外在中断优先级设置中,将串口优先级设置高于定时器2,数字越小越高。
相关的中断处理函数也要生成。
然后就可以generate code!生成代码。
代码修改
首先我们在我们项目的根目录中新建一个freemodbus文件夹,文件夹中再建一个modbus文件夹,一个port文件夹。
把你最开始下载下来的freemodbus中modbus文件夹中的内容复制到你刚才的modbus文件夹中,
把你最开始下载下来的freemodbus中demo/bare路径下的内容全部复制到你刚才的port文件夹中
然后我们进入cubeide,右键项目->属性,配置头文件和源文件路径。
把如图六个头文件路径添加。
把如图最下面两个源文件路径添加。
先在port.h文件中补充这两个宏定义,这是HAL库的全局中断开启、关闭函数。
ok,然后我们修改portserail.c
这两个函数前面的static标志去掉。
vMBPortSerialEnable函数修改如下
void
vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable )
{
/* If xRXEnable enable serial receive interrupts. If xTxENable enable
* transmitter empty interrupts.
*/
if (xRxEnable) //将串口收发中断和modbus联系起来,下面的串口改为自己使能的串口
{
__HAL_UART_ENABLE_IT(&huart2,UART_IT_RXNE); //我用的是串口2,故为&huart2
HAL_GPIO_WritePin(EN485_GPIO_Port, EN485_Pin, GPIO_PIN_RESET);//
}
else
{
__HAL_UART_DISABLE_IT(&huart2,UART_IT_RXNE);
HAL_GPIO_WritePin(EN485_GPIO_Port, EN485_Pin, GPIO_PIN_SET);//
}
if (xTxEnable)
{
HAL_GPIO_WritePin(EN485_GPIO_Port, EN485_Pin, GPIO_PIN_SET);//
__HAL_UART_ENABLE_IT(&huart2,UART_IT_TXE);
}//
else
{
HAL_GPIO_WritePin(EN485_GPIO_Port, EN485_Pin, GPIO_PIN_RESET);//
__HAL_UART_DISABLE_IT(&huart2,UART_IT_TXE);
}
}
串口初始化函数如下
BOOL
xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity )
{
huart2.Instance = USART2;
huart2.Init.BaudRate = ulBaudRate;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
switch(eParity)
{
// 奇校验
case MB_PAR_ODD:
huart2.Init.Parity = UART_PARITY_ODD;
huart2.Init.WordLength = UART_WORDLENGTH_9B; // 带奇偶校验数据位为9bits
break;
// 偶校验
case MB_PAR_EVEN:
huart2.Init.Parity = UART_PARITY_EVEN;
huart2.Init.WordLength = UART_WORDLENGTH_9B; // 带奇偶校验数据位为9bits
break;
// 无校验
default:
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.WordLength = UART_WORDLENGTH_8B; // 无奇偶校验数据位为8bits
break;
}
return HAL_UART_Init(&huart2) == HAL_OK ? TRUE : FALSE;
}
收发字节函数如下
BOOL
xMBPortSerialPutByte( CHAR ucByte )
{
/* Put a byte in the UARTs transmit buffer. This function is called
* by the protocol stack if pxMBFrameCBTransmitterEmpty( ) has been
* called. */
HAL_GPIO_WritePin(EN485_GPIO_Port, EN485_Pin, GPIO_PIN_SET);//
if(HAL_UART_Transmit (&huart2 ,(uint8_t *)&ucByte,1,10) != HAL_OK )
return FALSE ;//HAL_UART_Transmit最后一位形参为最大发送时间,
//超出改时间退出发送,可能导致485发送失败,可稍微长一点。
else
return TRUE;
}
BOOL
xMBPortSerialGetByte( CHAR * pucByte )
{
/* Return the byte in the UARTs receive buffer. This function is called
* by the protocol stack after pxMBFrameCBByteReceived( ) has been called.
*/
HAL_GPIO_WritePin(EN485_G