身是菩提樹,心如明鏡臺。時時勤擦拭,勿使惹塵埃。
在Linux下,串列埠裝置顯示在/dev目錄下,如果用的是USB轉的串列埠,我們執行下面的命令:
ls /dev/ | grep tty
就可以看到下面的資訊:
ttyUSB0
ttyUSB1
在Linux作業系統下,一切皆檔案,我們讀寫這兩個檔案就是利用串列埠接收和傳送資料。可以用一根母對母的交叉線,將兩個串列埠連線起來,在一端傳送資料,另外一端就能收到資料。我們可以用一個叫做XGCom的工具測試。我們在ttyUSB0這端傳送資料,在ttyUSB1那邊就可以收到資料。
當然我們也可以用C++程式設計讀寫串列埠,程式碼如下:
/* * SerialPort.h * * Created on: 2014年11月3日 * Author: Richard */ #ifndef SERIALPORT_H_ #define SERIALPORT_H_ #include <stdio.h> #include <fcntl.h> #include <pthread.h> //Message Format: head:2 bytes(0xFF,0xEE) | Command:1 byte | Data Size:1 byte | Data:DataSize bytes static const int HeadLen = 2; static const int CommandLen = 1; static const int DataSizeLen = 1; class SerialPort { public: SerialPort(); virtual ~SerialPort(); bool Setup(const char *PortName, int BaudRate, int ByteSize, int Parity, int StopBit); bool Shutdown(); bool CheckBuffer(); void AdvanceBuffer(int Len); virtual void OnRecv(); private: static void *ReadFunc(void *Param); int m_PortHandle; pthread_t m_ThreadID; unsigned char m_Buffer[1024]; int m_BufferSize; bool m_ThreadRunning; }; #endif /* SERIALPORT_H_ */
/* * SerialPort.cpp * * Created on: 2014年11月3日 * Author: jason */ #include "SerialPort.h" #include <unistd.h> #include <string.h> #include <signal.h> #include <termios.h> SerialPort::SerialPort() { // TODO Auto-generated constructor stub m_PortHandle = -1; m_ThreadID = -1; memset(m_Buffer, 0, 1024); m_BufferSize = 0; m_ThreadRunning = true; } SerialPort::~SerialPort() { // TODO Auto-generated destructor stub } bool SerialPort::Setup(const char *PortName, int BaudRate, int ByteSize, int Parity, int StopBit) { m_PortHandle = open(PortName, O_RDWR | O_NOCTTY | O_NDELAY); if (m_PortHandle < 0) { return false; } struct termios Opt; tcgetattr(m_PortHandle, &Opt); Opt.c_cflag |= (CLOCAL | CREAD); //設定控制模式狀態,本地連線,接收使能 Opt.c_cflag &= ~CSIZE; //字元長度,設定資料位之前一定要屏掉這個位 Opt.c_cflag &= ~CRTSCTS; //無硬體流控 Opt.c_cflag |= CS8; //8位資料長度 Opt.c_cflag &= ~CSTOPB; //1位停止位 Opt.c_iflag |= IGNPAR; //無奇偶檢驗位 Opt.c_oflag = 0; //輸出模式 Opt.c_lflag = 0; //不啟用終端模式 cfsetospeed(&Opt, B9600); //設定波特率 tcflush(m_PortHandle, TCIFLUSH); //溢位資料可以接收,但不讀 tcsetattr(m_PortHandle, TCSANOW, &Opt); //TCSANOW:所有改變立即生效 pthread_create(&m_ThreadID, NULL, ReadFunc, this); return true; } bool SerialPort::Shutdown() { m_ThreadRunning = false; pthread_join(m_ThreadID, NULL); close(m_PortHandle); return true; } void SerialPort::AdvanceBuffer(int Len) { for (int i = Len; i < m_BufferSize; i++) { m_Buffer[i - Len] = m_Buffer[i]; } for (int i = m_BufferSize - Len; i < m_BufferSize; i++) { m_Buffer[i] = 0; } m_BufferSize -= Len; } void SerialPort::OnRecv() { if (CheckBuffer()) { int TotalLen = HeadLen + CommandLen + DataSizeLen + m_Buffer[3]; char buff[200]; memset(buff, 0, 200); int Index = sprintf(buff, "Received Data: "); for (int i = 0; i < TotalLen; i++) { Index += sprintf(buff + Index, "%.2X ", m_Buffer[i]); } sprintf(buff + Index, "\n"); printf(buff); write(m_PortHandle, m_Buffer, TotalLen); AdvanceBuffer(TotalLen); } } bool SerialPort::CheckBuffer() { bool Ret = false; if (m_BufferSize >= HeadLen + CommandLen + DataSizeLen ) { if (m_Buffer[0] == 0xFF && m_Buffer[1] == 0xEE) { int TotalLen = HeadLen + CommandLen + DataSizeLen + m_Buffer[3]; if ((m_Buffer[TotalLen] == 0xFF || m_Buffer[TotalLen] == 0x00) && m_Buffer[TotalLen - 1] != 0x00) { Ret = true; } } } return Ret; } void *SerialPort::ReadFunc(void *Param) { SerialPort *Port = (SerialPort *)Param; fd_set HandleSet; while(1) { FD_ZERO(&HandleSet); FD_SET(Port->m_PortHandle, &HandleSet); struct timeval tv; tv.tv_sec = 1; tv.tv_usec = 0; int Ret = select(Port->m_PortHandle + 1, &HandleSet, NULL, NULL, &tv); if (Ret < 0) { break; } if (FD_ISSET(Port->m_PortHandle, &HandleSet)) { int Len = read(Port->m_PortHandle, Port->m_Buffer + Port->m_BufferSize, 100); if (Len > 0) { Port->m_BufferSize += Len; Port->OnRecv(); } } if (Port->m_ThreadRunning == false) { break; } } return NULL; }
我們在main函式裡面寫下測試程式碼:
/*
* main.cpp
*
* Created on: 2014年12月3日
* Author: Richard
*/
#include "SerialPort.h"
#include <unistd.h>
int main(int argc, char **argv) {
SerialPort Port;
Port.Setup("/dev/ttyUSB1", 9600, 8, 0, 0);
for (int i = 0; i < 20; ++ i) {
sleep(1);
}
Port.Shutdown();
return 0;
}
然後以root許可權執行:
我們用XGCom開啟/dev/ttyUSB0,然後傳送0xFFEE0A09010203040506070809,在控制檯那邊就顯示收到的資料。我們程式開啟的是/dev/ttyUSB1,然後我們用收到的資料寫/dev/ttyUSB1,這樣XGCom那裡也收到了資料。就是我們剛才傳送的資料。
相關推薦
身是菩提樹,心如明鏡臺。時時勤擦拭,勿使惹塵埃。
在Linux下,串列埠裝置顯示在/dev目錄下,如果用的是USB轉的串列埠,我們執行下面的命令: ls /dev/ | grep tty 就可以看到下面的資訊: ttyUSB0 ttyUSB1
陳皓專欄 【空谷幽蘭,心如皓月】
讓我們再來看一下使用者管理和程式所有者方面的東西。在Unix下,需要你做的是配置NIS伺服器和NFS伺服器(以Autofs自動mount),簡潔,清楚。到了Windows下,與其相似的是一個叫Domain的東西(主域控制器),首先,為了加入域,你需要重啟電腦(Unix下只需要配置/etc/nsswitch.c
身無綵鳳【雙飛翼】,心有靈犀一點通。
雙飛翼佈局 一、頁面佈局 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="wi
back-不忘初心,方得始終。講講我主場3個月的經歷。題外話。
自己的 如果 主場 的人 公司 教訓 勞動力 好的 藝術品 終於過了這段糾結的時光,有人問,為什麽要工作?可能有的人會說,為了金錢,為了生存,不得已的去工作。但是我覺得工作的意義不僅在此。如果你不熱愛你的工作,你不對你的工作充滿熱情,你的工作不能帶給你成就感。那麽你一定
10.16輸入一個字符串,內有數字和非數字字符,如: a123x456 17960? 302tab5876 將其中連續的數字作為一個整數,依次存放到一數組num中。例如123放在num[0]中,456放在num[1]中……統計共有多少個整數,並輸出這些數。
tab lnp zip sm2 cuc ycm rds qt5 tft 10.16輸入一個字符串,內有數字和非數字字符,如: a123x456 17960? 302tab5876 將其中連續的數字作為一個整數,依次存放到一數組num中。例
心如蘭酒,真正的洞藏美酒
好酒 車間 決定 制造 協調 般的 價值 作用 完成 什麽叫洞藏酒?洞藏酒的好處是什麽呢?白酒的儲藏是白酒制造的過程中必不可少的一道工序,白酒在釀造之後都要儲藏一年以上才能飲用。眾所周知,酒時間越長越好,但是這種觀念是片面的,決定酒品質的儲藏工藝有三大要素:時間、容器、環境
心如到底是個怎麽樣的人,看她這樣對待自己的孩子你就知道了……
class html clas targe tar zha 1025. 自己 title http://www.jobccn.com/zhaopin/job_11684.htmlhttp://www.jobccn.com/zhaopin/job_11682.htmlhttp
1.為什麽 要需要變量。二進制,方便,2.變量是什麽 ,3.聲明變量
http info mage .com 技術分享 圖片 alt 什麽 png 1.為什麽 要需要變量。二進制,方便,2.變量是什麽 ,3.聲明變量
a=[12,34,56],用程式碼求出a裡面三個數字組合,並求出組合裡面的最大數,如可以組成123456,125634,563412,561234,341256,345612。
這個題目主要用到迴圈、字串拼接和排序,程式碼如下: a = [12,34,56] d = [] #儲存新的list for i in a: for j in a: for k in a: if (i != j) and (j != k) and (i != k)
a=[12,34,56],用代碼求出a裏面三個數字組合,並求出組合裏面的最大數,如可以組成123456,125634,563412,561234,341256,345612。
eve rev 重復 最大 字符串拼接 代碼 lis end pen 這個題目主要用到循環、字符串拼接和排序,代碼如下: a = [12,34,56] d = [] #保存新的list for i in a: for j in a: for k in a:
從命令列讀入一個字串,表示一個年份,輸出該年的世界盃冠軍是哪支球隊。如 果該年沒有舉辦世界盃,則輸出:沒有舉辦世界盃
從命令列讀入一個字串,表示一個年份,輸出該年的世界盃冠軍是哪支球隊。如 果該年沒有舉辦世界盃,則輸出:沒有舉辦世界盃。 附錄:截止2009 年,歷屆世界盃冠軍、世界盃冠軍以及對應的奪冠年份: package cn.sc.test; import java.util.HashMap;
設有n個正整數,將他們連線成一排,組成一個最大的多位整數。 如:n=3時,3個整數13,312,343,連成的最大整數為34331213。
題目描述 設有n個正整數,將他們連線成一排,組成一個最大的多位整數。 如:n=3時,3個整數13,312,343,連成的最大整數為34331213。 如:n=4時,4個整數7,13,4,246連線成的最大整數為7424613。 輸入描述: 有多組測試樣例,每組測試樣例包含兩行,第一行為一
實現一個算法,尋找字符串中出現次數最少的、並且首次出現位置最前的字符 如"cbaacfdeaebb",符合要求的是"f",因為他只出現了一次(次數最少)。並且比其他只出現一次的字符(如"d")首次出現的位置最靠前。
出現一次 ole for else 尋找 cti 要求 最小值 一次 實現一個算法,尋找字符串中出現次數最少的、並且首次出現位置最前的字符如"cbaacfdeaebb",符合要求的是"f",因為他只出現了一次(次數最少)。並且比其他只出現一次的字符(如"d")首次出現的位置
12.15有一種數叫回文數,正讀和反讀都一樣,如12321便是一個迴文數。編寫一個程式,從命令列得到一個整數,判斷該數是不是迴文數
有一種數叫回文數,正讀和反讀都一樣,如12321便是一個迴文數。編寫一個程式,從命令列得到一個整數,判斷該數是不是迴文數 package Text6; import java.util.Scanner; public class Zuoyexuanzuo5 { public st
【疾風知勁草,智者必懷仁】此生之路,我將走過;走過這一次,便再也無法重來。所有力所能及的善行,所有充盈於心的善意,我將毫不吝惜,即刻傾於。我將不再拖延,再不淡漠,只因此生之路,再也無法重來。醒掌天下事,醉臥美人膝
此生之路,我將走過;走過這一次,便再也無法重來。所有力所能及的善行,所有充盈於心的善意,我將毫不吝惜,即刻傾於。我將不再拖延,再不淡漠,只因此生之路,再也無法重來。醒掌天下事,醉臥美人膝...
【倚天屠龍記】明志是IBM全球敏捷官方發言人,有10年一線敏捷研發、測試、技術支援、管理、諮詢經驗,為多家世界500強企業做敏捷諮詢和轉型服務。期望通過自己在IBM親身經歷、經驗、感悟的分享幫助您實踐真正敏捷。
倚天屠龍記 明志是IBM全球敏捷官方發言人,有10年一線敏捷研發、測試、技術支援、管理、諮詢經驗,為多家世界500強企業做敏捷諮詢和轉型服務。期望通過自己在IBM親身經歷、經驗、感悟的分享幫助您實踐真正敏捷。...
【《致青春》——雲夢澤】記住那些天, 我找出這素水漫出的青蓮; 像是山間的流水溫柔, 輕拍著心湖石岸卻流淌著歡快憂愁; 像是天空的白鳥掠過眼隙, 飛翔著心園幽夢而忘不記你年輕時的嬌羞。
記住那些天, 我找出這素水漫出的青蓮; 像是山間的流水溫柔, 輕拍著心湖石岸卻流淌著歡快憂愁; 像是天空的白鳥掠過眼隙, 飛翔著心園幽夢而忘不記你年輕時的嬌羞。...
【zoe 【 銀鈴花--給予幸福的勇氣】】【花語】如鈴蘭誕生的憂傷傳說一樣,鈴蘭的幸福會來得額外艱難,並且伴隨著隱約的宿命的憂傷。鈴蘭的守候是風中星星若有若無的嘆息,茫然而幽靜,只有有心才能感應;鈴蘭的氣質如同風中女子堅貞溫婉的愛的信仰一般純粹剔透,只
【花語】如鈴蘭誕生的憂傷傳說一樣,鈴蘭的幸福會來得額外艱難,並且伴隨著隱約的宿命的憂傷。鈴蘭的守候是風中星星若有若無的嘆息,茫然而幽靜,只有有心才能感應;鈴蘭的氣質如同風中女子堅貞溫婉的愛的信仰一般純...
C++入門題目:輸入一行電報文字,將字母變成其下一字母(如’a’變成’b’……’z’變成’a’其它字元不變)。
#include<iostream> #include<string.h> #include<stdio.h> using namespace std; int main() { char x[10000]; int b,d; gets(x
努力+堅持,而且還很年輕(夢在翱翔,心在路上。不忘初心,砥礪前行。)
UML學習筆記詳解 最近一直在學習UML的基礎知識,對於UML的學習和理解需要不斷地進行,總結是必不可少,在此為大家分享一下我的UML學習筆記。