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

美好乡村建设网站广州公关公司

美好乡村建设网站,广州公关公司,建设信用卡网站更改账单日,求网站2021在线观看代码地址 STM32MODBUSRTU: stm32上的modbus工程 从站 FreeModbus是一个开源的Modbus通信协议栈实现。它允许开发者在各种平台上轻松地实现Modbus通信功能,包括串口和以太网。FreeMODBUS提供了用于从设备和主站通信的功能,支持Modbus RTU和Modbus TCP协…

代码地址

STM32MODBUSRTU: stm32上的modbus工程

从站

FreeModbus是一个开源的Modbus通信协议栈实现。它允许开发者在各种平台上轻松地实现Modbus通信功能,包括串口和以太网。FreeMODBUS提供了用于从设备和主站通信的功能,支持Modbus RTU和Modbus TCP协议。在工业控制和自动化领域广泛应用。

  FreeModBus可通过官方网站下载:FreeMODBUS

参考文章:FreeModbus RTU 从机Hal库裸机移植避坑指南 - Atul-8 - 博客园

1. STM32CubeMX 配置流程

我假设你已经学会使用stm32cubeMX点灯了;

1.1下载模式配置

1.2 定时器配置

为了实现一个1750us的超时计时定时器,其中计算过程如下,使用内部时钟8M,预分配399+1,及400/8m=50us,计数周期为34+1,也就是35*50us=1750us

1.3 串口配置

1.4 中断配置

关闭自动生成中断函数,因为需要在freemodbus源码里添加这两个函数。

2.库文件导入

2.1 .c文件汇总

2.2 .h文件汇总

2.3 demo文件选择

3. 移植流程

ok 完成上述步骤后, 你就可以开始正式的移植工作了:

主要需要移植的地方为: portserial.c && porttimer.c && demo.c

E:\STM32CubeIDE\Workspace\FreeMODBUSRTUSlave\modbus\include\mbconfig.h

文件中将ASCII关闭

E:\STM32CubeIDE\Workspace\FreeMODBUSRTUSlave\modbus\rtu\mbrtu.c

文件中有两处断言需要调整,我不清楚为什么,但是我的不修改会进入断言

E:\STM32CubeIDE\Workspace\FreeMODBUSRTUSlave\modbus\port\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"
#include "main.h"
#include "usart.h"
/* ----------------------- static functions ---------------------------------*/
static void prvvUARTTxReadyISR( void );
static void prvvUARTRxISR( void );extern UART_HandleTypeDef huart1;/* ----------------------- Start implementation -----------------------------*/
void
vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable )
{/* If xRXEnable enable serial receive interrupts. If xTxENable enable* transmitter empty interrupts.*/if (xRxEnable) {__HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);} else {__HAL_UART_DISABLE_IT(&huart1, UART_IT_RXNE);}if (xTxEnable) {__HAL_UART_ENABLE_IT(&huart1, UART_IT_TXE);} else {__HAL_UART_DISABLE_IT(&huart1, UART_IT_TXE);}
}BOOL
xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity )
{MX_USART1_UART_Init();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. */USART1->DR = ucByte;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.*/*pucByte = (USART1->DR & (uint16_t)0x00FF);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(  );
}void USART1_IRQHandler(void)
{if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXNE)){__HAL_UART_CLEAR_FLAG(&huart1, UART_FLAG_RXNE);	prvvUARTRxISR();// __HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);}if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_TXE)){__HAL_UART_CLEAR_FLAG(&huart1, UART_FLAG_TXE);			prvvUARTTxReadyISR();}
//    HAL_UART_IRQHandler(&huart1);
}

E:\STM32CubeIDE\Workspace\FreeMODBUSRTUSlave\modbus\port\porttimer.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$*//* ----------------------- Platform includes --------------------------------*/
#include "port.h"/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mbport.h"
#include "main.h"
/* ----------------------- static functions ---------------------------------*/
static void prvvTIMERExpiredISR( void );extern TIM_HandleTypeDef htim4;
/* ----------------------- Start implementation -----------------------------*/static void MX_TIM4_Init(void)
{TIM_ClockConfigTypeDef sClockSourceConfig = {0};TIM_MasterConfigTypeDef sMasterConfig = {0};htim4.Instance = TIM4;htim4.Init.Prescaler = 399;htim4.Init.CounterMode = TIM_COUNTERMODE_UP;htim4.Init.Period = 34;htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;if (HAL_TIM_Base_Init(&htim4) != HAL_OK) {Error_Handler();}sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK) {Error_Handler();}sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK) {Error_Handler();}
}BOOL
xMBPortTimersInit( USHORT usTim1Timerout50us )
{MX_TIM4_Init();__HAL_TIM_CLEAR_FLAG(&htim4, TIM_FLAG_UPDATE);      __HAL_TIM_ENABLE_IT(&htim4, TIM_IT_UPDATE);					return TRUE;
}inline void
vMBPortTimersEnable(  )
{/* Enable the timer with the timeout passed to xMBPortTimersInit( ) */__HAL_TIM_SET_COUNTER(&htim4, 0);__HAL_TIM_ENABLE(&htim4);
}inline void
vMBPortTimersDisable(  )
{/* Disable any pending timers. */__HAL_TIM_DISABLE(&htim4);
}/* Create an ISR which is called whenever the timer has expired. This function* must then call pxMBPortCBTimerExpired( ) to notify the protocol stack that* the timer has expired.*/
static void prvvTIMERExpiredISR( void )
{( void )pxMBPortCBTimerExpired(  );
}void TIM4_IRQHandler(void)
{if(__HAL_TIM_GET_FLAG(&htim4, TIM_FLAG_UPDATE)){__HAL_TIM_CLEAR_FLAG(&htim4, TIM_FLAG_UPDATE);prvvTIMERExpiredISR();}
}

