刚写完一个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. Study on Android【六】--消息机制,异步和多线程
  2. centos6下的mysql的安装
  3. Msg3最大传输次数(maxHARQ-Msg3Tx)
  4. etl数据抽取工具_数据同步工具ETL、ELT傻傻分不清楚?3分钟看懂两者区别
  5. PHP版本不同可以导入导出吗,请教高人:两个php平台之间的数据导入导出
  6. C# 使用Epplus导出Excel [4]:合并指定行
  7. java使用JMail通过QQ邮件服务器实现自动发送邮件
  8. 【报告分享】与AI共进,智胜未来:智能金融联合报告-埃森哲百度.pdf
  9. linux命令行终端设置tab补全文件名或路径不区分大小写(大小写不敏感)
  10. uniapp App权限开启
  11. QCC3020呼吸灯设计
  12. 企业实践|分布式系统可观测性之应用业务指标监控
  13. C语言练习题,从键盘输入一个字符,在给定的字符串中寻找该输入字符,若找到将该字符从字符串中删掉,并输出该字符串,没有找到给出提示信息“未找到”。
  14. 计算机类需不需英语口语考试,关于计算机口语测试与传统口语测试比较分析.doc...
  15. 基于Vue源码中e2e测试实践
  16. [C++]深复制与浅复制
  17. IESM项目实训四——Web Audio录音和字符串转拼音
  18. Android应用设置系统情景模式
  19. iOS中把故事板中视功能和美工结合在1起
  20. 【转载】根据已知点通过COORD七参数计算

热门文章

  1. ubuntu使用nomachine远程桌面
  2. c语言编程项目实践报告快递管理系统,学生成绩管理系统C语言程序设计实践报告.doc...
  3. 西南大学网络实现路由器WIFI共享方案(一号多用户共享)
  4. GPS Guided Policy Search
  5. Android 定位功能简单实现
  6. 【概率论】理解全概率公式
  7. llt自发光_得物独家首发雷美诺时 x“贝爷”联名款新品 共同探索潮流文化
  8. VUE复习深入学习10.可复用性 组合 mixin!!!!!!
  9. filesystem编译Bug记录
  10. 应届毕业生,绝对有你不知道的——档案,面试,合同法,薪水,为人处事等问题 1