刚写完一个modbus通讯协议,调试完,整理出来了,软件代码只能为大家提供一个思路,仅供参考。

//communication.h
#include "H01_Global\_Define.h"
#include "H01_Global\base_types.h"#define SIZE_BUF_RECE 100
#define SIZE_BUF_TRAN 100#define TRANS_TIMER_DELAY_1MS    1
#define TRANS_TIMER_DELAY_10MS   10
#define TRANS_TIMER_DELAY_100MS  100
#define TRANS_TIMER_DELAY_1S   1000typedef union
{uint16_t word;struct {uint8_t low;uint8_t high;}byte;struct{uint8_t bit0:1;uint8_t bit1:1;uint8_t bit2:1;uint8_t bit3:1;uint8_t bit4:1;uint8_t bit5:1;uint8_t bit6:1;uint8_t bit7:1;uint8_t bit8:1;uint8_t bit9:1;uint8_t bit10:1;uint8_t bit11:1;uint8_t bit12:1;uint8_t bit13:1;uint8_t bit14:1;uint8_t bit15:1;}BIT;
}WORD_BYTE;typedef struct
{uint32_t MODBUS_Reg_Set_Speed;uint32_t MODBUS_Reg_Set_Enable_VSP;uint32_t MODBUS_Reg_Set_Dir;uint32_t MODBUS_Reg_Force_Stop;
}MODBUS_HOLDING_REGISTORS;typedef struct
{uint32_t MODBUS_Reg_Get_Motor_Type;uint32_t MODBUS_Reg_Get_Software_Version;uint32_t MODBUS_Reg_Get_Running_Status;uint32_t MODBUS_Reg_Get_Running_Speed;uint32_t MODBUS_Reg_Get_Phase_Current;uint32_t MODBUS_Reg_Get_IPM_Temperature;uint32_t MODBUS_Reg_Get_DC_Voltage;uint32_t MODBUS_Reg_Get_Running_Dir;uint32_t MODBUS_Reg_Get_Errors;
}MODBUS_INPUT_REGISTORS;typedef struct
{uint32_t dev_comm;uint32_t delay_tran;uint32_t Function_Code;uint32_t flag_state;uint32_t addr_dev;uint32_t pt_tran;uint32_t pt_rece;uint32_t len_tran;uint32_t len_rece;uint32_t xorsum_rece;uint32_t addsum_rece;uint32_t xorsum_tran;uint32_t addsum_tran;uint32_t flag_trans_start;uint32_t flag_trans_end;uint32_t flag_trans_timer_ON;uint32_t count_trans_timer_1ms;uint32_t count_trans_timer_10ms;uint32_t count_trans_timer_100ms;uint32_t count_trans_timer_1s;WORD_BYTE address_reg;WORD_BYTE num_reg;uint32_t buf_rece[SIZE_BUF_RECE];uint32_t buf_tran[SIZE_BUF_TRAN];MODBUS_HOLDING_REGISTORS Modbus_Holding_Reg ;MODBUS_INPUT_REGISTORS Modbus_Input_Reg;
}MODBUS_COMM;extern void Uart_Trans(void);
extern void Uart_Receive(void);
extern void Init_Modbus(void);
extern void Timer_Task(void);
extern void Proc_Modbus_Data(void);
extern uint32_t Read_Reg_Modbus(MODBUS_COMM *modbus);
void Set_Reg_Modbus(MODBUS_COMM *modbus, WORD_BYTE data);
extern void CRC_Rece_Check(void);
extern uint32_t Flag_Trans_End;
extern uint32_t Timer_Count;
extern uint32_t Timer_1s;
// communication.c
#include "H05_User\AllInOne.h"
/*****************************************************************************/
/* Local pre-processor symbols/macros ('#define')                            */
/*****************************************************************************/
#define MAX_DEV_COMM 4
#define DELAY_SENT 20
/*****************************************************************************/
/* Global variable definitions (declared in header file with 'extern')       */
/*****************************************************************************//*****************************************************************************/
/* Local type definitions ('typedef')                                        */
/*****************************************************************************/
typedef enum
{Reg_Set_Speed = 100,  //100Reg_Set_Enable_VSP,   //101Reg_Set_Dir,         //102Reg_Force_Stop
}Modbus_Holding_Registors;typedef enum
{Reg_Get_Motor_Type = 200, //200Reg_Get_Software_Version, //201Reg_Get_Running_Status,   //202Reg_Get_Running_Speed,    //203Reg_Get_Phase_Current,    //204Reg_Get_IPM_Temperature,  //205Reg_Get_DC_Voltage,       //206Reg_Get_Running_Dir,      //207Reg_Get_Errors            //208
}Modbus_Input_Registors;enum
{MODBUS_State_Idle = 0,MODBUS_State_Receive,MODBUS_State_Transmit
};
/*****************************************************************************/
/* Local variable definitions ('static')                                     */
/*****************************************************************************/
uint32_t Timer_Count;
uint32_t Timer_1s;
uint32_t Flag_Trans_End;
extern uint32_t Software_Version;
extern MODBUS_COMM modbus_comm;
extern MODBUS_COMM *modbus;void Init_Modbus()
{uint32_t temp = 0;modbus = &modbus_comm;modbus->addr_dev = 1;modbus->dev_comm = 0;modbus->delay_tran = 0;modbus->Function_Code = 0;modbus->flag_state = MODBUS_State_Idle;modbus->pt_tran = 0;modbus->pt_rece = 0;modbus->len_tran = 0;modbus->len_rece = 0;modbus->xorsum_rece = 0;modbus->xorsum_tran = 0;modbus->addsum_rece = 0;modbus->addsum_tran = 0;modbus->flag_trans_start = 0;modbus->flag_trans_end = 1;modbus->flag_trans_timer_ON = 0;modbus->count_trans_timer_1ms = 0;modbus->count_trans_timer_10ms = 0;modbus->count_trans_timer_100ms = 0;modbus->count_trans_timer_1s = 0;modbus->address_reg.word = 0;modbus->num_reg.word = 0;for(temp = 0; temp<SIZE_BUF_RECE; temp++){modbus->buf_rece[temp] = 0;}for(temp=0; temp<SIZE_BUF_TRAN; temp++){modbus->buf_tran[temp] = 0;}modbus->Modbus_Input_Reg.MODBUS_Reg_Get_DC_Voltage = 0;modbus->Modbus_Input_Reg.MODBUS_Reg_Get_Errors = 0;modbus->Modbus_Input_Reg.MODBUS_Reg_Get_IPM_Temperature = 0;modbus->Modbus_Input_Reg.MODBUS_Reg_Get_Motor_Type = 0;modbus->Modbus_Input_Reg.MODBUS_Reg_Get_Phase_Current = 0;modbus->Modbus_Input_Reg.MODBUS_Reg_Get_Running_Dir = 0;modbus->Modbus_Input_Reg.MODBUS_Reg_Get_Running_Speed = 0;modbus->Modbus_Input_Reg.MODBUS_Reg_Get_Running_Status = 0;modbus->Modbus_Input_Reg.MODBUS_Reg_Get_Software_Version = Software_Version;
}void Uart_Trans()
{uint32_t data_trans;if(modbus->flag_trans_start){if(modbus->pt_tran < modbus->len_tran){if(UART_SpiUartGetTxBufferSize() == 0){data_trans = modbus->buf_tran[modbus->pt_tran];UART_UartPutChar(data_trans);modbus->pt_tran++;modbus->flag_trans_end = 0;}}else{modbus->pt_tran = 0;modbus->pt_rece = 0;modbus->flag_trans_start = 0;modbus->flag_trans_end = 1;modbus->flag_state = MODBUS_State_Idle;}}else{modbus->pt_tran = 0;}
}void Uart_Receive()
{uint32_t data_rece;data_rece = UART_UartGetChar();if(modbus->flag_state){modbus->pt_rece = 0;}else{if((modbus->pt_rece)&&(modbus->addr_dev == modbus->buf_rece[0])){if(modbus->dev_comm > MAX_DEV_COMM){modbus->pt_rece = 0;}modbus->buf_rece[modbus->pt_rece] = data_rece;modbus->pt_rece++;if(modbus->pt_rece < 8){if(modbus->pt_rece == 7){if(modbus->buf_rece[1] >= 0x0F){modbus->len_rece = modbus->buf_rece[6]+9;}else{modbus->len_rece = 8;}}}else if(modbus->pt_rece >= modbus->len_rece){modbus->pt_rece = 0;modbus->flag_state = MODBUS_State_Receive;if(modbus->buf_rece[0]){modbus->delay_tran = DELAY_SENT;}}}else{if((modbus->addr_dev == data_rece) || (data_rece == 0)){modbus->buf_rece[0] = data_rece;modbus->pt_rece = 1;}}}modbus->dev_comm = 0;
}void Timer_Task()
{Timer_Count++;if(Timer_Count >= 5000){Timer_Count = 0;Timer_1s++;}if(modbus->flag_trans_timer_ON){modbus->count_trans_timer_100ms++;if(modbus->count_trans_timer_100ms >= TRANS_TIMER_DELAY_100MS){modbus->count_trans_timer_100ms = 0;modbus->flag_trans_timer_ON = 0;modbus->flag_trans_start = 1;}}
}uint32_t Read_Reg_Modbus(MODBUS_COMM *modbus)
{WORD_BYTE dat;uint32_t addr;addr = modbus->address_reg.word;dat.word = 0;if(modbus->Function_Code == 3){switch(addr){case Reg_Set_Speed:dat.word = modbus->Modbus_Holding_Reg.MODBUS_Reg_Set_Speed;break;case Reg_Set_Enable_VSP:dat.word = modbus->Modbus_Holding_Reg.MODBUS_Reg_Set_Enable_VSP;break;case Reg_Set_Dir:dat.word = modbus->Modbus_Holding_Reg.MODBUS_Reg_Set_Dir;break;case Reg_Force_Stop:dat.word = modbus->Modbus_Holding_Reg.MODBUS_Reg_Force_Stop;break;default:break;}}else if(modbus->Function_Code == 4){switch(addr){case Reg_Get_Motor_Type:dat.word = modbus->Modbus_Input_Reg.MODBUS_Reg_Get_Motor_Type;break;case Reg_Get_Software_Version:dat.word = modbus->Modbus_Input_Reg.MODBUS_Reg_Get_Software_Version;break;case Reg_Get_Running_Status:dat.word = modbus->Modbus_Input_Reg.MODBUS_Reg_Get_Running_Status;break;case Reg_Get_Running_Speed:dat.word = modbus->Modbus_Input_Reg.MODBUS_Reg_Get_Running_Speed;break;case Reg_Get_Phase_Current:dat.word = modbus->Modbus_Input_Reg.MODBUS_Reg_Get_Phase_Current;break;case Reg_Get_IPM_Temperature:dat.word = modbus->Modbus_Input_Reg.MODBUS_Reg_Get_IPM_Temperature;break;case Reg_Get_DC_Voltage:dat.word = modbus->Modbus_Input_Reg.MODBUS_Reg_Get_DC_Voltage;break;case Reg_Get_Running_Dir:dat.word = modbus->Modbus_Input_Reg.MODBUS_Reg_Get_Running_Dir;break;case Reg_Get_Errors:dat.word = modbus->Modbus_Input_Reg.MODBUS_Reg_Get_Errors;break;default:break;}}else if((modbus->Function_Code == 6)||(modbus->Function_Code == 16)){}return (dat.word);
}void Set_Reg_Modbus(MODBUS_COMM *modbus, WORD_BYTE data)
{if(modbus->Function_Code == 3){}else if(modbus->Function_Code == 4){}else if((modbus->Function_Code == 6)||(modbus->Function_Code == 16)){switch(modbus->address_reg.word){case Reg_Set_Speed:modbus->Modbus_Holding_Reg.MODBUS_Reg_Set_Speed = data.word;break;case Reg_Set_Enable_VSP:modbus->Modbus_Holding_Reg.MODBUS_Reg_Set_Enable_VSP = data.word;break;case Reg_Set_Dir:modbus->Modbus_Holding_Reg.MODBUS_Reg_Set_Dir = data.word;break;case Reg_Force_Stop:modbus->Modbus_Holding_Reg.MODBUS_Reg_Force_Stop = data.word;break;default:break;}}
}void Proc_Modbus_Data()
{uint32_t index_modbus;uint32_t index;WORD_BYTE data;if(modbus->flag_state == MODBUS_State_Receive){modbus->len_tran = 0;if(crc16_str_rece(modbus->buf_rece, modbus->len_rece-2)){modbus->addr_dev = modbus->buf_rece[0];modbus->Function_Code = modbus->buf_rece[1];modbus->buf_tran[0] = modbus->addr_dev;if((modbus->Function_Code&&(modbus->Function_Code<7)) || (modbus->Function_Code == 15) || (modbus->Function_Code == 16)){modbus->address_reg.byte.high = modbus->buf_rece[2];modbus->address_reg.byte.low = modbus->buf_rece[3];modbus->num_reg.byte.high = modbus->buf_rece[4];modbus->num_reg.byte.low = modbus->buf_rece[5];modbus->address_reg.word++;if((modbus->Function_Code == 3)||(modbus->Function_Code==4)||(modbus->Function_Code==6)||(modbus->Function_Code==16)){if((modbus->Function_Code==3)||(modbus->Function_Code==4)){modbus->buf_tran[1] = modbus->Function_Code;modbus->buf_tran[2] = (modbus->num_reg.byte.low<<1);modbus->len_tran = modbus->buf_tran[2] + 5;index_modbus = 3;for(index=0; index<modbus->num_reg.byte.low; index++, modbus->address_reg.word++){data.word = Read_Reg_Modbus(modbus);modbus->buf_tran[index_modbus++] = data.byte.high;modbus->buf_tran[index_modbus++] = data.byte.low;}}else if(modbus->Function_Code == 6){for(index=1; index<6; index++){modbus->buf_tran[index] = modbus->buf_rece[index];}modbus->len_tran = 8;data.byte.high = modbus->buf_rece[4];data.byte.low = modbus->buf_rece[5];Set_Reg_Modbus(modbus, data);}else{for(index=1; index<6; index++){modbus->buf_tran[index] = modbus->buf_rece[index];}modbus->len_tran = 8;index_modbus = 7;for(index=0; index<modbus->num_reg.byte.low; index++, modbus->address_reg.word++){data.byte.high = modbus->buf_rece[index_modbus++];data.byte.low = modbus->buf_rece[index_modbus++];Set_Reg_Modbus(modbus, data);}}}}if(modbus->len_tran){crc16_str_sent(modbus->buf_tran, (modbus->len_tran - 2));modbus->flag_state = MODBUS_State_Transmit;modbus->flag_trans_timer_ON = 1;modbus->count_trans_timer_100ms = 0;}else{modbus->flag_state = MODBUS_State_Idle;}}else{modbus->flag_state = MODBUS_State_Idle;}}
}

