目录
一、C语言实现模2-CRC算法
二、Python代码实现模2-CRC算法
三、使用PyQT制作上位机
3.1、制作UI
3.2、转化UI为Python代码
3.3、添加主函数并打包exe
模2-CRC算法模块函数的C语言代码如下,模2-CRC算法的实现原理可以参考另外一篇博客:模2CRC算法。
unsigned short int crc(unsigned char *data_add, unsigned char len_data)
{
unsigned char i=0,len_word=0;
unsigned short int word[100] = { 0x0000 };
unsigned short int crc_value=0x0000;
len_word = len_data / 2;
for (i = 0; i < len_word; i++)
{
word[i]=(data_add[2*i]<<8)+(data_add[2*i+1]);//两个字节合成一个字
word[i]=word[i]>> (i%16) | word[i]<< (16 - (i%16));//对数据字进行循环移位
crc_value = crc_value ^ word[i];//求循环移位后的校验和字
}
crc_value = (crc_value << (len_word%16)) | (crc_value >> (16-(len_word%16)));//对上个结果进行反向循环移位
return crc_value;
}
# 输入字节长度最大100,输出为16位大小的crc_value
def crc16(data_add, len_data):
word = [0] * 100 # python里面没有16位数据类型,定义为int型,数组大小为100
crc_value = 0 # crc的初始值为int类型0
len_word = len_data >> 1 # 字符串是半个字节,所以除以2
for i in range(0, int(len_word)):
str4 = data_add[(i * 4): (4 + i * 4)] # 每次取4个字符串,上位机读进来的是字符串
word[i] = int(str4,16) # 字符串转成10进制 如'0200'→ 512
word[i] = (word[i] >> (i % 16) | (word [i] << (16 - (i % 16))) & 0xFFFF) # 循环移位,因为是int类型,左移之后要& 0xFFFF保证只取低16位
crc_value = crc_value ^ word[i] # 求循环移位后的校验和字
crc_value = (((crc_value << (len_word % 16)) & 0xFFFF) | (crc_value >> (16-(len_word % 16)))) # 对上个结果进行反向循环移位
return crc_value
C语言代码转换成Python代码如上,测试代码如下,输出结果正确,并且字符串之间的英文空格和逗号被去掉,所以对于上位机的输入操作比较友好,可以不用手动去除空格逗号等。
from crc import *
test = '02 00,, 03003f800000000000000000' # 02 00 03 00 3f 80 00 00 00 00 00 00 00 00 30 06
test = test.replace(" ", "") # 去掉空格
test = test.replace(",", "") # 去掉逗号
test_out = crc16(test, int(len(test)/2)) # int(len(test)/2是输入的字节数
print("%X" % test_out) # %X是十六进制大写输出
代码封装为crc.py,开始制作UI界面,打开QTDesigner,新建一个UI,命名为crc_ui.ui设计好UI界面。首先添加QWidget(默认名字为Form),,然后添加QLineEdit(命名为Input并去掉属性Read Only,另外一个命名为Output,保留Read only)、QLabel(添加作者信息、版本号等)、QPushButton(命名为CalcButton)等Object。
打开PyCharm→External Tools里面的PyUIC,将crc_ui.ui转化为crc_ui.py。其中External Tools如何添加QTDesigner和PyUIC可以参考博客设置添加External Tools。
新建 main.py,添加如下代码,使用PyInstaller打包成一个单独的exe,命令:PyInstaller -F main.py -w。其中-F是打包成一个单独的exe,-w是去掉软件启动前的命令行串口,打包后的exe放到了工程目录的dist文件夹下,打开exe测试如图1。整个工程源码下载链接:源码下载。
import sys
from crc import *
from crc_ui import Ui_Form # QWidget命名为Form所以导入的是Ui_Form,同下
from PyQt5.QtWidgets import QApplication, QMainWindow
class myForm(QMainWindow , Ui_Form):
def __init__(self):
super(myForm,self).__init__()
self.setupUi(self)
self.setWindowTitle("CRC计算器") # 命名上位机名称
self.CalcButton.clicked.connect(self.calc_crc)
def calc_crc(self):
Arr_Input = self.Input.text() # 读取输入
Arr_Input = Arr_Input.replace(" ", "") # 去掉空格
Arr_Input = Arr_Input.replace(",", "") # 去掉逗号
Arr_Input = Arr_Input.replace("'", "") # 去掉'
Arr_out_int = crc16(Arr_Input, int(len(Arr_Input) / 2)) # int(len(Arr_Input)/2是输入的有效字节数
Arr_out_hex = '{:02X}'.format(Arr_out_int) # 十进制转换成字符串
self.Output.setText(Arr_out_hex) # QLineEdit使用setText显示字符串 Text Browser使用insertPlainText显示
if __name__=="__main__":
app=QApplication(sys.argv)
win=myForm()
win.show()
sys.exit(app.exec_())