Qt C++串口SerialPort通訊發送指令讀寫NFC M1卡

本示例使用的發卡器:https://item.taobao.com/item.htm?spm=a21dvs.23580594.0.0.52de2c1bVIuGpf&ft=t&id=18645495882?

一、確定已安裝Qt Serial Port組件

二、在.pro項目文件聲明引用Serialport組件

三、在.h頭文件內引用Serialport組件

四、在.cpp程序中實列化serial,并綁定串口接收數據的槽函數

五、打開串口并設置波特率、數據位、校驗位、停止位?

void MainWindow::on_Butt_Open_clicked()
{if(ui->Butt_Open->text() == "打開串口"){//設置串口為下拉欄所選串口名serial->setPortName(ui->Com_Serial->currentText());//設置波特率switch (ui->Com_Baud->currentIndex()){case 0: serial->setBaudRate(QSerialPort::Baud4800); break;//4800case 1: serial->setBaudRate(QSerialPort::Baud9600);   break;case 2: serial->setBaudRate(QSerialPort::Baud19200); break;case 3: serial->setBaudRate(QSerialPort::Baud38400);   break;case 4: serial->setBaudRate(QSerialPort::Baud57600);   break;case 5: serial->setBaudRate(QSerialPort::Baud115200);   break;default: break;}//設置數據位數switch (ui->Com_Size->currentIndex()){case 0:serial->setDataBits(QSerialPort::Data5); break;//1位case 1:serial->setDataBits(QSerialPort::Data6); break;case 2:serial->setDataBits(QSerialPort::Data7); break;//1位case 3:serial->setDataBits(QSerialPort::Data8); break;default: break;}//設置校驗位switch (ui->Com_Parity->currentIndex()){case 0:serial->setParity(QSerialPort::NoParity);   break;//無校驗位case 1:serial->setParity(QSerialPort::OddParity);  break;case 2:serial->setParity(QSerialPort::EvenParity);  break;case 3:serial->setParity(QSerialPort::MarkParity);  break;default: break;}//設置停止位switch (ui->Com_Stop->currentIndex()){case 0:serial->setStopBits(QSerialPort::OneStop); break;//1位case 1:serial->setStopBits(QSerialPort::OneAndHalfStop); break;case 2:serial->setStopBits(QSerialPort::TwoStop); break;default: break;}//設置流控制//serial->setFlowControl(QSerialPort::NoFlowControl);//無流控制serial->setFlowControl(QSerialPort::SoftwareControl);//打開串口 同時判斷是否成功bool info = serial->open(QIODevice::ReadWrite);if(info == true){qDebug()<<"success";//改變label顏色(指示燈)ui->label_16->setStyleSheet("background-color:rgb(0,255,0);border-radius:10px;");//關閉下拉欄設置使能ui->Com_Serial->setEnabled(false);ui->Com_Baud->setEnabled(false);ui->Com_Size->setEnabled(false);ui->Com_Parity->setEnabled(false);ui->Com_Stop->setEnabled(false);//改變按鈕文本為“關閉串口”ui->Butt_Open->setText(tr("關閉串口"));ui->Label_status->setText("");}else{qDebug()<<"fail";QMessageBox::critical (this, "警告", "串口打開失敗!", QMessageBox::Ok);}}else{   //關閉串口serial->clear();serial->close();//改變label顏色(指示燈)ui->label_16->setStyleSheet("background-color:rgb(255,0,0);border-radius:10px;");//恢復下拉欄設置使能ui->Com_Serial->setEnabled(true);ui->Com_Baud->setEnabled(true);ui->Com_Size->setEnabled(true);ui->Com_Parity->setEnabled(true);ui->Com_Stop->setEnabled(true);//改變按鈕文本為“打開串口”ui->Butt_Open->setText(tr("打開串口"));ui->Label_status->setText("請先選擇并打開與發卡器相連的串口!");}
}

?六、向串口發送讀M1卡扇區數據的指令

void MainWindow::on_Butt_ReadCard_clicked()
{unsigned char authkeybuf[6];QString authkeystr=ui->Text_key->toPlainText().trimmed();int checkbuflen=checkhexdata(authkeystr,authkeybuf);if (checkbuflen!=6){QMessageBox::critical(NULL, "提示", QString::asprintf("十六進制認證密鑰輸入錯誤,請輸入 %d", 6)+  " 字節的16進制認證密鑰!");ui->Text_key->setFocus();return;}if (serial->isOpen()) {     //檢查串口是否打開unsigned char databuff[16];databuff[0]=0x0e;databuff[1]=0x78;databuff[2]=0x17;databuff[3]=0x00;  //表示讀取任意卡databuff[4]=0x00;databuff[5]=0x00;databuff[6]=0x00;databuff[7]=ui->Com_Area->currentIndex();  //扇區號databuff[8]=ui->Com_Auth->currentIndex();  //認證方式for(int i=0;i<6;i++){databuff[9+i]=authkeybuf[i];}  //認證密鑰char crc= 0;for (int i=1;i<=14;i++){crc=crc xor databuff[i];}databuff[15]=crc;sendData.clear();sendData.append(reinterpret_cast<const char*>(databuff), sizeof(databuff));FuncCode=2;getdatapoint=0;serial->write(sendData);QString  dispinf=ByteArrayToHexString(sendData);ui->Text_HexData->setPlainText(dispinf);listadditems(getsystime()+"    Send:"+dispinf);}else{QMessageBox::critical (this, "警告", "請先打開與發卡器相連的串口!", QMessageBox::Ok);}
}

七、串口接收數據的槽函數返回讀卡操作結果

void MainWindow::ReadData()//讀取接收到的信息
{    QByteArray buf = serial->readAll();int buflen=buf.length();unsigned char databuff[buflen];std::copy(buf.begin(), buf.end(), databuff);QString str="";int crc=0;if (FuncCode>=0){                        //讀、寫M1、Ntag卡指令,為防止數據分包上傳,先將數據存入緩沖for (int i=0;i<buflen;i++){getdatabuff[getdatapoint]=databuff[i];getdatapoint++;}for (int i=0;i<getdatapoint;i++){    //校驗緩沖區內數據crc,如果校驗成功即認為數據全部接收完,開始分析接收數據str =str+QString::asprintf("%02X ", getdatabuff[i]);if (i>0){crc=crc xor getdatabuff[i];}}}else{  //其他串口調試指令,顯示串口接收數據for (int i=0;i<buflen;i++){          //str =str+QString::asprintf("%02X ", databuff[i]);if (i>0){crc=crc xor databuff[i];}}if(crc!=0){listadditems(getsystime()+" Receive:"+str);}}if(crc==0){  //接收數據校驗成功,數據有效getdatapoint=0;listadditems(getsystime()+" Receive:"+str);QString cardhao="";QString carddata="";switch(FuncCode){case 1:  //只讀卡號case 2:case 3:case 4:if(getdatabuff[0]==1){ //只返回一個字節的有效數據switch(getdatabuff[1]){case 1:str="密碼認證成功,卡片序列號已知,但讀取扇區內容失敗!";break;case 2:str="第0塊讀出,但第1、2塊沒讀出,僅扇區內容前16個字節的數據有效!";break;case 3:str="第0、1塊讀出,但第2塊沒讀出,僅扇區內容前32個字節的數據有效!";break;case 8:str="未尋到卡!";break;case 9:str="兩張以上卡片同時在感應區,發生沖突!";break;case 10:str="無法選擇激活卡片!";break;case 11:str="密碼裝載失敗,卡片序列號已知!";break;case 12:str="密碼認證失敗,卡片序列號已知!";break;}ui->Label_status->setText(str);}else{if(getdatabuff[0]==5){ //返回五個字節的有效數據str="讀取卡號成功";cardhao=QString::asprintf("%02X%02X%02X%02X", getdatabuff[2], getdatabuff[3], getdatabuff[4], getdatabuff[5]);switch(getdatabuff[1]){case 0:if(FuncCode==3){str="寫扇區數據成功";}else{if(FuncCode==4){str="修改扇區密鑰成功";}}break;case 1:str="密碼認證成功,卡片序列號已知,但讀取扇區內容失敗";break;case 2:str="第0塊讀出,但第1、2塊沒讀出,僅扇區內容前16個字節的數據有效";break;case 3:str="第0、1塊讀出,但第2塊沒讀出,僅扇區內容前32個字節的數據有效";break;case 8:str="未尋到卡!";break;case 9:str="兩張以上卡片同時在感應區,發生沖突";break;case 10:str="無法選擇激活卡片";break;case 11:str="密碼裝載失敗,卡片序列號已知";break;case 12:str="密碼認證失敗,卡片序列號已知";break;}ui->Label_status->setText(str+",16進制卡號:"+cardhao);}else{if(getdatabuff[0]==53){ //返回五十三個字節的有效數據cardhao=QString::asprintf("%02X%02X%02X%02X", getdatabuff[2], getdatabuff[3], getdatabuff[4], getdatabuff[5]);for (int i=6;i<=getdatabuff[0];i++){carddata=carddata+QString::asprintf("%02X", getdatabuff[i])+" ";}ui->Text_Data->setPlainText(carddata);ui->Label_status->setText("讀扇區數據成功,16進制卡號:"+cardhao);}}}break;case 5:break;case 6:if (getdatabuff[0]>7){cardhao="16進制卡號:"+QString::asprintf("%02X%02X%02X%02X%02X%02X%02X", getdatabuff[2], getdatabuff[3], getdatabuff[4], getdatabuff[5], getdatabuff[6], getdatabuff[7], getdatabuff[8]);}if(getdatabuff[1]==0){ui->Label_status->setText("寫Ntag卡塊數據成功,"+cardhao);}else{if(getdatabuff[1]==8){ui->Label_status->setText("未尋到卡!"); }else{if(getdatabuff[1]==9){ui->Label_status->setText("兩張以上卡片同時在感應區,發生沖突!"); }else{if(getdatabuff[1]==12){ui->Label_status->setText("密碼認證失敗!"+cardhao); }else{if(getdatabuff[1]==13){ui->Label_status->setText("讀卡失敗,可能要帶密碼操作!"+cardhao); }else{ui->Label_status->setText("寫Ntag卡失敗,"+QString::asprintf("返回錯誤代碼:%d",getdatabuff[1]));}}}}}break;case 7:     //讀Ntag卡返回狀態if (getdatabuff[0]>7){cardhao="16進制卡號:"+QString::asprintf("%02X%02X%02X%02X%02X%02X%02X", getdatabuff[2], getdatabuff[3], getdatabuff[4], getdatabuff[5], getdatabuff[6], getdatabuff[7], getdatabuff[8]);}if(getdatabuff[1]==0){for (int i=11;i<=getdatabuff[0];i++){carddata=carddata+QString::asprintf("%02X", getdatabuff[i])+" ";}ui->Text_TagData->setPlainText(carddata);ui->Label_status->setText("讀Ntag卡塊數據成功,"+cardhao);}else{if(getdatabuff[1]==8){ui->Label_status->setText("未尋到卡!"); }else{if(getdatabuff[1]==9){ui->Label_status->setText("兩張以上卡片同時在感應區,發生沖突!"); }else{if(getdatabuff[1]==12){ui->Label_status->setText("密碼認證失敗!"+cardhao); }else{if(getdatabuff[1]==13){ui->Label_status->setText("讀卡失敗,可能要帶密碼操作!"+cardhao); }else{ui->Label_status->setText("讀Ntag卡失敗,"+QString::asprintf("返回錯誤代碼:%d",getdatabuff[1]));}}}}}break;case 8:     //讀Ntag卡號返回狀態if(getdatabuff[0]==8 && getdatabuff[1]==0){cardhao=QString::asprintf("%02X%02X%02X%02X%02X%02X%02X", getdatabuff[2], getdatabuff[3], getdatabuff[4], getdatabuff[5], getdatabuff[6], getdatabuff[7], getdatabuff[8]);ui->Label_status->setText("讀Ntag卡號成功,16進制卡號:"+cardhao);}else{if(getdatabuff[0]==1 && getdatabuff[1]==8){ui->Label_status->setText("未尋到卡!");}else{if(getdatabuff[0]==1 && getdatabuff[1]==9){ui->Label_status->setText("讀Ntag卡號失敗,感應區內的卡不是Ntag卡!");}}}break;case 9:     //校驗Ntag卡密鑰if(getdatabuff[0]==3 && getdatabuff[1]==0){QString packhex=QString::asprintf("%02X%02X", getdatabuff[2], getdatabuff[3]);ui->Label_status->setText("Ntag卡密鑰校驗成功,PACK密鑰確認碼:"+packhex);}else{if(getdatabuff[0]==1 && getdatabuff[1]==12){ui->Label_status->setText("Ntag卡密鑰校驗失敗,請先讀取卡號、輸入8位正確的認證密鑰再校驗試試!");}}break;case 10:break;}}
}

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/89788.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/89788.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/89788.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Go 語言開發中用戶密碼加密存儲的最佳實踐

在現代 Web 應用開發中&#xff0c;用戶密碼的安全存儲是系統安全的重要環節。本文將結合 Go 語言和 GORM 框架&#xff0c;詳細介紹用戶密碼加密存儲的完整解決方案&#xff0c;包括數據庫模型設計、加密算法選擇、鹽值加密實現等關鍵技術點。 一、數據庫模型設計與 GORM 實踐…

優化Facebook廣告投放的五大關鍵策略

一、精確篩選目標國家用戶在Audience的locations設置目標國家時&#xff0c;務必勾選"People living in this location"選項。系統默認會選擇"People living in this location or recently in this location"&#xff0c;這會擴大受眾范圍&#xff0c;包含…

Debian-10-standard用`networking`服務的`/etc/network/interfaces`配置文件設置多網卡多IPv6

Debian-10-buster-standard用networking服務的/etc/network/interfaces配置文件設置多網卡多IPv6 Debian-10-buster-standard用networking服務的/etc/network/interfaces配置文件設置多網卡多IPv6 250703_123456 三塊網卡 : enp0s3 , enp0s8 , enp0s9 /etc/network/interfac…

對話式 AI workshop:Voice Agent 全球五城開發實錄

過去幾個月&#xff0c;TEN Framework 團隊與 Agora 和聲網圍繞 “對話式AI”題&#xff0c;踏上了橫跨全球五大城市的精彩旅程——東京、舊金山、巴黎、北京、京都。 五場精心籌備的Workshop 場場爆滿&#xff0c; 匯聚了來自當地及全球的開發者、創業者、產品經理與語音技術愛…

算法學習筆記:6.深度優先搜索算法——從原理到實戰,涵蓋 LeetCode 與考研 408 例題

在計算機科學領域&#xff0c;搜索算法是解決問題的重要工具&#xff0c;其中深度優先搜索&#xff08;Depth-First Search&#xff0c;簡稱 DFS&#xff09;憑借其簡潔高效的特性&#xff0c;在圖論、回溯、拓撲排序等眾多場景中發揮著關鍵作用。無論是 LeetCode 算法題&#…

vue create 和npm init 創建項目對比

以下是關于 vue create 和 npm init 的對比分析&#xff1a; 1. 定位與功能 vue create 定位&#xff1a;Vue 官方提供的腳手架工具&#xff0c;基于 Vue CLI&#xff0c;用于快速創建標準化的 Vue 項目&#xff0c;支持 Vue 2 和 Vue 3。功能&#xff1a;提供交互式配置&…

C++ bitset 模板類

bitset<256> 數據類型詳解 bitset<256> 是 C 標準庫中的一個模板類&#xff0c;用于處理固定大小的位集合&#xff08;Bit Set&#xff09;。它可以高效地操作和存儲二進制位&#xff0c;特別適合需要處理大量布爾標志或簡單計數的場景。 基本定義與特性 1. 模板參…

通信握手言和:PROFINET轉EtherCAT網關讓汽輪機振動數據“破壁”傳輸

某大型電廠的關鍵汽輪機設備采用EtherCAT振動傳感器進行實時監測&#xff0c;但由于工廠PLC振動分析系統基于PROFINET協議&#xff0c;數據無法直接接入&#xff0c;導致振動數據延遲、預警滯后&#xff0c;嚴重影響設備健康管理。傳統的人工巡檢和定期維護難以捕捉早期機械故障…

golang 中當 JSON 數據缺少結構體(struct)中定義的某些字段,會有異常嗎

目錄關鍵影響示例演示潛在問題與解決方案問題 1&#xff1a;邏輯錯誤&#xff08;零值干擾&#xff09;問題 2&#xff1a;忽略可選字段問題 3&#xff1a;第三方庫驗證最佳實踐總結在 Go 語言中&#xff0c;當 JSON 數據缺少結構體&#xff08;struct&#xff09;中定義的某些…

Fiddler 中文版怎么配合 Postman 與 Wireshark 做多環境接口調試?

現代項目中&#xff0c;開發、測試、預發布、生產環境往往分離配置&#xff0c;前端在開發過程中需要頻繁切換接口域名、驗證多環境表現。而接口升級或項目迭代時&#xff0c;還需要做回歸測試&#xff0c;確保老版本接口仍能兼容&#xff0c;避免線上事故。這些環節若僅靠代碼…

釘釘小程序開發技巧:getSystemInfo 系統信息獲取全解析

在釘釘小程序開發中&#xff0c;獲取設備系統信息是實現跨平臺適配和優化用戶體驗的關鍵環節。本文將深入解析 dd.getSystemInfo 接口的使用方法、技術細節與實際應用場景&#xff0c;幫助開發者高效應對多終端開發挑戰。一、接口功能與核心價值dd.getSystemInfo 是釘釘小程序提…

Java項目Maven配置JDK1.8全攻略

目錄 &#x1f9e9; 一、全局環境變量配置&#xff08;推薦系統級統一&#xff09; ?? 二、Maven全局配置&#xff08;多項目統一&#xff09; &#x1f4c2; 三、項目級配置&#xff08;推薦團隊協作&#xff09; &#x1f4bb; 四、IDE配置&#xff08;輔助驗證&#x…

使用tensorflow的線性回歸的例子(六)

波士頓房價 import matplotlib.pyplot as plt %matplotlib inline import tensorflow as tf import numpy as np from sklearn.datasets import load_boston import sklearn.linear_model as sk boston load_boston() features np.array(boston.data) labels np.arra…

YOLOv11深度解析:Ultralytics新一代目標檢測架構創新與實戰指南

?? 2024年Ultralytics重磅推出YOLOv11**:在精度與速度的平衡木上再進一步,參數減少22%,推理速度提升2%,多任務支持全面升級! ?? 一、YOLOv11核心創新:輕量化與注意力機制的完美融合 YOLOv11并非顛覆性重構,而是通過模塊級優化實現“少參數、高精度、快推理”的目標…

基于 SpringBoot+Vue.js+ElementUI 的 “花開富貴“ 花園管理系統設計與實現7000字論文

摘要 本論文詳細闡述了基于 SpringBoot、Vue.js 和 ElementUI 的 "花開富貴" 花園管理系統的設計與實現過程。該系統旨在為花園管理者提供高效、便捷的花園信息管理平臺&#xff0c;實現花卉信息、員工、客戶、訂單等全方位管理功能。論文首先分析了花園管理系統的研…

RESTful API 安裝使用教程

一、RESTful API 簡介 REST&#xff08;Representational State Transfer&#xff09;是一種基于 Web 的架構風格&#xff0c;RESTful API 是使用 HTTP 協議并遵循 REST 原則設計的 API 接口。其核心思想是&#xff1a;使用標準 HTTP 方法&#xff08;GET、POST、PUT、DELETE&…

【行云流水ai筆記】粗粒度控制:推薦CTRL、GeDi 細粒度/多屬性控制:推薦TOLE、GPT-4RL

TOLE模型完整啟動方法指南 TOLE (Token-level Optimization with Language Models) 是一種基于強化學習的可控文本生成方法&#xff0c;通過token級別的反饋實現對文本多個屬性的精確控制。以下是完整的啟動方法指南&#xff1a; 1. 環境準備 1.1 創建虛擬環境 conda creat…

【沉浸式解決問題】idea開發中mapper類中突然找不到對應實體類

目錄 一、問題描述二、場景還原三、原因分析四、解決方案 一、問題描述 mapper類繼承了mybatis-plus的BaseMapper&#xff0c;泛型需要填入實體類&#xff0c;但是不知怎么地突然實體類就報錯了&#xff0c;顯示沒有這個類 二、場景還原 實體類就是死活報錯找不到&#xff0c;所…

初學python的我開始Leetcode題11-2

提示&#xff1a;100道LeetCode熱題-11-1主要是二分查找相關&#xff0c;包括三題&#xff1a;搜索旋轉排序數組、尋找旋轉排序數組中的最小值、尋找兩個正序數組的中位數。由于初學&#xff0c;所以我的代碼部分僅供參考。前言上次的三道二分查找題較為基礎&#xff0c;主要是…

Python 數據分析與可視化 Day 12 - 建模前準備與數據集拆分

? 今日目標 掌握建模前常見準備步驟學會使用 train_test_split() 將數據劃分為訓練集和測試集理解特征&#xff08;X&#xff09;與標簽&#xff08;y&#xff09;的區分學習常見建模流程的輸入要求&#xff08;格式、維度&#xff09;&#x1f4d8; 一、建模前準備流程概覽 數…