news 2026/7/7 14:31:26

FreeModbus+STM32F407IGT6标准库项目代码

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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

测试的效果

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/7 11:02:10

拥抱AI,HPE Networking以“自动驾驶的网络”引领智能网络新时代

2025年12月16日&#xff0c;HPE Networking在北京举办以“拥抱AI&#xff0c;构建自动驾驶的网络”为主题的媒体沟通会&#xff0c;首次对外分享了在完成对 Juniper Networks 收购后所推出的全新战略路线&#xff1a;以构建“安全赋能的AI原生网络”为核心举措&#xff0c;打造…

作者头像 李华
网站建设 2026/7/7 2:04:27

基于springboot名老中医传承信息系统设计与开发

基于Spring Boot的名老中医传承信息系统设计与开发是一个结合了现代信息技术和传统中医智慧的综合性项目。以下是对该系统的详细介绍&#xff1a; 一、系统背景与意义 中医作为中华民族的传统医学&#xff0c;承载着丰富的历史文化底蕴与独特的医疗智慧。在历史的长河中&#x…

作者头像 李华
网站建设 2026/7/7 12:24:58

潮玩盲盒二手交易平台

可s我领取源码!!Spring Boot 潮玩盲盒二手交易平台是一款专为潮玩盲盒爱好者打造的线上二手交易系统。借助 Spring Boot 框架的高效性和灵活性&#xff0c;该平台旨在为用户提供便捷、安全且功能丰富的交易环境&#xff0c;促进潮玩盲盒的二手流通&#xff0c;满足玩家对独特潮…

作者头像 李华
网站建设 2026/7/6 3:40:28

除了抓包失败,Burp Suite还有哪些新手常遇到的配置问题?

除了抓包失败&#xff0c;Burp Suite新手还常遇到以下配置问题&#xff1a;一、证书配置问题证书未正确信任是新手最常遇到的HTTPS抓包问题。即使下载了Burp的CA证书&#xff0c;如果未导入到浏览器的"受信任的根证书颁发机构"存储区&#xff0c;浏览器仍会提示"…

作者头像 李华
网站建设 2026/7/7 9:15:41

Spring Boot 开发入门:从 0 到 1 搭建第一个 Web 项目

前言 Spring Boot 是由 Pivotal 团队推出的基于 Spring 框架的轻量级开发框架&#xff0c;它简化了 Spring 应用的配置流程&#xff0c;通过 “约定大于配置” 的核心思想&#xff0c;让开发者无需繁琐的 XML 配置就能快速搭建和运行项目。本文将从环境准备、项目创建、核心代…

作者头像 李华
网站建设 2026/7/7 6:45:29

JSP 指令

JSP 指令 引言 JavaServer Pages(JSP)是一种用于创建动态网页的技术。在JSP页面中,指令是一种特殊的元素,用于在JSP页面中提供配置信息。JSP指令可以影响JSP页面的编译、加载和执行过程。本文将详细介绍JSP指令的相关知识,包括其类型、语法和用途。 JSP指令的类型 JSP…

作者头像 李华