另外针对CRC校验的代码实现,请移步我的另一篇博客:
链接: CRC校验查表法原理及实现(CRC-16).

以上的代码仅仅是一demo例程,面向电机控制系统的modbus通讯协议,所以在定义寄存器的时候会定义电机运行期间的变量,仅供参考,不要来问我为什么移植到某平台上运行不了这样的问题,这仅仅是项目软件的很小的一个部分,仅提供思路而已。

Modbus通讯协议的C语言实现相关推荐

  1. Modbus通讯协议

    https://baike.baidu.com/item/Modbus%E9%80%9A%E8%AE%AF%E5%8D%8F%E8%AE%AE/5972462?fromtitle=ModBus& ...

  2. 杭州金田电磁转换器MODBUS通讯协议

    杭州金田电磁转换器MODBUS通讯协议 通讯协议采用标准MODBUS RTU通讯协议.仪表为从机. RTU消息帧定义 数据通讯由主机发起,主机首先发送RTU消息帧,消息帧发送至少要以3.5个字符时间的 ...

  3. MODBUS通讯协议及编程【一】

    一.Modbus 协议简介   Modbus 协议是应用于电子控制器上的一种通用语言.通过此协议,控制器相互之间.控制器经由网络(例如以太网)和其它设备之间可以通信.它已经成为一通用工业标准.有了它, ...

  4. Modbus 通讯协议

    Modbus 通讯协议 摘要 工业控制已从单机控制走向集中监控.集散控制,如今已进入网络时代,工业控制器连网也为网络管理提供了方便.Modbus就是工业控制器的网络协议中的一种. 关键词 Modbus ...

  5. STM32移植modbus通讯协议简明教程

    目录 一.本文讨论内容 二.工具与源码 三.Modbus概述 四.Modbus-RTU通讯协议 五.完成Modbus输入输出代码 六.完成Modbus逻辑功能 七.测试与验证 一.本文讨论内容 本文简 ...

  6. 基于modbus协议的工业自动化网络规范_工控学堂:解读Modbus通讯协议「宜收藏」...

    作为工控人,Modbus通讯协议想必都不陌生,Modbus通讯协议可以说是工业自动化领域应用最为广泛的通讯协议,因为他的开放性.可扩充性和标准化使他成为通用工业标准. 1979年施耐德电气制定了一个用 ...

  7. 一文搞懂物联网Modbus通讯协议

    简介: 一般来说,常见的物联网通讯协议众多,如蓝牙.Zigbee.WiFi.ModBus.PROFINET.EtherCAT.蜂窝等.而在众多的物联网通讯协议中,Modbus是当前非常流行的一种通讯协 ...

  8. 协议:Modbus通讯协议详细

    1.Modbus通讯协议详细解释 https://blog.csdn.net/rxiang12/article/details/79125813 2.Modbus通信协议详解 https://blog ...

  9. modbus通讯协议详解

    1.Modbus协议简介 Modbus协议是一种广泛应用于当今工业控制领域的通用通信协议.通过此协议,控制器相互之间.或者控制器经由网路(如以太网)可以和其他设备之间进行通信.Modbus协议使用的是 ...

