登录
注册
标签
会员
搜索
总线空间
相册
帮助
总线论坛
»
现场总线与工业以太网技术
»
Modbus
»
Modbus收发源代码(C51编写)
帖子标题
现场总线与工业以太网技术
Profibus
基金会现场总线
Modbus
ODVA
CAN总线
HART总线
其它总线与以太网
其它工控技术
工业无线技术
DCS技术
PLC技术
OPC与组态监控技术
仪器仪表技术
安全系统
工控外语
工控产品开发
批量控制
信息发布与技术交易
工控产品供求
技术交易信息
休闲娱乐
工控人生
开心一刻
水吧
站务公告
论坛管理
意见和建议
浙江华通信息技术有限公司
提供完整Zigbee解决方案
1/1页
1
跳转到
页
查看:311
[开发] Modbus收发源代码(C51编写)
modbus
个人空间
相册
组别:工程师
性别:
积分:64
帖子:33
2008-11-03 11:17
树型
|
收藏
|
小
中
大
1
#
Modbus收发源代码(C51编写)
Modbus收发源代码
共有5个文件
Modbus.h
Modbusstr.h
rxd.c
txd.c
maintest.c
TOP
发送短消息
查看公共资料
查找该会员全部帖子
UID:87
精华:
3
威望:16
金钱:73 元
来自:
注册: 2008-08-28
状态:
离线
modbus
个人空间
相册
组别:工程师
性别:
积分:64
帖子:33
2008-11-03 11:17
树型
|
收藏
|
小
中
大
2
#
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
32
extern
StrRxd xdata sys_rxd;
33
extern
StrTxd xdata sys_txd;
34
35
extern
void
init_proc_rxd(
void
);
36
extern
void
process_rxd(
void
);
37
extern
void
init_serial(
void
);
38
39
extern
uint8 lchksum(uint8 data_len);
40
extern
void
txd_sta(
void
);
41
extern
void
txd_man(
void
);
42
extern
void
txd_uni(uint8 cid2);
TOP
发送短消息
查看公共资料
查找该会员全部帖子
UID:87
精华:
3
威望:16
金钱:73 元
来自:
注册: 2008-08-28
状态:
离线
modbus
个人空间
相册
组别:工程师
性别:
积分:64
帖子:33
2008-11-03 11:18
树型
|
收藏
|
小
中
大
3
#
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
//
接收缓冲区结构变量
9
typedef
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
//
发送缓冲区结构变量
25
typedef
struct
str_txd_pool
26
...
{
27
uint8 pool[
255
];
//
发送数据ASCII缓冲区
28
uint8 combuf[
255
];
//
发送数据HEX缓冲区
29
uint8 txd_len;
//
发送数据长度
30
}
StrTxd;
31
#endif
TOP
发送短消息
查看公共资料
查找该会员全部帖子
UID:87
精华:
3
威望:16
金钱:73 元
来自:
注册: 2008-08-28
状态:
离线
modbus
个人空间
相册
组别:工程师
性别:
积分:64
帖子:33
2008-11-03 11:19
树型
|
收藏
|
小
中
大
4
#
txd.c
1
#include
"
ModBus.h
"
2
//
--------公有函数和变量-------
3
StrTxd xdata sys_txd;
4
/**/
/*
**************************************
*/
5
uint8 lchksum(uint8 data_len);
//
求LENTH_SUM函数
6
void
txd_sta(
void
);
//
发送系统告警信息
7
void
txd_man(
void
);
//
发送厂家信息
8
void
txd_uni(uint8 cid2);
//
发送系统通信信息
9
/**/
/*
****************************************
*/
10
void
package(
void
);
//
数据打包成ASCII码
11
void
chksum (
void
);
//
求校验和
12
void
com(
void
);
//
公共的发送函数
13
/**/
/*
****************************************
*/
14
uint8 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
/**/
/*
****************************************
*/
31
void
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
/**/
/*
****************************************
*/
57
void
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
/**/
/*
****************************************
*/
104
void
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
/**/
/*
****************************************
*/
129
void
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
/**/
/*
****************************************************
*/
155
void
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 版本
<