logo资料库

STM32上移植FreeModbus RTU.pdf

第1页 / 共18页
第2页 / 共18页
第3页 / 共18页
第4页 / 共18页
第5页 / 共18页
第6页 / 共18页
第7页 / 共18页
第8页 / 共18页
资料共18页,剩余部分请下载后查看
STM32 上移植 FreeModbus RTU 前 段 时 间 了 解 了 一 下 Modbus 协 议 , 移 植 了 一 次 , 不 成 功 http://www.openedv.com/thread-67471-1-1.html,不过找到方法之后,再次完善 在官网上面下载源码,度娘上面有些被人家修改过的,喜欢原汁原味的朋友去官网上下载, 本贴附件也附上源码。 开发平台:原子哥探索者开发板 V2.2 编译环境:MDK5.17 STM32 官方库函数:V1.5.1 FreeModbu 版本:V1.6.0 一、解压 freemodbus v1.6 源码 看到如下文件目录结构 文件夹 demo 就是官方针对不同平台移植的测试代码 文件夹 doc 是一些说明性文档 文件夹 modbus 就是功能实现的源码所在了 文件夹 tools 是上位机软件 德阳瑞能电力科技有限公司(李清林)
图一、FREEMODBUS V1.6 压缩后 MODBUS 文件夹内容 图二、FREEMODBUS V1.6 压缩后 DEMO 文件夹内容 图三、FREEMODBUS V1.6 压缩后 DEMO\BARE 文件夹内容 德阳瑞能电力科技有限公司(李清林)
图四、FREEMODBUS V1.6 压缩后 DEMO\BARE\port 文件夹内容 德阳瑞能电力科技有限公司(李清林)
二、建立工程 2.1 、 新 建 一 个 工 程 ( 这 个 就 随 意 了 ), 工 程 项 目 所 有 的 文 件 夹 名 为 RMC215+FreeModbus+USART1+TIM2,在该文件夹内再建立一个文件夹 FreeModbus,然后 在文件夹 FreeModbus 下再分别建立一个 modbus 文件夹和 port 文件夹,参见下图。 图五、工程项目所在文件夹下创建一个 FREEMODBUS 文件夹 图六、工程项目所在文件夹 FREEMODBUS 下创建 modbus 文件夹和 port 文件夹 2.2 、 将 FreeModbusV1.6 下 的 modbus 所 有 文 件 夹 及 文 件 拷 贝 到 新 建 工 程 项 目 FreeModbus 文件夹下的 modbus 子文件夹下。 德阳瑞能电力科技有限公司(李清林)
2.3、进入 FreeModbusV1.6 下的 demo 文件夹,看到有各个平台的测试代码文件夹,没 看到 STM32 的,但是看到 BARE 这个不带任何平台的代码文件,将 FreeModbusV1.6 下 \demo\BARE\port 下的所有文件拷贝到新建工程项目 FreeModbus 文件夹下\port 文件夹中。 其中: (1)、port.h 需要修改。 (2)、porteven.c 不需要任何修改 (3)、portserial.c 需要修改 (4)、porttimer.c 需要修改。 (5)、另外还需要在 main 函数增加 4 个回调函数。 (5.1 )、 操 作 输入 寄 存 器 的回 调 函 数 eMBErrorCode eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs ) (5.2)、操作保持寄存器的回调函数 eMBErrorCode eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode ) ( 5.3 )、 操 作 线 圈 的 的 回 调 函 数 eMBErrorCode eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode ) (5.4)、操作离散寄存器的的回调函数 eMBErrorCode eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete ) 德阳瑞能电力科技有限公司(李清林)
2.3、打开 MDK(用 IAR 也行,随意了),建立工程。。。(省略 1 万字) 下图是我创建好的移植工程项目。 三、添加代码 3.1、打开 portserial.c 文件,这个是移植串口的,不管是 ASCII 模式还是 RTU 模式都需 要串口支持的,void vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable )函数,使能 或失能串口的,移植代码如下: void vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable ) { /* If xRXEnable enable serial receive interrupts. If xTxENable enable 德阳瑞能电力科技有限公司(李清林)
* transmitter empty interrupts. */ if (xRxEnable) //接收使能 { USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); //使能接收中断 GPIO_ResetBits(GPIOG, GPIO_Pin_8); //设置 RS485 接收 } else //失能 { USART_ITConfig(USART2, USART_IT_RXNE, DISABLE); //失能接收中断 GPIO_SetBits(GPIOG, GPIO_Pin_8); //设置 RS485 发送 } if (xTxEnable) //发送使能 { USART_ITConfig(USART2, USART_IT_TC, ENABLE); //使能 GPIO_SetBits(GPIOG, GPIO_Pin_8); //设置 RS485 发送 } else //失能 { USART_ITConfig(USART2, USART_IT_TC, DISABLE); //失能 GPIO_ResetBits(GPIOG, GPIO_Pin_8); //设置 RS485 接收 } } 3.1.1、串口初始化函数 BOOL xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity ),使用的是串口 2 进行通讯 BOOL xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity ) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; (void)ucPORT; //不修改串口号 (void)ucDataBits; //不修改数据位长度 (void)eParity; //不修改检验格式 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOG, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); // //管脚复用 德阳瑞能电力科技有限公司(李清林)
// GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2); GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2); // //发送管脚 PA.02 //接收管脚 PA.03 // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOA, &GPIO_InitStructure); // //485 芯片发送接收控制管脚 // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOG, &GPIO_InitStructure); // //配置串口参数 // USART_InitStructure.USART_BaudRate = ulBaudRate; //只修改波特率 USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Parity = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART2, &USART_InitStructure); // //使能串口 // USART_Cmd(USART2, ENABLE); // //配置中断优先级 // NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); 德阳瑞能电力科技有限公司(李清林)
分享到:
收藏