当前位置: 首页 > news >正文

FreeModbus+STM32F407IGT6标准库项目代码

FreeModbus移植的文章比较多了,分享一个移植好可用的代码。

代码连接:STM32F407IGT6移植FreeModbushttps://gitee.com/zhuzheshuai/STM32F407IGT6_FreeModbus

通信使用串口和RS485两种方式,RS485发送/接收使能引脚用的PH9,可以根据实际电路进行修改。原理图和代码。

#include "bsp_usart.h" void USART3_Init(uint32_t baud) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; GPIO_StructInit(&GPIO_InitStructure); USART_StructInit(&USART_InitStructure); GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_USART3); GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_USART3); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = baud; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_Init(USART3, &USART_InitStructure); USART_Cmd(USART3, ENABLE); NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } void USART1_Init(uint32_t baud) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; GPIO_StructInit(&GPIO_InitStructure); USART_StructInit(&USART_InitStructure); GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1); GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = baud; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_Init(USART1, &USART_InitStructure); USART_Cmd(USART1, ENABLE); NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } void RS485_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_StructInit(&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOH, &GPIO_InitStructure); GPIO_WriteBit(GPIOH, GPIO_Pin_9, Bit_RESET); } int fputc(int ch, FILE *f) { USART_SendData(USART1, (uint8_t)ch); while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); return ch; } int fgetc(FILE *f) { /* 等待串口1输入数据 */ while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET); return (int)USART_ReceiveData(USART1); }

用了条件编译,如果Modbus通讯用的串口,注释 #define EN_RS485;如果用RS485需要修改对应串口引脚号和RS485的使能引脚。

portserial.c

/* * FreeModbus Libary: BARE Port * Copyright (C) 2006 Christian Walter <wolti@sil.at> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * File: $Id$ */ #include "port.h" /* ----------------------- Modbus includes ----------------------------------*/ #include "mb.h" #include "mbport.h" /* ----------------------- User includes ----------------------------------*/ #include "bsp_usart.h" #define SLAVE_RS485_RECEIVE_MODE GPIO_WriteBit(GPIOH, GPIO_Pin_9, Bit_SET) #define SLAVE_RS485_SEND_MODE GPIO_WriteBit(GPIOH, GPIO_Pin_9, Bit_RESET) #define EN_RS485 /* ----------------------- static functions ---------------------------------*/ static void prvvUARTTxReadyISR( void ); static void prvvUARTRxISR( void ); /* ----------------------- Start implementation -----------------------------*/ void vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable ) { /* If xRXEnable enable serial receive interrupts. If xTxENable enable * transmitter empty interrupts. */ #ifdef EN_RS485 if(xRxEnable == TRUE) { SLAVE_RS485_RECEIVE_MODE; USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); } else { SLAVE_RS485_SEND_MODE; USART_ITConfig(USART3, USART_IT_RXNE, DISABLE); } if(xTxEnable == TRUE) { USART_ITConfig(USART3, USART_IT_TXE, ENABLE); } else { USART_ITConfig(USART3, USART_IT_TXE, DISABLE); } #else 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); } #endif } BOOL xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity ) { #ifdef EN_RS485 USART3_Init((uint32_t)ulBaudRate); #else USART1_Init((uint32_t)ulBaudRate); #endif return TRUE; } 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. */ #ifdef EN_RS485 SLAVE_RS485_SEND_MODE; USART_SendData(USART3, (uint16_t)ucByte); while(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET); SLAVE_RS485_RECEIVE_MODE; #else USART_SendData(USART1, (uint16_t)ucByte); #endif 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. */ #ifdef EN_RS485 *pucByte = (CHAR)USART_ReceiveData(USART3); #else *pucByte = (CHAR)USART_ReceiveData(USART1); #endif return TRUE; } /* Create an interrupt handler for the transmit buffer empty interrupt * (or an equivalent) for your target processor. This function should then * call pxMBFrameCBTransmitterEmpty( ) which tells the protocol stack that * a new character can be sent. The protocol stack will then call * xMBPortSerialPutByte( ) to send the character. */ static void prvvUARTTxReadyISR( void ) { pxMBFrameCBTransmitterEmpty( ); } /* Create an interrupt handler for the receive interrupt for your target * processor. This function should then call pxMBFrameCBByteReceived( ). The * protocol stack will then call xMBPortSerialGetByte( ) to retrieve the * character. */ static void prvvUARTRxISR( void ) { pxMBFrameCBByteReceived( ); } #ifdef EN_RS485 void USART3_IRQHandler(void) { if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) { prvvUARTRxISR(); USART_ClearITPendingBit(USART3, USART_IT_RXNE); } if(USART_GetITStatus(USART3, USART_IT_ORE) != RESET) { USART_ClearITPendingBit(USART3, USART_IT_ORE); prvvUARTRxISR(); } if(USART_GetITStatus(USART3, USART_IT_TXE) != RESET) { prvvUARTTxReadyISR(); USART_ClearITPendingBit(USART3, USART_IT_TXE); } } #else void USART1_IRQHandler(void) { if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) { prvvUARTRxISR(); USART_ClearITPendingBit(USART1, USART_IT_RXNE); } if(USART_GetITStatus(USART1, USART_IT_ORE) != RESET) { USART_ClearITPendingBit(USART1, USART_IT_ORE); prvvUARTRxISR(); } if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET) { prvvUARTTxReadyISR(); USART_ClearITPendingBit(USART1, USART_IT_TXE); } } #endif

后续增加了FreeRTOS

测试的效果

http://www.cnnetsun.cn/news/115836.html

相关文章:

  • 基于Spring Boot人才招聘管理系统
  • 拒绝“魔法值”注入:手把手教你实现 Spring Boot 高性能枚举校验注解 @InEnum
  • 国内容易上手的claudecode一键配置指南
  • 复原IP地址
  • Redis 发布订阅
  • JQuery支持WebUploader完成百万文件断点续传的原理?
  • Vue3如何结合组件实现大文件分片的并行上传优化?
  • 类型分布统计-Cordovaopenharmony多维分析实战
  • 四时四名,一山万象:朝鲜金刚山的锦绣风姿
  • 基于Spring Boot的果蔬销售系统
  • Scala Collection(集合)
  • 介观交通流仿真软件:DynusT_(11).交通事件管理
  • django基于Python天气分析系统
  • python基于大数据的分析长沙旅游景点推荐系统
  • 基于Django的学分管理系统
  • 广度优先遍历与最短路径
  • 通信系统仿真:通信系统基础理论_(11).光通信技术
  • 17、Linux文件与目录操作全解析
  • 21、Linux系统进程与包管理全解析
  • 二叉排序树的插入、先序/中序/后序/层次遍历、节点查询
  • 如何在 Spring Boot 中接入 Amazon ElastiCache
  • 基于51单片机的血糖步数测量仪
  • Linux C/C++ 学习日记(51):内存池
  • AAAI25|基于神经共形控制的时间序列预测模型
  • CATCH:ICLR 2025 最值得关注的时间序列异常检测新框架
  • 开发到生产全链路:Docker containerd Kubernetes 运行时全景指南
  • 文件包含漏洞终极指南
  • #扫雷游戏
  • Java计算机毕设之基于springboot+vue的高校学院校内订餐系统的设计与实现基于JAVA的学院校内订餐系统的实现(完整前后端代码+说明文档+LW,调试定制等)
  • 小程序计算机毕设之基于微信跑腿小程序的设计与实现基于springboot+微信小程序的跑腿小程序的设计与实现(完整前后端代码+说明文档+LW,调试定制等)