浙江华通信息技术有限公司提供完整Zigbee解决方案    
1/1页1 跳转到查看:311
发新话题 回复该主题

[开发] Modbus收发源代码(C51编写)

Modbus收发源代码(C51编写)

Modbus收发源代码
共有5个文件
Modbus.h
Modbusstr.h
rxd.c
txd.c
maintest.c

TOP

 

modbus.h

1#include "reg51.h"
2#include "ModBusStr.h"
3
4#define uchar unsigned char
5#define uint unsigned int
6#define uint8 unsigned char
7#define uint16 unsigned int
8
9#define OK 1
10#define ERROR 0
11
12#define RIGHT 1
13#define WRONG 0
14
15
16#define POOLLEN 255 //缓冲区大小
17
18#define INIT_COMMAND 0x20
19#define START_COMMAND 0x21
20#define END_COMMAND 0x22
21#define ALARM_COMMAND 0x23
22
23
24#define FRAME_START 0x7e //帧开始标志
25#define FRAME_END 0x0d //帧结束标志
26#define VER 0x10
27#define ADDR 0x01
28
29
30#define M_CID 0x25 //设备识别码,0x25代表直流电源柜
31
32extern StrRxd xdata sys_rxd;
33extern StrTxd xdata sys_txd;
34
35extern void init_proc_rxd(void);
36extern void process_rxd(void);
37extern void init_serial(void);
38
39extern uint8 lchksum(uint8 data_len);
40extern void txd_sta(void);
41extern void txd_man(void);
42extern void txd_uni(uint8 cid2);

TOP

 

modbusstr.h

1#ifndef MODBUSSTR_H
2#define MODBUSSTR_H
3//==============================================
4#define uchar unsigned char
5#define uint unsigned int
6#define uint8 unsigned char
7#define uint16 unsigned int
8//接收缓冲区结构变量
9typedef struct str_rxd_pool
10{
11 uint8 pool[255]; //接收数据缓冲区
12 uint8 front; //头指针
13 uint8 rear; //尾指针
14 uint8 rd_byte; //暂存读数据
15 uint8 frm_num; //缓冲区中的帧数量
16 uint8 add_buf[16]; //用于存放接收缓冲的地址,可以存放16个帧地址,奇数位是首地址,偶数位是尾地址
17 uint8 rec_buf[255]; //去除包头包尾后的数据保留区,这里只保留一帧有效数据
18
19 uint8 start_0x7e; //接收到帧头标志
20 uint8 end_0x0d; //接收到帧尾标志
21
22}
StrRxd;
23//===============================================
24//发送缓冲区结构变量
25typedef struct str_txd_pool
26{
27 uint8 pool[255]; //发送数据ASCII缓冲区
28 uint8 combuf[255]; //发送数据HEX缓冲区
29 uint8 txd_len; //发送数据长度
30}
StrTxd;
31#endif

TOP

 

txd.c

1#include "ModBus.h"
2//--------公有函数和变量-------
3StrTxd xdata sys_txd;
4/****************************************/
5uint8 lchksum(uint8 data_len); //求LENTH_SUM函数
6void txd_sta(void); //发送系统告警信息
7void txd_man(void); //发送厂家信息
8void txd_uni(uint8 cid2); //发送系统通信信息
9/******************************************/
10void package(void); //数据打包成ASCII码
11void chksum (void); //求校验和
12void com(void); //公共的发送函数
13/******************************************/
14uint8 lchksum(uint8 data_len)
15{
16 uint8 sum,temp1;
17 sum = 0;
18 if (data_len)
19 {
20 sum = data_len & 0x0f;
21 temp1 = (data_len & 0xf0)>>4;
22 sum += temp1;
23 sum = sum %16;
24 sum = (~sum)+1;
25 sum = sum <<4;
26 }

27
28 return sum;
29}

30/******************************************/
31void package(void)
32{
33 uint8 i;
34 uint8 temp1,temp2;
35
36 sys_txd.pool[0] = FRAME_START;
37
38 for(i = 1;i < POOLLEN; i++)
39 {
40 if( (sys_txd.combuf == 0xaa ) && (sys_txd.combuf[i+1] == 0x55 ) ) //结束标志
41 {
42 sys_txd.pool[i*2-1] = FRAME_END;
43 break;
44 }

45 else
46 {
47 temp1 = sys_txd.combuf;
48 temp2 = temp1 & 0x0f;
49 temp1 = temp1 & 0xf0;
50 temp1 = temp1>>4;
51 sys_txd.pool[i*2-1] = (temp1>0x09)?(temp1+0x37)temp1+0x30);
52 sys_txd.pool[i*2] = (temp2>0x09)?(temp2+0x37)temp2+0x30);
53 }

