实现CRC-16校验的C语言代码分析

版权申诉
0 下载量 200 浏览量 更新于2024-11-13 收藏 659B RAR 举报
资源摘要信息: "该资源是一个包含CRC-16(循环冗余校验)算法实现的C语言代码压缩包文件,文件名为crc.rar_16。该压缩包中包含了名为crc.c的C语言源文件,用于计算任意数据序列的CRC-16校验码。CRC广泛应用于数据通信和存储领域,确保数据传输或存储的完整性。CRC-16是一种较为常用的校验方式,它通过一个约定的多项式对数据进行模二除法运算,从而生成一个固定长度(通常是16位)的校验值。" ### CRC-16算法知识点 1. **定义与作用** CRC-16算法是一种基于多项式的编码方法,用于错误检测。它通过在数据后附加一个固定位数(通常是16位)的校验码,用于检测数据在传输或存储过程中是否出错。 2. **工作原理** CRC算法通过选择一个特定的生成多项式(也称为CRC多项式),将数据视为一个大的二进制数。将这个大的二进制数与生成多项式的二进制形式进行模二除法运算,得到的余数即为CRC校验码。 3. **生成多项式** 对于CRC-16,有多种生成多项式,常见的有CRC-16-CCITT(0x1021)、CRC-16-IBM(0x8005)等。不同的多项式生成不同的校验码,但都可以检测错误。 4. **编码过程** - 初始化寄存器(通常为16位)为全0或某个特定值。 - 将数据序列(通常是以字节为单位)按位循环处理,每次循环处理一个字节。 - 每次循环将寄存器中的值与字节数据异或,然后左移,移出的高位补0。 - 检查最高位是否为1,如果是,则用生成多项式的二进制形式与寄存器的值进行异或操作。 - 重复上述步骤,直到处理完所有数据。 - 最终寄存器中的值即为CRC-16校验码。 5. **错误检测** 接收方使用与发送方相同的多项式和算法计算收到数据的CRC校验码,若计算结果与发送方附带的校验码相同,则数据无误。若不相同,则数据在传输过程中可能发生了错误。 6. **应用场景** CRC-16算法广泛应用于串行通信协议中,如串行端口通信、数据存储器中,以确保数据的完整性和可靠性。 ### C语言编程知识点 1. **文件结构** 在本资源中,通过一个名为crc.c的C语言源文件实现CRC-16算法。该文件通常包含算法的实现代码,以及可能的main函数用于测试。 2. **位操作** C语言中的位操作对于实现CRC算法至关重要。位运算符如<<(左移)、>>(右移)、&(与)、^(异或)、|(或)将被用于处理数据序列和寄存器值。 3. **数组与循环** 在C语言实现中,通常会使用数组来表示数据序列,并通过循环来迭代处理每个字节。 4. **函数与模块化** CRC算法的实现可以被封装在一个或多个函数中,以便于代码的重用和模块化。例如,可能包含一个计算单个字节的CRC值的函数,以及一个循环处理整个数据序列的函数。 5. **调试与测试** 在开发CRC算法时,需要编写相应的测试代码来验证算法的正确性。测试可以包括已知数据和校验码的验证,以及随机数据的测试。 通过以上知识点,可以深入理解CRC-16算法的原理和实现方法,以及C语言在编写此算法时的应用。此压缩包内的资源将对开发者在数据完整性校验方面的工作提供支持。
2023-05-27 上传

