Python_Example_modbus协议 串口 _接收_处理_响应 实现程序
2018-09-13
Author: 楚格
IDE: Pycharm2018.02 Python 3.7
KeyWord : 串口数据发送与接收 modbus CAN
Explain:
思路:
1.打开串口 (Function_Serial_Info() # 打开串口)
2.循环接收数据 (Function_Receive_Data() # 接收函数)
3.处理数据(暂时是赋值,未作读取Excel处理)[数据的modbus以及添加]
4.响应数据(Function_Handle_Reveice() # 处理函数)
5发送数据(Function_Send_Data()#发送函数)
1------------------------------------------------------------------------------------------------------------------
1 __all__ = []2
3 import sys
4 import os
5
6 import re
7 import string
8 import binascii
9 import array
10 import signal
11 import serial
12 import time
13 from time import sleep
14
15 # =========================================
16
17
18 \'\'\'
19 # ------------------------------------------
20 # 导入:本文件夹中 .py 模块
21 # 直接引用模块名称
22 # ------------------------------------------
23 \'\'\'
24 # preject module
25 from Testing_CRC import *
26
27
28 # ============================================================================
29
30
31
32 \'\'\'
33 # ============================================================================
34 # Function: 串口设置 函数
35 # Explain :
36 # :
37 # ============================================================================
38 \'\'\'
39 def Function_Serial_Info():
40 print(\'串口初始化 Function_Serial_Info\')
41 # -----------------------------
42
43 global global_var_serial_init
44 global global_var_serial_band
45
46 # 必须设置串口
47 local_var_serial_func = True
48
49 while local_var_serial_func:
50
51 print("默认请输入:1 \n重新输入为:2")
52
53 # default = input(\'您的请选择: \')
54 default = "1" # debug
55
56 if default == "1":
57 global_var_serial_init = serial.Serial(port="COM5", baudrate=115200, timeout=1) # 端口控制
58 local_var_serial_func = False # 结束执行
59
60 elif default == "2":
61 port = input(\'串口号(数字): \', ) # 端口号
62
63 local_var_serial_nunber = True
64
65 while local_var_serial_nunber:
66 print(\'可选波特率:1 = 9600 \n\t\t 2 = 115200\')
67 global_var_serial_band = input(\'波特率序号: \')
68
69 if global_var_serial_band == "1":
70 global_var_serial_band = 9600
71 local_var_serial_nunber = False
72
73 elif global_var_serial_band == "2":
74 global_var_serial_band = 115200
75 local_var_serial_nunber = False
76
77 else:
78 print(\'超出范围:请重新选择波特率!\')
79 local_var_serial_nunber = True
80
81 # 组装成串口初设信息
82 global_var_serial_init = serial.Serial(port="COM" + port, baudrate=global_var_serial_band, timeout=1) # 端口控制
83
84 local_var_serial_func = False # 结束执行
85
86 else:
87 print(\'超出选择范围,请重新选择序号!\')
88 local_var_serial_func = True # 返回继续执行
89
90 # ------------------------------------------------------
91
92
93 \'\'\'
94 # ============================================================================
95 # Function: 接受数据 函数
96 # Explain : 接受串口收到的数据
97 # :
98 # ============================================================================
99 \'\'\'
100 def Function_Receive_Data():
101 print(\'Function_Receive_Data :\')
102 # ======================================
103 global global_var_receive_string # 作为获取到的数据
104
105 # 接收单次数据,外部进行处理 SINGLE #循环接收数据,内部进行处理 LOOP
106 FREQUENCY = True
107 SINGLE = False
108 LOOP = True
109
110 if FREQUENCY == SINGLE:
111 print(SINGLE)
112 # 待开发模块
113
114 elif FREQUENCY ==LOOP:
115 print(\'LOOP: \')
116 # ------------------------------------------------------
117 line = global_var_serial_init.readline() # 读取全部内容
118 print("Len :", len(line), " Type :", type(line), " readline : %s" % line)
119
120 # 字节变成字符串,目的是方便处理数据
121 types_transform_string = line.hex() # 字节变成字符串
122 print("Len :", len(types_transform_string), type(types_transform_string), types_transform_string)
123
124 # ------------------------------------------------------
125 # 数据名称变换 目的是作为全局变量
126 global_var_receive_string = types_transform_string
127
128 # return global_var_receive_string
129
130 else:
131 pass
132 # ------------------------------------------------------
133
134 \'\'\'
135 # ============================================================================
136 # Function: 发送数据 函数
137 # Explain : 发送数据到串口
138 # golal_var_result_send_data
139 # ============================================================================
140 \'\'\'
141 def Function_Send_Data(send_data):
142 print(\'发送指令函数 Function_Send_Data\')
143 # ---------------------------
144 print(\'\'\'
145 ---- Info of Send Data Parameter ----
146 Send data : %s
147 Serial Port : %s
148 \'\'\' % ( send_data,global_var_serial_init.port)
149 )
150
151 # 判断是字符串还是字节
152 # or define b\'string\',bytes should be used not str
153 # serInstance.write(atCmdStr.encode(\'utf-8\'))
154
155 local_var_send_data_buff =send_data
156 #--------------------------------------
157 # 发送函数 核心语句 输出接口
158 global_var_serial_init.write(local_var_send_data_buff)
159 #--------------------------------------
160
161 # global_var_serial_init.close() # 关闭串口
162 # global_var_serial_init.open() # 打开端口
163 # global_var_serial_init.isOpen() #串口是否被打开
164 # ---------------------------------------------------------
165 \'\'\'
166 # ============================================================================
167 # Function: 数据处理 函数
168 # Explain: 接收数据进行处理
169 # global_var_receive_string
170 # ============================================================================
171 \'\'\'
172 def Function_Handle_Reveice():
173 print(\'Function_Handle_Reveice : \')
174 # ======================================
175 # global global_var_send_data
176 global global_var_crc_value
177
178 local_var_handle_data = global_var_receive_string
179
180 # 字符串重新规整 剪断拼接字符串
181 DIVISION = 24
182 local_var_handle_data = local_var_handle_data[10:] +local_var_handle_data[:10]
183 local_var_Temp_1 =local_var_handle_data[ :DIVISION] # 新划分的数据 local_var_Temp_1
184 local_var_Temp_2 =local_var_handle_data[DIVISION: ] # 新划分的数据 local_var_Temp_2
185
186 print(\'\'\'
187 ---- info of new string ----
188 local_var_Temp_1 : %s
189 CAN_ID : %s
190 Modbus_data : %s
191 local_var_Temp_2 : %s
192 CAN_ID : %s
193 Modbus_data : %s
194 \'\'\' % (local_var_Temp_1,local_var_Temp_1[:8],local_var_Temp_1[8:],
195 local_var_Temp_2, local_var_Temp_2[:8], local_var_Temp_2[8:]
196 )
197 )
198
199 # 结果存留区
200 \'\'\'
201 #---------------------------------------------------------------------------------------
202 # 0x04 功能码请求报文格式说明
203 #
204 # 数据含义 设备地址 功能码 寄存器起始地址 寄存器数量 CRC校验码
205 # 字节数 1 1 2 2 2 (Bytes)
206 # 说明 0-255 0x04 0x0000-0xFFFF 1-125(0x7D)
207 #
208 # 0x04 功能码请求正常回复报文格式说明
209 #
210 # 数据含义 设备地址 功能码 字节数 数据内容 CRC校验码
211 # 字节数 1 1 1 2xN 2 (Bytes)
212 # 说明 0-255 0x04 2×N :2-250 N 为被请求的寄存器数
213 # ---------------------------------------------------------------------------------------
214 \'\'\'
215 # request data format
216 L_DIVI = 0
217 result_CAN_ID = local_var_Temp_1[(L_DIVI + 0):(L_DIVI + 8)]
218 result_slave_address = local_var_Temp_1[(L_DIVI + 8):(L_DIVI + 10)]
219 result_slave_function = local_var_Temp_1[(L_DIVI + 10):(L_DIVI + 12)]
220 result_slave_register = local_var_Temp_1[(L_DIVI + 12):(L_DIVI + 16)]
221 result_slave_number = local_var_Temp_1[(L_DIVI + 16):(L_DIVI + 20)]
222
223 # 根据不同 result_CAN_ID 进行处理,包括组包 response data
224
225 if result_CAN_ID == \'00000001\':
226 print(result_CAN_ID,result_slave_register,result_slave_number)
227 \'\'\'
228 # 保存CANID addr function REG && NUM (需要判断进行处理) 然后进行CRC
229 # 进行处理,先赋值,后变量读取,最后读取Excel
230 \'\'\'
231 if (result_slave_register == \'09c3\') and (result_slave_number == \'0052\' ):
232
233 # 这里是Excel接口 后期可以读取data 填充
234 Local_temp_value = \'080102030405060708\'# CRC = 0x D4C9
235
236 #--------------------
237 # 预处理目的:添加 CRC码
238 local_var_modbus_data = result_slave_address + result_slave_function + Local_temp_value
239 Pack_modbus_data = Function_HexString_Trans(local_var_modbus_data)
240 Pack_Buff_modbus_data = Function_Modbus_CRC(Pack_modbus_data,0)
241
242 Pack_Buff_CAN_data = result_CAN_ID # 作为格式对称保留
243
244 local_var_result_send_data = Function_HexString_Trans(Pack_Buff_CAN_data) + Pack_Buff_modbus_data
245
246 # * *************************
247 if BOOT_DEBUG : # 开发层
248 print(\'result_return_data: \', local_var_result_send_data)
249
250 #--------------------------
251 # handle data finish got together package
252 # 这是处理完成后,组包发送给串口
253 #-------------------------------------------------------------------
254 Function_Send_Data(local_var_result_send_data) # 核心 函数
255 #-------------------------------------------------------------------
256
257 elif result_CAN_ID == \'00000002\':
258 print(\'2\'*111)
259
260 else:
261 pass
262
263
264 # ========================================================
265
266 # ---------------------------------------------------------
267
268 \'\'\'
269 # ============================================================================
270 # Function: Modbus CRC 校验 函数
271 # Explain: 输入参数 列表 [1, 4, 8, 1, 2, 3, 4, 5, 6, 7, 8 ]
272 # 输出参数 列表 [1, 4, 8, 1, 2, 3, 4, 5, 6, 7, 8, 212, 201]
273 # check right: 1 wrong: 0
274 #
275 # ============================================================================
276 \'\'\'
277 def Function_Modbus_CRC(Pack_modbus_data,test_type):
278 print(\'Function_Modbus_CRC : \',)
279 #------------------------------------
280 global global_var_modbus_data_buff
281 global global_var_modbus_check
282
283 if test_type == 0 :
284 # # CRC 校验 添加校验码
285 temp_crc_translate = CalCRC16(Pack_modbus_data, len(Pack_modbus_data)) # 核心步骤
286 # ****************
287 if BOOT_DEBUG: # 开发层
288 print(\'crc_transformation: \', temp_crc_translate, type(temp_crc_translate)) # Int没有Len
289 # -------------------------
290 # # 注意添加先后顺序 先低 后高
291 Pack_modbus_data.append(int(hex(temp_crc_translate & 0xFF), 16))
292 Pack_modbus_data.append(int(hex((temp_crc_translate >> 8) & 0xFF), 16))
293 # print(\'Pack_Buff_modbus_data : \', len(Pack_modbus_data), type(Pack_modbus_data),Pack_modbus_data) # calculation value CRC
294 # -------------------------
295 global_var_modbus_data_buff = Pack_modbus_data # 重新命名
296
297 return global_var_modbus_data_buff
298
299 # ---------------------------------------------------------
300 # CRC 校验检查 check
301 elif test_type == 1 :
302
303 temp_CRC_check = CheckCRC(Pack_modbus_data, len(Pack_modbus_data), 0)
304
305 if temp_CRC_check == 1:
306 print(\'Result :\', temp_CRC_check) # check calculation value
307 print(\'CRC_Check : Right\')
308 global_var_modbus_check = temp_CRC_check # 重新命名
309
310 return global_var_modbus_check
311
312 else:
313 print(\'Result :\', temp_CRC_check) # check calculation value
314 print(\'CRC_Check : wrong\')
315 global_var_modbus_check = temp_CRC_check # 重新命名
316
317 return global_var_modbus_check
318
319 # ---------------------------------------------------------
320 # ---------------------------------------------------------
321 \'\'\'
322 # ============================================================================
323 # 函数 数据转换
324 # Explain: 输入参数:data_trans
325 # 输出参数:global_var_trans_data
326 # 功能 :hex string转换为整形列表
327 # example: AT = \'01F2AA0405\'
328 # SEND_AT = Function_HexString_Trans(AT)
329 # print(SEND_AT)
330 # Function_Send_Data(SEND_AT)
331 # time.sleep(2)
332 # ============================================================================
333 \'\'\'
334 def Function_HexString_Trans(data_trans):
335 print(\'Function_HexString_Trans : \',)
336 #------------------------------------
337 global global_var_trans_data
338
339 temp = bytearray.fromhex(data_trans)
340 global_var_trans_data= list(temp)
341 # print(global_var_trans_data)
342
343 return global_var_trans_data
344
345 # --------------------------------------------
346
347
348
349 # ============================================================================
350
351
352 \'\'\'
353 # ============================================================================
354 # 测试专用
355 # ============================================================================
356 \'\'\'
357 if __name__ == \'__main__\':
358 print(\'-------------------------------------\')
359 print(\'=\t\t 欢迎进入 测试环境 \t\t\t=\')
360 print(\'-------------------------------------\n\')
361
362 Function_Serial_Info() # 打开串口
363 # 需要关闭窗口
364 # global_var_serial_init.close() # 关闭串口
365 # global_var_serial_init.open() # 打开端口
366 print(global_var_serial_init.isOpen())
367
368
369 TEST_RUN = True # 测试层演示
370 USER_DEBUD = True # 用户层调试 False
371 BOOT_DEBUG = True # 开发层调试 False
372
373 # 一直收到数据
374 while True:
375
376 Function_Receive_Data() # 接收函数
377 Function_Handle_Reveice() # 处理函数
378
379 if TEST_RUN:
380 print(\'USER_DEBUD\')
381 # --------------------------
382 else:
383 pass
384
385 # global_var_serial_init.colse()
386 # ===============================================================
1 __all__ = ["CalCRC16","CheckCRC"]2
3 # ===============================================================
4 import crcmod
5
6
7
8 # ===============================================================
9 \'\'\'
10 # ======================================
11 # 校验函数 函数
12 # ======================================
13 \'\'\'
14 def CalCRC16(data, length):
15 print(\' 校验函数 CalCRC16\')
16 print(\'显示输入参数:\',data,\'\t\', length)
17
18 crc=0xFFFF # 初始值 变量申明
19 if length == 0:
20 length = 1
21 ## for j in data:
22 ## crc ^= j
23
24 j = 0
25 while length != 0:
26 crc ^= list.__getitem__(data, j)
27 #print(\'j=0x%02x, length=0x%02x, crc=0x%04x\' %(j,length,crc))
28 for i in range(0,8):
29 if crc & 1:
30 crc >>= 1
31 crc ^= 0xA001
32 else:
33 crc >>= 1
34 length -= 1
35 j += 1
36 ##if length == 0:
37 ## break
38
39 return crc
40
41 # ===============================================================
42 def CheckCRC(data, length, crctype):
43 print(\'校验CRC CheckCRC\')
44 print(\'Length | Type | Data : \',length, type(data), data)
45
46 if length < 3:
47 print(\'The data len(%d) is less than 3!!!\', length)
48 return 0
49
50 crc_res = 0
51 tmp=[0,0,0,0]
52
53 if crctype == 0:
54 crc_res = CalCRC16(data, length-2)
55 tmp[0] = crc_res & 0xFF
56 tmp[1] = (crc_res >> 8) & 0xFF
57
58 if data[length-2] == tmp[0] and data[length-1] == tmp[1]:
59 return 1
60 elif crctype == 1:
61 print(\'CRC32 is not support...\')
62
63 return 0
64 # ===============================================================
65
66
67
68
69
70 # ===============================================================
71 \'\'\'
72 #===============================================================
73 # 测试专用
74 #===============================================================
75 \'\'\'
76 if __name__ == \'__main__\':
77
78 ## Name Identifier-name, Poly Reverse Init-value XOR-out Check
79 ## [\'modbus\',\'CrcModbus\',0x18005,REVERSE,0xFFFF,0x0000,0x4B37]
80 ## crc16 = crcmod.mkCrcFun(0x18005, rev=True, initCrc=0xFFFF, xorOut=0x0000) # rev=True,False
81
82 crc16 = crcmod.mkCrcFun(0x18005, initCrc=0xFFFF,rev=True, xorOut=0x0000) # rev=True,False
83 crc_array = b\'0xFE 0xFD\'
84 crc_calc = crc16(crc_array) #计算得到的CRC
85 a=hex(crc_calc)
86 print(crc_calc,a)
87 print(\'\n\')
88
89 # =========================================
90 crc_value = [0x01, 0x04, 0x13, 0x87, 0x00, 0x30]
91 crc_transformation = CalCRC16(crc_value,len(crc_value))
92 crc_calculation = hex(crc_transformation)
93 # print(\'crc_calculation:\',crc_calculation)
94 tasd = [0x00,0x00]
95 tasd[0] = crc_transformation & 0xFF
96 tasd[1] = (crc_transformation >> 8) & 0xFF
97 H =hex(tasd[0])
98 L =hex(tasd[1])
99 H_value = int(H,16)
100 L_value = int(L,16)
101 crc_value.append(H_value)
102 crc_value.append(L_value)
103 print(crc_value) # calculation value CRC
104
105 # ========================================================
106 print(\'\n\')
107 # crc_value2 = [0x01, 0x04, 0x13, 0x87, 0x00, 0x30,0x44,0xB3]
108 # print(\'crc_value2:\',crc_value2)
109 # crc_cheak=CheckCRC(crc_value2,len(crc_value2),0)
110
111 crc_check=CheckCRC(crc_value,len(crc_value),0)
112 if crc_check == 1:
113 print(\'Right\')
114 else:
115 print(\'wrong\')
116
117 print(crc_check) # check calculation value
以上是 Python_Example_modbus协议 串口 _接收_处理_响应 实现程序 的全部内容, 来源链接: utcz.com/z/388809.html