最新文章

  1. 好程序员Web前端教程分享Vue学习心得
  2. MyBatis-学习笔记10【10.JNDI扩展知识】
  3. centos7 tomcat_centos7中利用logrotate工具切割日志,以tomcat日志为例
  4. 2017 Multi-University Training Contest - Team 2——HDU6045HDU6047HDU6055
  5. 创建线程都有哪些方式?— Callable篇
  6. 从放牛娃到北大博士,这篇论文后记刷屏
  7. Dubbo 面试题汇总(附答案)
  8. iphone查看删除的短信_苹果删除的短信
  9. Kali Linux Web 渗透测试秘籍 第九章 客户端攻击和社会工程
  10. 小米 11 不送充电器;苹果已修复 iCloud 登录激活问题;Ruby 3.0.0 发布|极客头条...
  11. yum提示Another app is currently holding the yum lock
  12. 两分钟,帮你搞懂光纤接头
  13. 【Excel】两组行数不同数据做二维柱状图
  14. Clonezilla SE---克隆linux------转载
  15. 计算机基础及msoffice应用内容,计算机一级计算机基础及 ms office 应用考些什么 自考计算机应用基础,要考哪些内容?...
  16. c语言 表盘指针旋转,请教下,表盘指针图片旋转 ??
  17. 止咳绝招 献给身边咳嗽的人
  18. 你从哪里来你是谁你到哪里去_你到底在哪里?
  19. 高边坡监测主要监测的内容
  20. GuestOS? HostOS?

热门文章

  1. Python实现小说人物关系输出(完整+修正)
  2. html光标自动定位,div自动获焦并将光标定位到最后
  3. 开源的 .NET 工作流引擎 Elsa 开源
  4. 图像 文本 列表 字体使用
  5. editplus注册码生成器
  6. 获取到小程序全局唯一的 App 实例(getApp()获取)
  7. Tessy—支持复杂场景测试的单元集成测试工具
  8. day day up
  9. day day day upupupup
  10. iNode mac版用网线上不去网的解决方法 thunderbolt