//XW_crc_p.v `pragma protect begin module DW_crc_p( data_in, crc_in, crc_ok, crc_out ); parameter integer data_width = 16; parameter integer poly_size = 16; parameter integer crc_cfg = 7; parameter integer bit_order = 3; parameter integer poly_coef0 = 4129; parameter integer poly_coef1 = 0; parameter integer poly_coef2 = 0; parameter integer poly_coef3 = 0; input [data_width-1:0] data_in; input [poly_size-1:0] crc_in; output crc_ok; output [poly_size-1:0] crc_out; `define DW_max_data_crc_1 (data_width>poly_size?data_width:poly_size) wire [poly_size-1:0] crc_in_inv; wire [poly_size-1:0] crc_reg; wire [poly_size-1:0] crc_out_inv; wire [poly_size-1:0] crc_chk_crc_in; reg [poly_size-1:0] crc_inv_alt; reg [poly_size-1:0] crc_polynomial; `include "bit_order_crc_function.inc" `include "bit_order_data_function.inc" `include "calculate_crc_w_in_function.inc" `include "calculate_crc_function.inc" `include "calculate_crc_crc_function.inc" generate //begin genvar bit_idx; reg [63:0] crc_polynomial64; reg [15:0] coef0; reg [15:0] coef1; reg [15:0] coef2; reg [15:0] coef3; assign coef0= poly_coef0; assign coef0= poly_coef1; assign coef0= poly_coef2; assign coef0= poly_coef3; assign crc_polynomial64 = {coef3, coef2, coef1, coef0}; assign crc_pollynomial = crc_polynomial64[poly_size-1:0]; case(crc_cfg/2) 0: assign crc_inv_alt = {poly_size{1'b0}}; 1: for(bit_idx = 0; bit_idx<poly_sizel bit_idx=bit_idx+1) assign crc_inv_alt[bit_idx] = (bit_idx % 2)? 1'b0:1'b1; 2: for(bit_idx=0; bit_idx<poly_size; bit_idx=bit_idx+1) assign crc_inv_alt[bit_idx] = (bit_idx % 2)?1'b1:1'b0; 3: assign crc_inv_alt = { poly_size{1'b1}}; endcase endgenerate assign crc_in_inv = bit_order_crc(crc_in) ^ crc_inv_alt; assign crc_reg = calculate_crc(bit_order_data(data_in)); assign crc_out_inv = crc_reg; assign crc_out = bit_order_crc(crc_out_inv)^ crc_inv_alt; assign crc_chk_crc_in = calculate_crc_crc(crc_reg, crc_in_inv); assign crc_ok = (crc_chk_crc_in ==0); `undef DW_max_data_crc_1 endmodule `pragma protect end can you write a testbench for this piece of CRC verilog code so that this verilog file and the testbench can be used togerther by vcs to verify the correctness of this verilog file?

2023-06-14 上传

import serial import modbus_tk.defines as cst from modbus_tk import modbus_rtu import struct # 打开两个串口 com1 = serial.Serial(port='com2', baudrate=38400, bytesize=8, parity='N', stopbits=1) com2 = serial.Serial(port='com3', baudrate=38400, bytesize=8, parity='N', stopbits=1) # 创建Modbus RTU主机(master) master = modbus_rtu.RtuMaster(com1) master.set_timeout(1.0) master.set_verbose(True) # 读取保持寄存器数据 red = master.execute(1, cst.READ_HOLDING_REGISTERS, 0, 9) print(red) # 将字节数组划分为若干个长度为4的子数组 # def hex_f(a,b): # # g1=b # # z=a+g1#高低16位组合 # # z1=hex(z)[2:]#取0x后边的部分 # # # print(z1) # # return struct.unpack('!f', z1.decode('hex'))[0]#返回浮点数 # # e = hex_f(red[0],red[1]) # # print(e) red1 = master.execute(1, cst.READ_HOLDING_REGISTERS, 0, 9)[0] # 这里可以修改需要读取的功能码 print(red1) new = int(red1 * 0.8) print(new) red =master.execute(1, function_code=cst.WRITE_MULTIPLE_REGISTERS, starting_address=0, output_value=[new]) # 读取输入寄存器数据 input_regs = master.execute(1, cst.READ_INPUT_REGISTERS, 0, 9) print(input_regs,1) # 读取输入线圈数据 input_bits = master.execute(1, cst.READ_COILS, 0, 9) print(input_bits,2) # 读取输出线圈数据 output_bits = master.execute(1, cst.READ_DISCRETE_INPUTS, 0, 9) print(output_bits,3) # 将所有读取数据打包为Modbus RTU消息并写入com2串口 data = red + input_regs + input_bits + output_bits com2.write(master._do_crc(data)) # 关闭串口 com1.close() com2.close()AttributeError: 'RtuMaster' object has no attribute '_do_crc'咋修改不报错

2023-05-27 上传
2023-05-27 上传