本示例使用的读卡器介绍:RS232串口RFID NFC IC卡读写器可二次开发编程发卡器USB转COM-淘宝网 (taobao.com)
class Ui_Frame(object): def setupUi(self, Frame): Frame.setObjectName("Frame") Frame.resize(826, 571) self.Com_Serial = QtWidgets.QComboBox(Frame) self.Com_Serial.setGeometry(QtCore.QRect(98, 10, 150, 30)) font = QtGui.QFont() font.setFamily("宋体") font.setPointSize(10) self.Com_Serial.setFont(font) self.Com_Serial.setObjectName("Com_Serial") self.Butt_Open = QtWidgets.QPushButton(Frame) self.Butt_Open.setGeometry(QtCore.QRect(13, 10, 71, 30)) font = QtGui.QFont() font.setFamily("宋体") font.setPointSize(10) self.Butt_Open.setFont(font) self.Butt_Open.setObjectName("Butt_Open") self.List_Info = QtWidgets.QListWidget(Frame) self.List_Info.setGeometry(QtCore.QRect(10, 370, 802, 191)) font = QtGui.QFont() font.setFamily("宋体") font.setPointSize(10) self.List_Info.setFont(font) self.List_Info.setObjectName("List_Info") self.Butt_Beep = QtWidgets.QPushButton(Frame) self.Butt_Beep.setGeometry(QtCore.QRect(13, 50, 130, 30)) font = QtGui.QFont() font.setFamily("宋体") font.setPointSize(10) self.Butt_Beep.setFont(font) self.Butt_Beep.setObjectName("Butt_Beep") self.Text_HexData = QtWidgets.QTextBrowser(Frame) self.Text_HexData.setGeometry(QtCore.QRect(150, 290, 660, 71)) font = QtGui.QFont() font.setFamily("宋体") font.setPointSize(10) self.Text_HexData.setFont(font) self.Text_HexData.setReadOnly(False) self.Text_HexData.setObjectName("Text_HexData") self.Butt_Sendhex = QtWidgets.QPushButton(Frame) self.Butt_Sendhex.setGeometry(QtCore.QRect(10, 291, 130, 30)) font = QtGui.QFont() font.setFamily("宋体") font.setPointSize(10) self.Butt_Sendhex.setFont(font) self.Butt_Sendhex.setObjectName("Butt_Sendhex") self.label_2 = QtWidgets.QLabel(Frame) self.label_2.setGeometry(QtCore.QRect(265, 10, 61, 30)) font = QtGui.QFont() font.setFamily("宋体") font.setPointSize(12) self.label_2.setFont(font) self.label_2.setObjectName("label_2") self.Com_Baud = QtWidgets.QComboBox(Frame) self.Com_Baud.setGeometry(QtCore.QRect(327, 10, 71, 30)) font = QtGui.QFont() font.setFamily("宋体") font.setPointSize(10) self.Com_Baud.setFont(font) self.Com_Baud.setObjectName("Com_Baud") self.Com_Baud.addItem("") self.Com_Baud.addItem("") self.Com_Baud.addItem("") self.Com_Baud.addItem("") self.Com_Baud.addItem("") self.Com_Baud.addItem("") self.Com_Size = QtWidgets.QComboBox(Frame) self.Com_Size.setGeometry(QtCore.QRect(489, 10, 41, 30)) font = QtGui.QFont() font.setFamily("宋体") font.setPointSize(10) self.Com_Size.setFont(font) self.Com_Size.setObjectName("Com_Size") self.Com_Size.addItem("") self.Com_Size.addItem("") self.Com_Size.addItem("") self.Com_Size.addItem("") self.label_3 = QtWidgets.QLabel(Frame) self.label_3.setGeometry(QtCore.QRect(429, 10, 61, 30)) font = QtGui.QFont() font.setFamily("宋体") font.setPointSize(12) self.label_3.setFont(font) self.label_3.setObjectName("label_3") self.Com_Stop = QtWidgets.QComboBox(Frame) self.Com_Stop.setGeometry(QtCore.QRect(614, 10, 41, 30)) font = QtGui.QFont() font.setFamily("宋体") font.setPointSize(10) self.Com_Stop.setFont(font) self.Com_Stop.setObjectName("Com_Stop") self.Com_Stop.addItem("") self.Com_Stop.addItem("") self.Com_Stop.addItem("") self.label_4 = QtWidgets.QLabel(Frame) self.label_4.setGeometry(QtCore.QRect(554, 10, 61, 30)) font = QtGui.QFont() font.setFamily("宋体") font.setPointSize(12) self.label_4.setFont(font) self.label_4.setObjectName("label_4") self.label_5 = QtWidgets.QLabel(Frame) self.label_5.setGeometry(QtCore.QRect(677, 10, 61, 30)) font = QtGui.QFont() font.setFamily("宋体") font.setPointSize(12) self.label_5.setFont(font) self.label_5.setObjectName("label_5") self.Com_Parity = QtWidgets.QComboBox(Frame) self.Com_Parity.setGeometry(QtCore.QRect(737, 10, 71, 30)) font = QtGui.QFont() font.setFamily("宋体") font.setPointSize(10) self.Com_Parity.setFont(font) self.Com_Parity.setObjectName("Com_Parity") self.Com_Parity.addItem("") self.Com_Parity.addItem("") self.Com_Parity.addItem("") self.Com_Parity.addItem("") self.Com_Parity.addItem("") self.Com_Parity.setItemText(4, "") self.Sp_Delay = QtWidgets.QSpinBox(Frame) self.Sp_Delay.setGeometry(QtCore.QRect(150, 50, 80, 30)) self.Sp_Delay.setMaximum(65535) self.Sp_Delay.setSingleStep(10) self.Sp_Delay.setObjectName("Sp_Delay") self.Butt_Request = QtWidgets.QPushButton(Frame) self.Butt_Request.setGeometry(QtCore.QRect(11, 90, 130, 30)) font = QtGui.QFont() font.setFamily("宋体") font.setPointSize(10) self.Butt_Request.setFont(font) self.Butt_Request.setObjectName("Butt_Request") self.Butt_ReadCard = QtWidgets.QPushButton(Frame) self.Butt_ReadCard.setGeometry(QtCore.QRect(11, 130, 130, 30)) font = QtGui.QFont() font.setFamily("宋体") font.setPointSize(10) self.Butt_ReadCard.setFont(font) self.Butt_ReadCard.setObjectName("Butt_ReadCard") self.Butt_Writecard = QtWidgets.QPushButton(Frame) self.Butt_Writecard.setGeometry(QtCore.QRect(10, 170, 130, 30)) font = QtGui.QFont() font.setFamily("宋体") font.setPointSize(10) self.Butt_Writecard.setFont(font) self.Butt_Writecard.setObjectName("Butt_Writecard") self.Butt_Changekey = QtWidgets.QPushButton(Frame) self.Butt_Changekey.setGeometry(QtCore.QRect(10, 250, 130, 30)) font = QtGui.QFont() font.setFamily("宋体") font.setPointSize(10) self.Butt_Changekey.setFont(font) self.Butt_Changekey.setObjectName("Butt_Changekey") self.label_6 = QtWidgets.QLabel(Frame) self.label_6.setGeometry(QtCore.QRect(239, 51, 40, 30)) font = QtGui.QFont() font.setFamily("宋体") font.setPointSize(12) self.label_6.setFont(font) self.label_6.setObjectName("label_6") self.Com_Area = QtWidgets.QComboBox(Frame) self.Com_Area.setGeometry(QtCore.QRect(150, 130, 80, 30)) font = QtGui.QFont() font.setFamily("宋体") font.setPointSize(10) self.Com_Area.setFont(font) self.Com_Area.setObjectName("Com_Area") self.Com_Area.addItem("") self.Com_Area.addItem("") self.Com_Area.addItem("") self.Com_Area.addItem("") self.Com_Area.addItem("") self.Com_Area.addItem("") self.Com_Area.addItem("") self.Com_Area.addItem("") self.Com_Area.addItem("") self.Com_Area.addItem("") self.Com_Area.addItem("") self.Com_Area.addItem("") self.Com_Area.addItem("") self.Com_Area.addItem("") self.Com_Area.addItem("") self.Com_Area.addItem("") self.Com_Auth = QtWidgets.QComboBox(Frame) self.Com_Auth.setGeometry(QtCore.QRect(245, 130, 111, 30)) font = QtGui.QFont() font.setFamily("宋体") font.setPointSize(10) self.Com_Auth.setFont(font) self.Com_Auth.setObjectName("Com_Auth") self.Com_Auth.addItem("") self.Com_Auth.addItem("") self.Text_key = QtWidgets.QTextBrowser(Frame) self.Text_key.setGeometry(QtCore.QRect(471, 130, 140, 30)) font = QtGui.QFont() font.setFamily("宋体") font.setPointSize(10) self.Text_key.setFont(font) self.Text_key.setReadOnly(False) self.Text_key.setObjectName("Text_key") self.label_7 = QtWidgets.QLabel(Frame) self.label_7.setGeometry(QtCore.QRect(375, 130, 100, 30)) font = QtGui.QFont() font.setFamily("宋体") font.setPointSize(12) self.label_7.setFont(font) self.label_7.setObjectName("label_7") self.Text_Newkey = QtWidgets.QTextBrowser(Frame) self.Text_Newkey.setGeometry(QtCore.QRect(150, 250, 360, 30)) font = QtGui.QFont() font.setFamily("宋体") font.setPointSize(10) self.Text_Newkey.setFont(font) self.Text_Newkey.setReadOnly(False) self.Text_Newkey.setObjectName("Text_Newkey") self.label_8 = QtWidgets.QLabel(Frame) self.label_8.setGeometry(QtCore.QRect(533, 250, 271, 30)) font = QtGui.QFont() font.setFamily("宋体") font.setPointSize(10) self.label_8.setFont(font) self.label_8.setObjectName("label_8") self.Label_Cardno = QtWidgets.QLabel(Frame) self.Label_Cardno.setGeometry(QtCore.QRect(152, 92, 660, 30)) font = QtGui.QFont() font.setFamily("宋体") font.setPointSize(12) self.Label_Cardno.setFont(font) self.Label_Cardno.setText("") self.Label_Cardno.setObjectName("Label_Cardno") self.Text_Data = QtWidgets.QTextBrowser(Frame) self.Text_Data.setGeometry(QtCore.QRect(150, 170, 661, 71)) font = QtGui.QFont() font.setFamily("宋体") font.setPointSize(10) self.Text_Data.setFont(font) self.Text_Data.setReadOnly(False) self.Text_Data.setObjectName("Text_Data") self.Butt_Clear = QtWidgets.QPushButton(Frame) self.Butt_Clear.setGeometry(QtCore.QRect(10, 332, 130, 30)) font = QtGui.QFont() font.setFamily("宋体") font.setPointSize(10) self.Butt_Clear.setFont(font) self.Butt_Clear.setObjectName("Butt_Clear") self.subSerialListenThread=SerialListenThread() self.subSerialListenThread.serial_data.connect(self.SerialGetData) self.subSerialListenThread.start() self.retranslateUi(Frame) self.Butt_Open.clicked.connect(self.Butt_Open_click) self.Butt_Beep.clicked.connect(self.Butt_Beep_click) self.Butt_Request.clicked.connect(self.Butt_Request_click) self.Com_Serial.currentIndexChanged.connect(self.Com_Serialselectionchange) self.Butt_ReadCard.clicked.connect(self.Butt_ReadCard_click) self.Butt_Writecard.clicked.connect(self.Butt_Writecard_click) self.Butt_Changekey.clicked.connect(self.Butt_Changekey_click) self.Butt_Sendhex.clicked.connect(self.Butt_Sendhex_click) self.Butt_Clear.clicked.connect(self.Butt_Clear_click) self.retranslateUi(Frame) QtCore.QMetaObject.connectSlotsByName(Frame) def retranslateUi(self, Frame): _translate = QtCore.QCoreApplication.translate Frame.setWindowTitle(_translate("Frame", "IC-07串口读写器")) self.Butt_Open.setText(_translate("Frame", "打开串口")) self.Butt_Beep.setText(_translate("Frame", "驱动发卡器响声")) self.Butt_Sendhex.setText(_translate("Frame", "发送HEX数据")) self.label_2.setText(_translate("Frame", "波特率:")) self.Com_Baud.setItemText(0, _translate("Frame", "4800")) self.Com_Baud.setItemText(1, _translate("Frame", "9600")) self.Com_Baud.setItemText(2, _translate("Frame", "19200")) self.Com_Baud.setItemText(3, _translate("Frame", "38400")) self.Com_Baud.setItemText(4, _translate("Frame", "57600")) self.Com_Baud.setItemText(5, _translate("Frame", "115200")) self.Com_Size.setItemText(0, _translate("Frame", "5")) self.Com_Size.setItemText(1, _translate("Frame", "6")) self.Com_Size.setItemText(2, _translate("Frame", "7")) self.Com_Size.setItemText(3, _translate("Frame", "8")) self.label_3.setText(_translate("Frame", "数据位:")) self.Com_Stop.setItemText(0, _translate("Frame", "1")) self.Com_Stop.setItemText(1, _translate("Frame", "1.5")) self.Com_Stop.setItemText(2, _translate("Frame", "2")) self.label_4.setText(_translate("Frame", "停止位:")) self.label_5.setText(_translate("Frame", "校验位:")) self.Com_Parity.setItemText(0, _translate("Frame", "N")) self.Com_Parity.setItemText(1, _translate("Frame", "O")) self.Com_Parity.setItemText(2, _translate("Frame", "E")) self.Com_Parity.setItemText(3, _translate("Frame", "M")) self.Butt_Request.setText(_translate("Frame", "仅读取IC卡序列号")) self.Butt_ReadCard.setText(_translate("Frame", "读取IC卡扇区数据")) self.Butt_Writecard.setText(_translate("Frame", "写数据到IC卡扇区")) self.Butt_Changekey.setText(_translate("Frame", "修改IC卡扇区密码")) self.label_6.setText(_translate("Frame", "毫秒")) self.Com_Area.setItemText(0, _translate("Frame", "0 扇区")) self.Com_Area.setItemText(1, _translate("Frame", "1 扇区")) self.Com_Area.setItemText(2, _translate("Frame", "2 扇区")) self.Com_Area.setItemText(3, _translate("Frame", "3 扇区")) self.Com_Area.setItemText(4, _translate("Frame", "4 扇区")) self.Com_Area.setItemText(5, _translate("Frame", "5 扇区")) self.Com_Area.setItemText(6, _translate("Frame", "6 扇区")) self.Com_Area.setItemText(7, _translate("Frame", "7 扇区")) self.Com_Area.setItemText(8, _translate("Frame", "8 扇区")) self.Com_Area.setItemText(9, _translate("Frame", "9 扇区")) self.Com_Area.setItemText(10, _translate("Frame", "10 扇区")) self.Com_Area.setItemText(11, _translate("Frame", "11 扇区")) self.Com_Area.setItemText(12, _translate("Frame", "12 扇区")) self.Com_Area.setItemText(13, _translate("Frame", "13 扇区")) self.Com_Area.setItemText(14, _translate("Frame", "14 扇区")) self.Com_Area.setItemText(15, _translate("Frame", "15 扇区")) self.Com_Auth.setItemText(0, _translate("Frame", "B密码认证")) self.Com_Auth.setItemText(1, _translate("Frame", "A密码认证")) self.Text_key.setHtml(_translate("Frame", "\n" "\n" "FF FF FF FF FF FF
")) self.label_7.setText(_translate("Frame", "旧认证密码:")) self.Text_Newkey.setHtml(_translate("Frame", "\n" "\n" "FF FF FF FF FF FF FF 07 80 69 FF FF FF FF FF FF
")) self.label_8.setText(_translate("Frame", "6字节新A密码+4字节新控制位+6字节新B密码")) self.Text_Data.setMarkdown(_translate("Frame", "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00\n" "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00\n" "\n" "")) self.Text_Data.setHtml(_translate("Frame", "\n" "\n" "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
")) self.Butt_Clear.setText(_translate("Frame", "清除下栏报文"))
#pip3 install pyserial 安装Python串口通讯库
import serial
import time
import sys
import serial.tools.list_ports
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QDateTime
from PyQt5.QtWidgets import QApplication, QWidget, QDesktopWidget,QMessageBox
selecom=0
ser = serial.Serial()
ComIsOpen=False
OrderCode=0
RcvBuff=b''
class SerialListenThread(QThread): # 串口侦听线程
serial_data = pyqtSignal(int,str) # 创建一个信号,触发时传递显示信息给槽函数
def run(self):
global ComIsOpen
global OrderCode
global RcvBuff
while ComIsOpen:
try:
rcvdata = ser.read_all()
if (len(rcvdata) > 0):
if (OrderCode<=1):
GetData = '接收数据:'
for num in range(0, len(rcvdata)):
GetData = GetData + '%02X ' % (rcvdata[num])
self.serial_data.emit(1, GetData)
else:
RcvBuff = RcvBuff + rcvdata
if (len(RcvBuff)>=RcvBuff[0]+2):
deldata=RcvBuff[0:RcvBuff[0]+2]
GetData = '接收数据:'
for num in range(0, len(deldata)):
GetData = GetData + '%02X ' % (deldata[num])
self.serial_data.emit(1, GetData)
crc = 0 # 计算返回数据的校验位
for num in range(1, len(deldata) - 1):
crc = crc ^ deldata[num]
if (crc == deldata[len(deldata) - 1]):
if(OrderCode==2): #寻卡指令返回信息
if (deldata[0] == 1 and deldata[1] == 8):
self.serial_data.emit(2, '未寻到卡!')
elif (deldata[0] == 1 and deldata[1] == 9):
self.serial_data.emit(2, '两张以上卡片同时在感应区,发生冲突!')
elif (deldata[0] == 1 and deldata[1] == 10):
self.serial_data.emit(2, '无法选择激活卡片!')
elif (deldata[0] == 5):
self.serial_data.emit(2, '寻到IC卡,16进制卡号:%02X %02X %02X %02X ' % (deldata[2], deldata[3], deldata[4], deldata[5]))
elif(OrderCode==3): #轻松读IC卡扇区指令返回数据
if (deldata[0] == 1 and deldata[1] == 8):
self.serial_data.emit(2, '未寻到卡!')
elif (deldata[0] == 1 and deldata[1] == 9):
self.serial_data.emit(2, '两张以上卡片同时在感应区,发生冲突!')
elif (deldata[0] == 5):
if (deldata[1] == 1):
self.serial_data.emit(2, '寻到IC卡,16进制卡号:%02X %02X %02X %02X ' % (deldata[2], deldata[3], deldata[4], deldata[5]) + ',密码认证成功,但读取扇区内容失败!')
elif (deldata[1] == 2):
self.serial_data.emit(2, '寻到IC卡,16进制卡号:%02X %02X %02X %02X ' % (deldata[2], deldata[3], deldata[4], deldata[5]) + ',第0块读出,但第1、2块没读出,仅扇区内容前16个字节的数据有效!')
elif (deldata[1] == 3):
self.serial_data.emit(2, '寻到IC卡,16进制卡号:%02X %02X %02X %02X ' % (deldata[2], deldata[3], deldata[4], deldata[5]) + ',第0、1块读出,但第2块没读出,仅扇区内容前32个字节的数据有效!')
elif (deldata[1] == 10):
self.serial_data.emit(2, '寻到IC卡,16进制卡号:%02X %02X %02X %02X ' % (deldata[2], deldata[3], deldata[4], deldata[5]) + ',无法选择激活卡片!')
elif (deldata[1] == 12):
self.serial_data.emit(2, '寻到IC卡,16进制卡号:%02X %02X %02X %02X ' % (deldata[2], deldata[3], deldata[4], deldata[5]) + ',密码认证失败!')
else:
self.serial_data.emit(2, '操作失败,错误代码:' + str(deldata[1]))
elif (deldata[0] == 53):
self.serial_data.emit(2, '寻到IC卡,16进制卡号:%02X %02X %02X %02X ' % (deldata[2], deldata[3], deldata[4], deldata[5]) + ',读取扇区数据成功!')
ReturnInf = ''
for num in range(6, len(deldata) - 1):
ReturnInf = ReturnInf + '%02X ' % (deldata[num])
self.serial_data.emit(3,ReturnInf)
elif (OrderCode == 4):
if (deldata[0] == 1 and deldata[1] == 8):
self.serial_data.emit(2, '未寻到卡!')
elif (deldata[0] == 1 and deldata[1] == 9):
self.serial_data.emit(2, '两张以上卡片同时在感应区,发生冲突!')
elif (deldata[0] == 5):
if (deldata[1] == 0):
self.serial_data.emit(4, '寻到IC卡,16进制卡号:%02X %02X %02X %02X ' % (deldata[2], deldata[3], deldata[4], deldata[5]) + ',写扇区数据成功!')
elif (deldata[1] == 1):
self.serial_data.emit(2, '寻到IC卡,16进制卡号:%02X %02X %02X %02X ' % (deldata[2], deldata[3], deldata[4], deldata[5]) + ',密码认证成功,但写扇区内容失败!')
elif (deldata[1] == 2):
self.serial_data.emit(2, '寻到IC卡,16进制卡号:%02X %02X %02X %02X ' % (deldata[2], deldata[3], deldata[4], deldata[5]) + ',第0块写入成功,但第1、2块写入失败!')
elif (deldata[1] == 3):
self.serial_data.emit(2, '寻到IC卡,16进制卡号:%02X %02X %02X %02X ' % (deldata[2], deldata[3], deldata[4], deldata[5]) + ',第0、1块写入成功,但第2块写入失败!')
elif (deldata[1] == 10):
self.serial_data.emit(2, '寻到IC卡,16进制卡号:%02X %02X %02X %02X ' % (deldata[2], deldata[3], deldata[4], deldata[5]) + ',无法选择激活卡片!')
elif (deldata[1] == 12):
self.serial_data.emit(2, '寻到IC卡,16进制卡号:%02X %02X %02X %02X ' % (deldata[2], deldata[3], deldata[4], deldata[5]) + ',密码认证失败!')
else:
self.serial_data.emit(2, '操作失败,错误代码:' + str(deldata[1]))
elif (OrderCode == 5):
if (deldata[0] == 1 and deldata[1] == 8):
self.serial_data.emit(2, '未寻到卡!')
elif (deldata[0] == 1 and deldata[1] == 9):
self.serial_data.emit(2, '两张以上卡片同时在感应区,发生冲突!')
elif (deldata[0] == 5):
if (deldata[1] == 0):
self.serial_data.emit(4, '寻到IC卡,16进制卡号:%02X %02X %02X %02X ' % (deldata[2], deldata[3], deldata[4], deldata[5]) + ',修改IC卡密码成功!')
elif (deldata[1] == 10):
self.serial_data.emit(2, '寻到IC卡,16进制卡号:%02X %02X %02X %02X ' % (deldata[2], deldata[3], deldata[4], deldata[5]) + ',无法选择激活卡片!')
elif (deldata[1] == 12):
self.serial_data.emit(2, '寻到IC卡,16进制卡号:%02X %02X %02X %02X ' % (deldata[2], deldata[3], deldata[4], deldata[5]) + ',密码认证失败!')
else:
self.serial_data.emit(2, '操作失败,错误代码:' + str(deldata[1]))
RcvBuff = RcvBuff[RcvBuff[0] + 2:]
if(len(RcvBuff)==0):
OrderCode=0
except:
self.serial_data.emit(1, '串口正在接收数据...')
def SerialGetData(self,dispcode,Getdata):
if (dispcode == 1):
self.ListAddItem(Getdata)
elif (dispcode == 2):
self.Label_Cardno.setText(Getdata)
elif (dispcode == 3):
self.Text_Data.setText(Getdata)
self.Butt_Beep_click()
elif (dispcode == 4):
self.Label_Cardno.setText(Getdata)
self.Butt_Beep_click()
def Butt_Clear_click(self):
self.List_Info.clear()
def ListAddItem(self,itemstr):
if self.List_Info.count() > 10:
self.List_Info.clear()
self.List_Info.addItem(itemstr)
self.List_Info.scrollToBottom()
seleid = self.List_Info.count() - 1
self.List_Info.item(seleid).setSelected(True)
def Com_Serialselectionchange(self):
global ComIsOpen
global ser
ser = serial.Serial()
ser.close()
ComIsOpen = False
self.Butt_Open.setText('打开串口')
def Butt_Open_click(self):
global ComIsOpen
global ser
global selecom
global RcvBuff
if(self.Butt_Open.text()=='打开串口'):
port_serial = self.Com_Serial.currentText()
port_baud=int(self.Com_Baud.currentText())
port_bytesize=int(self.Com_Size.currentText())
port_parity=self.Com_Parity.currentText()
port_stopbits=int(self.Com_Stop.currentText())
try:
ser = serial.Serial(port_serial, port_baud, bytesize=port_bytesize, parity=port_parity, stopbits=port_stopbits, xonxoff=False,rtscts=False, dsrdtr=False)
if (ser.isOpen()):
selecom=self.Com_Serial.currentIndex()
self.subSerialListenThread = SerialListenThread()
self.subSerialListenThread.serial_data.connect(self.SerialGetData)
self.subSerialListenThread.start() #开启串口接收线程
RcvBuff=b''
ComIsOpen = True
self.Butt_Open.setText('关闭串口')
except:
res = QMessageBox.critical(None, "警告", " 您选择的串口打开失败,请检查该串口是否已被其他应用占用!",QMessageBox.Yes)
else:
ser = serial.Serial()
ser.close()
ComIsOpen =False
self.Butt_Open.setText('打开串口')
self.Com_Serial.clear() #刷新串口列表,看是否有新串口
port_list = list(serial.tools.list_ports.comports())
for i in range(0, len(port_list)):
self.Com_Serial.addItem(list(port_list[i])[0])
if (self.Com_Serial.count()-1>=selecom ):
self.Com_Serial.setCurrentIndex(selecom)
else:
self.Com_Serial.setCurrentIndex(0)
def Butt_Beep_click(self):
global ComIsOpen
global ser
global OrderCode
global RcvBuff
if(ComIsOpen):
OrderCode=1
beepdelay = self.Sp_Delay.value() # 响声时长,单位豪秒
sdata = bytes([eval('0x03')]) # 1字节指令长度
sdata = sdata + bytes([eval('0x0F')]) # 1字节功能码
sdata = sdata + bytes([beepdelay % 256]) # 2字节蜂鸣响声延时 低位
sdata = sdata + bytes([beepdelay // 256]) # 高位
sdata = sdata + bytes([sdata[1] ^ sdata[2] ^ sdata[3]]) # 1字节异或和校验码
RcvBuff=b''
ser.write(sdata) # 向串口写入数据
SendInf=''
for num in range(0, len(sdata)):
SendInf = SendInf + '%02X ' % (sdata[num])
self.Text_HexData.setText(SendInf)
self.ListAddItem('发送数据:'+SendInf)
else:
QMessageBox.critical(None, "提示", "请先选择打开与读写器相连的串口!", QMessageBox.Yes)
def Butt_Request_click(self):
global ComIsOpen
global ser
global OrderCode
global RcvBuff
if(ComIsOpen):
self.Label_Cardno.setText('')
OrderCode=2
sdata = bytes([eval('0x01'), eval('0xF0'), eval('0xF0')])
RcvBuff=b''
ser.write(sdata) # 向串口写入数据
SendInf=''
for num in range(0, len(sdata)):
SendInf = SendInf + '%02X ' % (sdata[num])
self.Text_HexData.setText(SendInf)
self.ListAddItem('发送数据:'+SendInf)
else:
QMessageBox.critical(None, "提示", "请先选择打开与读写器相连的串口!", QMessageBox.Yes)
def Butt_ReadCard_click(self):
global ComIsOpen
global ser
global OrderCode
global RcvBuff
if(ComIsOpen):
try:
keys = bytes.fromhex(self.Text_key.toPlainText())
except:
QMessageBox.critical(None, "提示", "卡密码输入错误!", QMessageBox.Yes)
return
if(len(keys)!=6):
QMessageBox.critical(None, "提示", "卡密码输入错误!", QMessageBox.Yes)
return
sdata = bytes([eval('0x0E'), eval('0x78'), eval('0x17')]) # 指令长度 、功能码、读写卡操作权限
sdata = sdata + bytes.fromhex('00000000') # 4字节的16进制 要操作的卡号,如果全部取0表示可以 操作任意卡
sdata = sdata + bytes([self.Com_Area.currentIndex()]) # 操作扇区号,取值0-15
sdata = sdata + bytes([self.Com_Auth.currentIndex()]) # 卡片认证方式,1为A密码认证,0为B密码认证,推荐取1
sdata = sdata + keys # 6字节的16进制 卡片认证密码
crc = 0 # 计算校验位
for num in range(1, 15):
crc = crc ^ sdata[num]
sdata = sdata + bytes([crc])
OrderCode=3
RcvBuff=b''
ser.write(sdata) # 向串口写入数据
SendInf = ''
for num in range(0, len(sdata)):
SendInf = SendInf + '%02X ' % (sdata[num])
self.Text_HexData.setText(SendInf)
self.ListAddItem('发送数据:' + SendInf)
else:
QMessageBox.critical(None, "提示", "请先选择打开与读写器相连的串口!", QMessageBox.Yes)
def Butt_Writecard_click(self):
global ComIsOpen
global ser
global OrderCode
global RcvBuff
if(ComIsOpen):
try:
keys = bytes.fromhex(self.Text_key.toPlainText())
except:
QMessageBox.critical(None, "提示", "卡密码输入错误!", QMessageBox.Yes)
return
if(len(keys)!=6):
QMessageBox.critical(None, "提示", "卡密码输入错误!", QMessageBox.Yes)
return
try:
wdata = bytes.fromhex(self.Text_Data.toPlainText())
except:
QMessageBox.critical(None, "提示", "写卡数据输入错误!", QMessageBox.Yes)
return
if(len(wdata)<48):
res = QMessageBox.question(None, "提示", "写卡数据不足48位,是否要补足48位写入?",QMessageBox.Yes | QMessageBox.No)
if (QMessageBox.No == res):
return
else:
wdata=wdata[0:48]
sdata = bytes([eval('0x3E'), eval('0x69'), eval('0x17')]) # 指令长度 、功能码、读写卡操作权限
sdata = sdata + bytes.fromhex('00000000') # 4字节的16进制 要操作的卡号,如果全部取0表示可以 操作任意卡
sdata = sdata + bytes([self.Com_Area.currentIndex()]) # 操作扇区号,取值0-15
sdata = sdata + bytes([self.Com_Auth.currentIndex()]) # 卡片认证方式,1为A密码认证,0为B密码认证,推荐取1
sdata = sdata + keys # 6字节的16进制 卡片认证密码
sdata = sdata + wdata # 48个字节的写入数据
crc = 0 # 计算校验位
for num in range(1, 63):
crc = crc ^ sdata[num]
sdata = sdata + bytes([crc])
OrderCode=4
RcvBuff=b''
ser.write(sdata) # 向串口写入数据
SendInf = ''
for num in range(0, len(sdata)):
SendInf = SendInf + '%02X ' % (sdata[num])
self.Text_HexData.setText(SendInf)
self.ListAddItem('发送数据:' + SendInf)
else:
QMessageBox.critical(None, "提示", "请先选择打开与读写器相连的串口!", QMessageBox.Yes)
def Butt_Changekey_click(self):
global ComIsOpen
global ser
global OrderCode
global RcvBuff
if(ComIsOpen):
try:
keys = bytes.fromhex(self.Text_key.toPlainText())
except:
QMessageBox.critical(None, "提示", "卡密码输入错误!", QMessageBox.Yes)
return
if(len(keys)!=6):
QMessageBox.critical(None, "提示", "卡密码输入错误!", QMessageBox.Yes)
return
try:
newkey = bytes.fromhex(self.Text_Newkey.toPlainText())
except:
QMessageBox.critical(None, "提示", "新密码及控制位输入错误!", QMessageBox.Yes)
return
if(len(newkey)!=16):
QMessageBox.critical(None, "提示", "新密码及控制位输入错误!", QMessageBox.Yes)
return
res = QMessageBox.question(None, "警告", " 您确定要继续执行修改卡密码及控制位的操作吗?如确定修改请务必记住卡的新密码,否则卡片将报废!",QMessageBox.Yes | QMessageBox.No)
if (QMessageBox.Yes == res):
sdata = bytes([eval('0x1F'), eval('0xF1'), eval('0x17')]) # 指令长度 、功能码、读写卡操作权限
sdata = sdata + bytes.fromhex('00000000') # 4字节的16进制 要操作的卡号,如果全部取0表示可以 操作任意卡
sdata = sdata + bytes([self.Com_Area.currentIndex()]) # 操作扇区号,取值0-15
sdata = sdata + bytes([self.Com_Auth.currentIndex()]) # 卡片认证方式,1为A密码认证,0为B密码认证,推荐取1
sdata = sdata + keys # 6字节的16进制 卡片认证密码
sdata = sdata + newkey # 16个字节的新密码
sdata = sdata + bytes([3]) # 取值0只修改A密码,取值2修改AB密码,取值3修改AB密码及控制位
crc = 0 # 计算校验位
for num in range(1, 32):
crc = crc ^ sdata[num]
sdata = sdata + bytes([crc])
OrderCode=5
RcvBuff=b''
ser.write(sdata) # 向串口写入数据
SendInf = ''
for num in range(0, len(sdata)):
SendInf = SendInf + '%02X ' % (sdata[num])
self.Text_HexData.setText(SendInf)
self.ListAddItem('发送数据:' + SendInf)
else:
QMessageBox.critical(None, "提示", "请先选择打开与读写器相连的串口!", QMessageBox.Yes)
def Butt_Sendhex_click(self):
global ComIsOpen
global ser
global OrderCode
global RcvBuff
if(ComIsOpen):
self.Label_Cardno.setText('')
try:
sdata = bytes.fromhex(self.Text_HexData.toPlainText())
except:
QMessageBox.critical(None, "提示", "发送数据输入错误!", QMessageBox.Yes)
return
if(len(sdata)==0):
QMessageBox.critical(None, "提示", "请输入要向串口发送的十六进制数据!", QMessageBox.Yes)
return
OrderCode=0
RcvBuff=b''
ser.write(sdata) # 向串口写入数据
SendInf=''
for num in range(0, len(sdata)):
SendInf = SendInf + '%02X ' % (sdata[num])
self.Text_HexData.setText(SendInf)
self.ListAddItem('发送数据:'+SendInf)
else:
QMessageBox.critical(None, "提示", "请先选择打开与读写器相连的串口!", QMessageBox.Yes)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Frame = QtWidgets.QFrame()
ui = Ui_Frame()
ui.setupUi(Frame)
screen = QDesktopWidget().screenGeometry()
size = Frame.geometry()
# 获得窗口相关坐标
newLeft = (screen.width() - size.width()) // 2
newTop = (screen.height() - size.height()) // 2
# 移动窗口使其居中
Frame.move(newLeft, newTop)
Frame.show()
port_list = list(serial.tools.list_ports.comports())
for i in range(0, len(port_list)):
ui.Com_Serial.addItem(list(port_list[i])[0])
ui.Com_Baud.setCurrentIndex(2)
ui.Com_Size.setCurrentIndex(3)
ui.Com_Stop.setCurrentIndex(0)
ui.Sp_Delay.setMaximum(65535)
ui.Sp_Delay.setValue(50)
ui.Com_Auth.setCurrentIndex(1)
sys.exit(app.exec_())