E:\STM32CubeIDE\Workspace\FreeMODBUSRTUSlave\modbus\demo.c

代码如下:这里是主要modbus栈需要维护的数据

/** FreeModbus Libary: BARE Demo Application* Copyright (C) 2006 Christian Walter <wolti@sil.at>** This program is free software; you can redistribute it and/or modify* it under the terms of the GNU General Public License as published by* the Free Software Foundation; either version 2 of the License, or* (at your option) any later version.** This program 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 General Public License for more details.** You should have received a copy of the GNU General Public License* along with this program; if not, write to the Free Software* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA** File: $Id$*//* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mbport.h"/* ----------------------- Defines ------------------------------------------*/
#define REG_INPUT_START 1000
#define REG_INPUT_NREGS 4/* ----------------------- Static variables ---------------------------------*/
static USHORT   usRegInputStart = REG_INPUT_START;
static USHORT   usRegInputBuf[REG_INPUT_NREGS];// 十路输入寄存器
#define REG_INPUT_SIZE  10
uint16_t REG_INPUT_BUF[REG_INPUT_SIZE];// 十路保持寄存器
#define REG_HOLD_SIZE   10
uint16_t REG_HOLD_BUF[REG_HOLD_SIZE];// 十路线圈
#define REG_COILS_SIZE 10
uint8_t REG_COILS_BUF[REG_COILS_SIZE] = {1, 1, 1, 1, 0, 0, 0, 0, 1, 1};// 十路离散量
#define REG_DISC_SIZE  10
uint8_t REG_DISC_BUF[REG_DISC_SIZE] = {1,1,1,1,0,0,0,0,1,1};/* ----------------------- Start implementation -----------------------------*//// CMD4命令处理回调函数
eMBErrorCode
eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
{USHORT usRegIndex = usAddress - 1;// 非法检测if ((usRegIndex + usNRegs) > REG_INPUT_SIZE) {return MB_ENOREG;}// 循环读取while (usNRegs > 0) {*pucRegBuffer++ = (unsigned char)(REG_INPUT_BUF[usRegIndex] >> 8);*pucRegBuffer++ = (unsigned char)(REG_INPUT_BUF[usRegIndex] & 0xFF);usRegIndex++;usNRegs--;}// 模拟输入寄存器被改变for (usRegIndex = 0; usRegIndex < REG_INPUT_SIZE; usRegIndex++) {REG_INPUT_BUF[usRegIndex]++;}return MB_ENOERR;
}/// CMD6、3、16命令处理回调函数
eMBErrorCode
eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs,eMBRegisterMode eMode )
{USHORT usRegIndex = usAddress - 1;// 非法检测if ((usRegIndex + usNRegs) > REG_HOLD_SIZE) {return MB_ENOREG;}// 写寄存器if (eMode == MB_REG_WRITE) {while (usNRegs > 0) {REG_HOLD_BUF[usRegIndex] = (pucRegBuffer[0] << 8) | pucRegBuffer[1];pucRegBuffer += 2;usRegIndex++;usNRegs--;}}// 读寄存器else {while (usNRegs > 0) {*pucRegBuffer++ = (unsigned char)(REG_HOLD_BUF[usRegIndex] >> 8);*pucRegBuffer++ = (unsigned char)(REG_HOLD_BUF[usRegIndex] & 0xFF);usRegIndex++;usNRegs--;}}return MB_ENOERR;
}/// CMD1、5、15命令处理回调函数
eMBErrorCode
eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils,eMBRegisterMode eMode )
{USHORT usRegIndex = usAddress - 1;UCHAR ucBits = 0;UCHAR ucState = 0;UCHAR ucLoops = 0;// 非法检测if ((usRegIndex + usNCoils) > REG_COILS_SIZE) {return MB_ENOREG;}if (eMode == MB_REG_WRITE) {ucLoops = (usNCoils - 1) / 8 + 1;while (ucLoops != 0) {ucState = *pucRegBuffer++;ucBits = 0;while (usNCoils != 0 && ucBits < 8) {REG_COILS_BUF[usRegIndex++] = (ucState >> ucBits) & 0X01;usNCoils--;ucBits++;}ucLoops--;}} else {ucLoops = (usNCoils - 1) / 8 + 1;while (ucLoops != 0) {ucState = 0;ucBits = 0;while (usNCoils != 0 && ucBits < 8) {if (REG_COILS_BUF[usRegIndex]) {ucState |= (1 << ucBits);}usNCoils--;usRegIndex++;ucBits++;}*pucRegBuffer++ = ucState;ucLoops--;}}return MB_ENOERR;
}/// CMD2命令处理回调函数
eMBErrorCode
eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
{USHORT usRegIndex = usAddress - 1;UCHAR ucBits = 0;UCHAR ucState = 0;UCHAR ucLoops = 0;// 非法检测if ((usRegIndex + usNDiscrete) > REG_DISC_SIZE) {return MB_ENOREG;}ucLoops = (usNDiscrete - 1) / 8 + 1;while (ucLoops != 0) {ucState = 0;ucBits = 0;while (usNDiscrete != 0 && ucBits < 8) {if (REG_DISC_BUF[usRegIndex]) {ucState |= (1 << ucBits);}usNDiscrete--;usRegIndex++;ucBits++;}*pucRegBuffer++ = ucState;ucLoops--;}// 模拟离散量输入被改变for (usRegIndex = 0; usRegIndex < REG_DISC_SIZE; usRegIndex++) {REG_DISC_BUF[usRegIndex] = !REG_DISC_BUF[usRegIndex];}return MB_ENOERR;
}