54 }

55}

56/******************************************/
57void chksum (void)
58{
59 uint8 i;
60 uint8 sumh,suml,temp;
61 uint16 sum = 0;
62
63 for(i = 1;i < POOLLEN;i++ )
64 {
65 if( sys_txd.pool == FRAME_END )
66 {
67 temp = i;
68 break;
69 }

70 else
71 {
72 sum += sys_txd.pool; //溢出部分不用考虑
73 }

74 }

75
76 sum = (~sum) + 1;//取反+1
77 sumh = (uint8)(sum/256);//高8位
78 suml = (uint8)sum;
79 i = temp;
80
81 temp = (sumh&0xf0)>>4;
82 temp = (temp>0x09)?(temp+0x37)temp+0x30);
83 sys_txd.pool = temp;
84
85 temp = (sumh & 0x0f);
86 temp = (temp>0x09)?(temp+0x37)temp+0x30);
87 sys_txd.pool[i+1] = temp;
88
89 temp = (suml&0xf0)>>4;
90 temp = (temp>0x09)?(temp+0x37)temp+0x30);
91 sys_txd.pool[i+2] = temp;
92
93 temp = (suml&0x0f);
94 temp = (temp>0x09)?(temp+0x37)temp+0x30);
95 sys_txd.pool[i+3] = temp;
96
97 sys_txd.pool[i+4] = FRAME_END;
98
99 sys_txd.txd_len = i+4;
100
101 return;
102}

103/******************************************/
104void com(void)
105{
106 uint8 i;
107 uint8 j;
108
109 EA = 0;
110// RS485EN = 1; //使用485通信的时候使用
111 for( i = 0;i <= sys_txd.txd_len;i++ )
112 {
113 SBUF = sys_txd.pool;
114 while(TI==0);
115 TI = 0;
116 if( sys_txd.pool == FRAME_END )
117 {
118 for( j=0;j <= sys_txd.txd_len;j++ )
119 {
120 sys_txd.pool = 0; //对已经发送的数据清0
121 }

122 }

123 }

124// RS485EN = 0;
125// RI = 0; //注意,如果485的接收使能一直有效,必须要这一行解决
126 EA = 1;
127}

128/******************************************/
129void txd_sta(void)
130{
131
132 sys_txd.combuf[0] = FRAME_START; //起始标志
133 sys_txd.combuf[1] = VER; //版本号
134 sys_txd.combuf[2] = ADDR; //地址,主机
135 sys_txd.combuf[3] = M_CID; //设备ID
136//------以上是包头---------
137 sys_txd.combuf[4] = 0x44; //Cid2=0x44,表示发送所有的告警状态
138//------length---------
139 sys_txd.combuf[5] = lchksum(20); //length checksum//////////////////////
140 sys_txd.combuf[6] = 20; //length id
141 /********************************************/
142 sys_txd.combuf[7] = 20; //这里放告警信息
143 sys_txd.combuf[8] = 20; //
144 sys_txd.combuf[9] = 20; //
145 sys_txd.combuf[10] = 20; //
146 /********************************************/
147 sys_txd.combuf[11] = 0xaa; //end ;
148 sys_txd.combuf[12] = 0x55; //数据打包成ASCII码
149
150 package(); //////////////////////////////
151 chksum(); //除起始和校验和以及结束之外的ASCII码求校验和
152 com();
153}

154/******************************************************/
155void txd_man(void)
156{
157//-----------------------------------------------------------------
158 sys_txd.combuf[0] = FRAME_START; //起始标志
159 sys_txd.combuf[1] = VER; //版本号
160 sys_txd.combuf[2] = ADDR; //地址,主机
161 sys_txd.combuf[3] = M_CID; //设备ID
162 //----------以上是包头
163//-----------------------------------------------------------------
164 sys_txd.combuf[4] =0x51;
165
166 sys_txd.combuf[5] =lchksum(0x40);
167 sys_txd.combuf[6] =0x40;
168
169 sys_txd.combuf[7] = 'L'; //L
170 sys_txd.combuf[8] = 'I'; //I
171 sys_txd.combuf[9] = 'N'; //N
172 sys_txd.combuf[10] = 'E'; //E
173 sys_txd.combuf[11] = 0;
174 sys_txd.combuf[12] = 0x00;
175 sys_txd.combuf[13] = 0x00;
176 sys_txd.combuf[14] = 0x00;
177 sys_txd.combuf[15] = 0x00;
178 sys_txd.combuf[16] = 0x00;
179
180 sys_txd.combuf[17] = 0x01; //1 版本<