常見的硬件通信接口協(xié)議 1.硬件通信接口協(xié)議 很多硬件傳感器需要用到如下的通信協(xié)議 串口(上層應(yīng)用的串口代碼編寫,不是底層的串口代碼編寫)
2.使用串口的傳感器 串口藍(lán)牙,串口wifi 開發(fā)板跟電腦 串口通信的代碼實(shí)現(xiàn) 常見的硬件校驗(yàn)算法有哪些?算法原理是怎么樣?
1.兩個(gè)版本 QT中的串口編程(既可以在window上運(yùn)行,也能在ARM平臺(tái),linux平臺(tái)都能運(yùn)行) linux中的串口編程(只能在ARM平臺(tái),linux平臺(tái)運(yùn)行) 波特率: 串口傳輸數(shù)據(jù)的速度 115200表示每一秒鐘傳輸115200個(gè)比特位 數(shù)據(jù)位:串口傳輸一幀數(shù)據(jù)的位數(shù) 奇偶校驗(yàn):校驗(yàn)--》檢查數(shù)據(jù)收發(fā)是否發(fā)生了錯(cuò)誤 奇校驗(yàn) 偶校驗(yàn) 停止位:標(biāo)記數(shù)據(jù)的結(jié)尾 流控: 當(dāng)數(shù)據(jù)的接收端無(wú)法收到數(shù)據(jù)的時(shí)候,會(huì)通知發(fā)送端停止發(fā)送 2.QT中的串口編程 類和方法 添加的庫(kù).pro: serialport QSerialPortInfo //獲取當(dāng)前系統(tǒng)中所有的串口信息 QSerialPort //表示串口 (1)代碼思路 第一步:獲取當(dāng)前系統(tǒng)所有的串口信息
第二步:創(chuàng)建QSerialPort 串口對(duì)象,配置串口的參數(shù) QSerialPort::QSerialPort(const QString &name) 參數(shù):name --》串口的名字 bool setBaudRate(qint32 baudRate) 參數(shù):baudRate --》你要設(shè)置的波特率 QSerialPort::Baud115200 bool setDataBits(QSerialPort::DataBits dataBits) 參數(shù):dataBits --》QSerialPort::Data8 8位數(shù)據(jù)位 bool setParity(QSerialPort::Parity parity) 參數(shù):parity --》QSerialPort::NoParity 無(wú)奇偶校驗(yàn) QSerialPort::EvenParity 偶校驗(yàn) QSerialPort::OddParity 奇校驗(yàn) bool setStopBits(QSerialPort::StopBits stopBits) 參數(shù):stopBits --》QSerialPort::OneStop 1位停止位 QSerialPort::OneAndHalfStop 1.5位停止位 bool setFlowControl(QSerialPort::FlowControl flowControl) 參數(shù):flowControl --》QSerialPort::NoFlowControl 無(wú)流控 QSerialPort::HardwareControl 硬件流控 QSerialPort::SoftwareControl 軟件流控 第三步:打開串口
第四步:讀寫串口數(shù)據(jù) 讀串口--》接收對(duì)方從串口發(fā)送過來的數(shù)據(jù) [signal] void QIODevice::readyRead() //關(guān)聯(lián)這個(gè)信號(hào),在槽函數(shù)中讀取數(shù)據(jù) read/readAll 寫串口--》你把數(shù)據(jù)從串口發(fā)送給對(duì)方
第五步:關(guān)閉串口 void QSerialPort::close() 3.實(shí)際開發(fā)使用串口的時(shí)候,參數(shù)究竟配置成什么樣?? 答案:認(rèn)真閱讀傳感器廠家提供的使用說明書--》清楚地告訴你串口該如何配置 linux中串口編程 1.重要的結(jié)構(gòu)體
2.思路和方法 第一步:打開串口的驅(qū)動(dòng) 連接電腦 --》/dev/ttySAC0 右上角第一排 --》/dev/ttySAC1 右上角第二排 --》/dev/ttySAC2 右上角第三排 --》/dev/ttySAC3 open() 第二步:配置串口 #include <termios.h> #include <unistd.h> int tcgetattr(int fd, struct termios *termios_p); //獲取當(dāng)前串口的配置信息 參數(shù): fd --》串口的文件描述符 termios_p --》結(jié)構(gòu)體指針,用來保存串口配置信息 (1)設(shè)置串口工作在原始模式(串口只用于數(shù)據(jù)的收發(fā),不用做其它功能)
(2)設(shè)置波特率,數(shù)據(jù)位,停止位,奇偶校驗(yàn)....... 波特率: int cfsetispeed(struct termios *termios_p, speed_t speed); int cfsetospeed(struct termios *termios_p, speed_t speed); 參數(shù):speed --》你要設(shè)置的波特率B115200 B數(shù)字(就是波特率)
奇偶校驗(yàn): 奇校驗(yàn) myios.c_cflag |= (PARODD | PARENB); myios.c_iflag |= INPCK; 偶校驗(yàn) myios.c_cflag |= PARENB; myios.c_cflag &= ~PARODD;/* 清除奇校驗(yàn)標(biāo)志,則配置為偶校驗(yàn)*/ myios.c_iflag |= INPCK; 無(wú)校驗(yàn) myios.c_cflag &= ~PARENB; //使能 --》開啟 失能 --》關(guān)閉
設(shè)置最少讀取的字符數(shù)量和最長(zhǎng)等待時(shí)間 myiosc_cc[VTIME] = 0; myios.c_cc[VMIN] = 4; 讓剛才的設(shè)置生效(激活配置)
第三步:收發(fā)數(shù)據(jù) 發(fā)送 write() 接收 read() 第四步:關(guān)閉串口 close() 串口的應(yīng)用--》通過串口讀寫獲取RFID的卡號(hào) 1.分析RFID的通信協(xié)議 通信協(xié)議:硬件傳感器依照什么樣的數(shù)據(jù)格式去發(fā)送/接收數(shù)據(jù) 類似于tcp通信發(fā)送字符串/發(fā)送表情包 2.分析ISO14443A命令 A命令(請(qǐng)求): 激活RFID讀卡模塊,使之能夠?qū)ν獍l(fā)射電磁場(chǎng),當(dāng)有卡靠近模塊的時(shí)候,模塊能夠感應(yīng)到卡的存在 char abuf[7]; abuf[0]=0x07; //幀長(zhǎng) abuf[1]=0x02; //ISO14443A abuf[2]='A';// A命令 abuf[3]=0x01; //信息長(zhǎng)度 abuf[4]=0x52; //ALL模式 abuf[5]=校驗(yàn)和; abuf[6]=0x03; //幀結(jié)束標(biāo)記 //發(fā)送A命令給模塊 write(fd,abuf,7); //串口發(fā)送A命令給RFID讀卡模塊 主機(jī)--》從機(jī) 命令
//接收模塊回復(fù)的應(yīng)答信息 char rbuf[8]; read(fd,rbuf,8); 從機(jī)--》主機(jī) 狀態(tài) //判斷接收的應(yīng)答信息是否正確 if(rbuf[2]==0x00) //應(yīng)答成功 printf('A命令發(fā)送成功了!\n'); else printf('A命令沒有發(fā)送成功了!\n'); B命令(防碰撞): 防止多張卡同時(shí)進(jìn)入磁場(chǎng)范圍,出現(xiàn)讀寫沖突的問題(只會(huì)挑選其中一張來讀寫) char bbuf[8]; bbuf[0]=0x08; //幀長(zhǎng) bbuf[1]=0x02; //ISO14443A bbuf[2]='B';// B命令 bbuf[3]=0x02; //信息長(zhǎng)度 bbuf[4]=0x93; //一級(jí)防碰撞 bbuf[5]=0x00; bbuf[6]=校驗(yàn)和; bbuf[7]=0x03; //幀結(jié)束標(biāo)記 //發(fā)送B命令給模塊 write(fd,bbuf,8); //串口發(fā)送B命令給RFID讀卡模塊 主機(jī)--》從機(jī) 命令 //接收模塊回復(fù)的應(yīng)答信息 charrbuf[10]; read(fd,rbuf,10); 從機(jī)--》主機(jī) 狀態(tài) //判斷接收的應(yīng)答信息是否正確 if(rbuf[2]==0x00) //應(yīng)答成功 printf('B命令發(fā)送成功了,同時(shí)得到了序列號(hào)!\n'); //卡的序列號(hào) rbuf[4]rbuf[5]rbuf[6]rbuf[7] else printf('B命令沒有發(fā)送成功了!\n'); 練習(xí):(源碼下節(jié)公布) 1.循環(huán)給RFID模塊發(fā)送AB命令,打印得到的卡序列號(hào)
老師給的參考代碼: 第一個(gè):以非阻塞的方式打開串口(無(wú)論串口是否有數(shù)據(jù)可讀,read去讀取串口數(shù)據(jù)的時(shí)候都不會(huì)阻塞) fd = open('/dev/ttySAC1', O_RDWR | O_NOCTTY | O_NONBLOCK); 第二個(gè):使用了多路復(fù)用監(jiān)測(cè)串口是否有數(shù)據(jù)可讀(可讀就調(diào)用read去讀取模塊的響應(yīng)信息) 第三個(gè):延時(shí)--》while(1)執(zhí)行速度太快了,串口的讀寫速度跟不上,所以適當(dāng)延時(shí)一下 |
|