E:\STM32CubeIDE\Workspace\FreeMODBUSRTUSlave\Core\Src\freertos.c

如下修改:

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "mb.h"
#include "mbport.h"
/* USER CODE END Includes */
/* USER CODE BEGIN Header_StartDefaultTask */
/*** @brief  Function implementing the defaultTask thread.* @param  argument: Not used* @retval None*/
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)
{/* USER CODE BEGIN StartDefaultTask *//* Infinite loop */eMBInit(MB_RTU, 0x01, 0, 115200, MB_PAR_NONE); eMBEnable();for(;;){osDelay(1);eMBPoll();}/* USER CODE END StartDefaultTask */
}

4. 运行

好像带连续读取保护,这个我还没看,连续读取会失败

答:由于主频过低,导致使用中断的方式接收数据时,让处理时间稍微耗时,导致下一次数据露采,所以会有通讯失败的情况。

解决办法是提高主频,或者降低波特率。

主站

开源一套MODBUS主机代码(带讲解分析) – 电子创客营

源码地址:https://github.com/Derrick45/modbus-host

1. STM32CubeMX 配置流程

1.1配置系统模式

1.2配置定时器3

这个需要和port中代码保持一致

因为系统主频配置为64MHz

1.3配置串口1

1.4打开串口1和tim3中断

1.5 取消默认生成中断函数

因为后面代码需要自己实现

1.6 freeRTOS创建两个任务

一个默认任务,处理poll函数,一个任务做发送

1.7 配置系统时钟为64M

1.8 生成独立文件

2. 库文件导入

把源码文件放到modbus文件夹中

环境配置

3.移植流程

MODBUSRTUMaster\Core\Src\freertos.c

添加头文件

任务逻辑实现,默认任务处理poll

发送任务每一秒钟发送一次测试数据

4. 运行

http://www.dtcms.com/wzjs/479854.html

相关文章:

  • 温州网站制作哪家好运营商大数据精准营销
  • 做saas平台网站厦门seo排名外包
  • 微信网站模块大连网站制作
  • cms适合做什么网站seo分析报告
  • 建设网站的网站首页正规电商培训班
  • 做订购网站深圳百度seo哪家好
  • 企业简介模板图片百度seo培训课程
  • 四川全美网络科技有限公司重庆seo是什么
  • 免费学做美食视频网站有哪些外贸网站平台哪个好
  • 兰州优秀网站推广商业计划书
  • 百度如何做推广网站关键词优化排名软件
  • HTML发布网站淘宝如何刷关键词增加权重
  • 想换掉做网站的公司无锡网络推广外包
  • 小型企业网站模板广西seo快速排名
  • 网站建设教程论坛郑州seo多少钱
  • 推送网站建设网络营销模式有哪些
  • 轻量级WordPress西安百度关键词优化
  • 网站相应速度十大免费货源网站免费版本
  • 关于网站建设的几点体会网络营销工具包括
  • 人事怎么做招聘网站比对分析宣传推广渠道有哪些
  • 自己怎样做网站文章关键词内链全自动引流推广软件app
  • 怎么把自己做的网站让外网访问seo优化外包公司
  • 3dweb做的网站电脑培训网上培训班
  • 天蝎做网站建网站免费外链网盘
  • 高端网站建设推荐万维科技广州seo关键词
  • 做网站运营有前途吗宁波seo网站推广软件
  • 企业网站建设财务规划郑州网络推广大包
  • 免费做网站的好不好东莞网站定制开发
  • 做鞋原料网站市场调研报告范文模板word
  • 宿州网站建设营销方式有哪几种