IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> FreeModbus从站源码解析(portserial.c) -> 正文阅读

[嵌入式]FreeModbus从站源码解析(portserial.c)

portserial.c

#include "port.h"
#include "mb.h"
#include "mbport.h"

#define EVENT_SERIAL_TRANS_START    (1<<0)  // 串口发送事件等待标志位 

EventGroupHandle_t SlaveSerialSendEvent;    // 串口发送事件

static void prvvUARTTxReadyISR(void); //串口发送回调函数
static void prvvUARTRxISR(void);              //串口接收中断回调函数

/*
 **********************************************
 * @Func:RS485初始化及事件标志组初始化
 * @ucPORT : 选择串口端口,暂未使用
 * @ulBaudRate : 波特率
 * @ucDataBits : 数据位
 * @eParity : 奇偶校验位
 **********************************************
*/
BOOL xMBPortSerialInit(UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits,
        eMBParity eParity)
{
	(void)ucPORT;
	(void)ucDataBits;
	(void)eParity;
	bsp_rs485_init(ulBaudRate);                   // RS485初始化
	SlaveSerialSendEvent = xEventGroupCreate();   // 创建从机串口发送事件
	return TRUE;
}
/*
 ***********************************
 * @Func : 串口发送\接收使能
 * @xRxEnable : 接收使能参数
 * @xTxEnable : 发送使能参数
 * @Note : 不能同时收发
 ***********************************
*/
void vMBPortSerialEnable(BOOL xRxEnable, BOOL xTxEnable)
{
	if(xRxEnable)
	{	
		// 使能串口接收中断 RS485方向设置为接收
		__HAL_UART_ENABLE_IT(&USART2_RS485Handler,USART_IT_RXNE);
		RS485_RECV;
	}
	else
	{
		// 失能串口接收中断 RS485方向设置为发送
		__HAL_UART_DISABLE_IT(&USART2_RS485Handler,USART_IT_RXNE);
		RS485_SEND;
	}
	if(xTxEnable)
	{
		// 置事件标志位有效
		xEventGroupSetBits(SlaveSerialSendEvent,EVENT_SERIAL_TRANS_START);
	}
	else
	{
		// 获取事件后清除标志位,用于停止发送使任务
		//     slaveSendIrq_task进入阻塞状态
		xEventGroupWaitBits(SlaveSerialSendEvent,		
						EVENT_SERIAL_TRANS_START,
						pdTRUE,				
						pdFALSE,
					    0);	
	}
}
/*
 ********************************************
 * @Func : Modbus在Diseable状态下释放资源
 ********************************************
*/
void vMBPortClose(void)
{
    // 释放资源
    // 用户自行添加
}
/*
 ********************************************
 * @Func : 串口发送一个字节数据
 * @ucByte : 待发送数据
 ********************************************
*/
BOOL xMBPortSerialPutByte(CHAR ucByte)
{
    u8 ret = 0;
	ret = HAL_UART_Transmit(&USART2_RS485Handler, (u8 *)(&ucByte),1,200);
    return ret;
}
/*
 ********************************************
 * @Func : 串口接收一个字节数据
 * @pucByte : 收到的数据
 ********************************************
*/
BOOL xMBPortSerialGetByte(CHAR * pucByte)
{
    HAL_UART_Receive(&USART2_RS485Handler,(u8 *)pucByte,1,200);
    return TRUE;
}

/*
 *******************************************************
 * @Func : 函数指针,指向xMBRTUTransmitFSM发送状态机
 * @Note : slaveSendIrq_task任务获取发送事件有效
 *             后周期调用
 *******************************************************
*/
static void prvvUARTTxReadyISR(void)
{
	//函数指针,指向xMBRTUTransmitFSM
    pxMBFrameCBTransmitterEmpty();
}

/*
 *******************************************************
 * @Func : 函数指针,指向xMBRTUReceiveFSM接收状态机
 * @Note : 串口接收中断服务任务调用
 *******************************************************
*/
static void prvvUARTRxISR(void)
{
	//函数指针,指向 xMBRTUReceiveFSM
    pxMBFrameCBByteReceived();
}

/*
 *******************************************************
 * @Func : 从机发送任务
 * @Note : 完成发送状态机的状态切换
 *******************************************************
*/
void slaveSendIrq_task(void *pvParameters){
    EventBits_t recved_event;
    while (1)
    {
        // 等待事件有效(不清标志位,会一直有效),否则阻塞
        recved_event = xEventGroupWaitBits(SlaveSerialSendEvent,		
						EVENT_SERIAL_TRANS_START,
						pdFALSE,				
						pdFALSE,
					    portMAX_DELAY);	
        // 调用函数 prvvUARTTxReadyISR
		if(recved_event==EVENT_SERIAL_TRANS_START)
        	prvvUARTTxReadyISR();
    }
}

/*
 *******************************************************
 * @Func : 串口接收中断服务函数
 * @Note : 完成接收状态机的状态切换
 *******************************************************
*/
 #ifdef MODBUS_SLAVE_MODE
void USART2_IRQHandler(void)
{
	if(__HAL_USART_GET_FLAG(&USART2_RS485Handler, USART_FLAG_RXNE) != RESET)
	{	 
		// 调用函数 prvvUARTRxISR()
		prvvUARTRxISR();
	}  	
} 
#endif

Modbus资料大全

笔者将Modbus 主机、从机协议完整资料整理如下:

文件说明
freemodbus-v1.6.zipFreeModbusV1.6源码
FreeModbusMasterSlave(Rev1.0.0).zip笔者移植好测试通过STM32+FreeRTOS+FreeModbus Master Slave代码
ModbusSlave 7.0和ModbusPoll_7.0软件注册码.zipFreeModbus Master Slave调试工具
FreeModbus V1.6 主机使用说明.mdFreeModbus 主机使用说明文档
FreeModbus 从机流程图.vsdFreeModbus 从机流程图
FreeModbus 主机流程图.vsdFreeModbus 主机流程图
Modbus应用协议.doc笔者整理的 FreeModbus 协议文档
FreeModbus Datasheet笔者搜集 FreeModbus 官方协议文档

资料链接:👉FreeModbus资源传送门👈
资料介绍:👉FreeModbus资源介绍传送门👈

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-04-04 12:27:28  更:2022-04-04 12:28:56 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 4:52:00-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码