设为首页 加入收藏

TOP

freemodbus移植进STM32(包含HAL库和标准库两种方法)(一)
2023-07-23 13:26:04 】 浏览:101
Tags:freemodbus STM32 包含 HAL 方法

freemodbus移植

基于freemodbus1.6
使用HAL库
软件:stm32cubemx stm32cubeide

后续会更新标准库的移植。以及rtos下的移植(尽量)

下载freemodbus1.6

这个获取方法网上到处都是,不细说了。

cubemx新建工程

新建工程只列出了与移植freemodbus相关的设置
这里我使用的是485通信,所以额外使能了一个引脚
image
使能一个定时器,这里我用的是tim2。并且开始定时器2中断
image
其他设置如下图,参数其实设什么无所谓,因为后面要改的,我们并不用系统的初始化函数。
image
然后使能一个串口,我这里用的串口1,参数其实设什么无所谓,因为后面要改的,
image
这里可以把串口1和定时器2的最前面的取消勾选,就不会生成他们的初始化函数,不勾也没有太大关系,因为我们的函数在他之后,会覆盖掉系统的设置。
image

另外在中断优先级设置中,将串口优先级设置高于定时器2,数字越小越高。
image
相关的中断处理函数也要生成。
image

然后就可以generate code!生成代码。

代码修改

首先我们在我们项目的根目录中新建一个freemodbus文件夹,文件夹中再建一个modbus文件夹,一个port文件夹。
image
把你最开始下载下来的freemodbus中modbus文件夹中的内容复制到你刚才的modbus文件夹中,
image
把你最开始下载下来的freemodbus中demo/bare路径下的内容全部复制到你刚才的port文件夹中
image

然后我们进入cubeide,右键项目->属性,配置头文件和源文件路径。
image
把如图六个头文件路径添加。
image
把如图最下面两个源文件路径添加。
image

先在port.h文件中补充这两个宏定义,这是HAL库的全局中断开启、关闭函数。
image

ok,然后我们修改portserail.c
这两个函数前面的static标志去掉。
image
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
首页 上一页 1 2 3 4 5 下一页 尾页 1/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇驱动开发:内核读写内存浮点数 下一篇位段/位域 的使用

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目