新聞中心
近年來,隨著技術(shù)的快速發(fā)展,深度學(xué)習(xí)技術(shù)在各個(gè)領(lǐng)域中有著廣泛的應(yīng)用。而在深度學(xué)習(xí)應(yīng)用過程中,很多時(shí)候需要與其他硬件進(jìn)行通信,其中串口通信是一種常見的方式。本文將著重介紹Linux C語言串口編程代碼的實(shí)現(xiàn)方法和注意事項(xiàng)。

一、串口通信基礎(chǔ)知識(shí)
串口通信是指通過串行接口(Serial Port)將數(shù)據(jù)傳輸?shù)接?jì)算機(jī)或其他設(shè)備上。串口通信包括兩個(gè)方面:串口發(fā)送和串口接收,分別對(duì)應(yīng)數(shù)據(jù)的發(fā)送和接收。
在C語言中進(jìn)行串口編程,需要使用到Linux下的一些API函數(shù),包括open、close、read、write、ioctl等,下面將對(duì)這些函數(shù)進(jìn)行簡單介紹。
(1)open函數(shù)
函數(shù)原型為:
“`
int open(const char *pathname, int flags);
“`
作用是打開一個(gè)文件或者設(shè)備,成功打開后返回一個(gè)文件描述符,否則返回-1。
在串口編程中,pathname參數(shù)指定了串口的設(shè)備文件名,比如/dev/ttyUSB0等。
flags參數(shù)則是一些選項(xiàng)組成的位掩碼,包括O_RDON表示以只讀方式打開設(shè)備,O_WRON表示以只寫方式打開設(shè)備,O_RDWR表示以讀寫方式打開設(shè)備,O_NONBLOCK表示以非阻塞方式打開設(shè)備等等。
(2)close函數(shù)
函數(shù)原型為:
“`
int close(int fd);
“`
作用是關(guān)閉指定的文件或設(shè)備。其中fd參數(shù)指定了要關(guān)閉的文件描述符。
(3)read函數(shù)
函數(shù)原型為:
“`
ssize_t read(int fd, void *buf, size_t count);
“`
作用是從串口中讀取數(shù)據(jù),將讀取到的數(shù)據(jù)存到buf中,最多讀取count字節(jié)。函數(shù)返回實(shí)際讀取的字節(jié)數(shù),如果返回0則表示讀到了文件末尾,如果返回-1則表示出現(xiàn)了錯(cuò)誤。
(4)write函數(shù)
函數(shù)原型為:
“`
ssize_t write(int fd, const void *buf, size_t count);
“`
作用是將數(shù)據(jù)寫入到串口中,其中fd參數(shù)指定了要寫入數(shù)據(jù)的文件描述符,buf參數(shù)指定了要寫入的數(shù)據(jù)緩沖區(qū),count參數(shù)指定了要寫入的字節(jié)數(shù)。函數(shù)返回實(shí)際寫入的字節(jié)數(shù),如果返回-1則表示出現(xiàn)了錯(cuò)誤。
(5)ioctl函數(shù)
函數(shù)原型為:
“`
int ioctl(int fd, unsigned long request, …);
“`
作用是通過請(qǐng)求碼request來控制設(shè)備的各種參數(shù)。其中fd參數(shù)指定了要控制的設(shè)備的文件描述符,request參數(shù)則指定了要進(jìn)行的操作,后面的可變參數(shù)則表示一些參數(shù)值。
在串口編程中,比較常用的操作包括B9600、B115200、CS8、CLOCAL、CREAD等。其中,B9600表示串口波特率為9600,B115200表示串口波特率為115200,CS8表示發(fā)送8位數(shù)據(jù),CLOCAL表示忽略調(diào)制解調(diào)器信號(hào)線路,CREAD表示啟動(dòng)接收器。
二、串口編程實(shí)現(xiàn)
現(xiàn)在我們來看具體的串口編程實(shí)現(xiàn)步驟。我們需要打開串口設(shè)備文件,可以使用如下代碼:
“`
int fd = open(“/dev/ttyUSB0”, O_RDWR | O_NOCTTY | O_NDELAY);
if (fd
perror(“open fled”);
return -1;
}
“`
在上面的代碼中,使用O_RDWR選項(xiàng)表示以讀寫方式打開串口設(shè)備,O_NOCTTY選項(xiàng)表示不將端口設(shè)成控制終端,O_NDELAY選項(xiàng)表示不關(guān)心DCD信號(hào)線上的信號(hào),即可以忽略調(diào)制解調(diào)器的控制。
接下來,需要對(duì)串口相關(guān)參數(shù)進(jìn)行配置。需要將文件描述符以串口設(shè)備的方式打開:
“`
struct termios options;
tcgetattr(fd, &options); //獲取串口參數(shù)
cfsetispeed(&options, B115200); //波特率
cfsetospeed(&options, B115200);
options.c_cflag |= CS8; //發(fā)送8位數(shù)據(jù)
options.c_cflag &= ~PARENB; //不使用奇偶校驗(yàn)
options.c_cflag &= ~CSTOPB; //一位停止位
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); //關(guān)閉規(guī)范模式,禁止回顯
options.c_cc[VTIME] = 0; //非阻塞
options.c_cc[VMIN] = 1;
tcsetattr(fd, TCSANOW, &options); //設(shè)置串口參數(shù)
“`
在上面的代碼中,利用tcgetattr函數(shù)獲取串口設(shè)備的參數(shù),并將其存儲(chǔ)在options結(jié)構(gòu)體中。然后,使用cfsetispeed和cfsetospeed函數(shù)配置串口的波特率。接著,使用位運(yùn)算符設(shè)置其他的串口參數(shù),包括發(fā)送8位數(shù)據(jù),不進(jìn)行奇偶校驗(yàn),一位停止位等等。
使用tcsetattr函數(shù)將配置好的串口參數(shù)設(shè)置到串口設(shè)備上。
下一步,就是實(shí)現(xiàn)讀寫串口數(shù)據(jù)的功能。我們可以使用read和write函數(shù)來實(shí)現(xiàn)。比如,發(fā)送一個(gè)字節(jié)的數(shù)據(jù),可以使用如下代碼:
“`
unsigned char data = ‘A’;
write(fd, &data, 1);
“`
在上面的代碼中,將要發(fā)送的數(shù)據(jù)存儲(chǔ)在data變量中,然后通過write函數(shù)將其發(fā)送出去。
同樣地,接收一個(gè)字節(jié)的數(shù)據(jù),可以使用如下代碼:
“`
unsigned char buf[1];
read(fd, buf, 1);
“`
在上面的代碼中,定義了一個(gè)1字節(jié)的緩沖區(qū)buf,然后使用read函數(shù)從串口中讀取數(shù)據(jù),并將其放入緩沖區(qū)中。
當(dāng)不再需要使用串口時(shí),需要使用close函數(shù)將其關(guān)閉:
“`
close(fd);
“`
三、注意事項(xiàng)
在進(jìn)行串口編程時(shí),需要注意一些細(xì)節(jié)問題,比如:
(1)串口波特率要一致
在進(jìn)行串口通信時(shí),發(fā)送方和接收方的波特率必須一致,否則會(huì)出現(xiàn)亂碼等問題。
(2)數(shù)據(jù)位、校驗(yàn)位、停止位要一致
同樣地,發(fā)送方和接收方的數(shù)據(jù)位、奇偶校驗(yàn)和停止位也必須一致。
(3)串口設(shè)置完成后必須進(jìn)行同步
在設(shè)置串口參數(shù)完成后,必須使用tcsetattr函數(shù)將參數(shù)設(shè)置到串口設(shè)備上,才能保證參數(shù)生效。
(4)使用非阻塞方式進(jìn)行串口通信
在進(jìn)行串口通信時(shí),建議使用非阻塞方式,以避免程序阻塞。
(5)注意可能的錯(cuò)誤情況
在進(jìn)行串口通信時(shí),可能會(huì)出現(xiàn)各種錯(cuò)誤情況,比如讀寫超時(shí)、奇偶校驗(yàn)錯(cuò)誤等等,需要進(jìn)行適當(dāng)?shù)奶幚怼?/p>
在進(jìn)行串口編程時(shí),需要注意各種細(xì)節(jié)問題,以保證程序正確、穩(wěn)定地運(yùn)行。
本文通過介紹了Linux C語言串口編程的基本知識(shí)和實(shí)現(xiàn)方法,包括串口通信基礎(chǔ)知識(shí)、串口編程實(shí)現(xiàn)和注意事項(xiàng)等。希望讀者能夠通過本文對(duì)Linux C語言串口編程有更深入的了解,從而更好地應(yīng)用于實(shí)際項(xiàng)目中。
相關(guān)問題拓展閱讀:
- Linux C 配置串口
- linux 串口編程
Linux C 配置串口
配置串口需要包含
頭文件
其中最核心的配置
結(jié)構(gòu)體
為:
如何獲取該結(jié)構(gòu)呢?我們操作串口跟操作文件一樣,也是調(diào)用 open() 函數(shù)來打開串口,
這樣我們就能夠得到一個(gè)
文件描述符
fd ,然后就可以調(diào)用 tcgetattr() 函數(shù)來獲取上述配置結(jié)構(gòu)體了。
Linux 串口默認(rèn)的配置為:
波特率
9600,數(shù)據(jù)位 8 位,無
奇偶校驗(yàn)
,停止位 1 位,無 CTS/RTS 。
以下介紹一些常用的配置項(xiàng):波特率、奇偶校驗(yàn)、數(shù)據(jù)位、停止位、硬件控制流。
相關(guān)接口:
Linux 將串口的波特率辯笑分為了輸入波特率和輸出波特率,不過最常用的場景是將兩者設(shè)置成一樣。
cfgetispeed() 函數(shù)獲取輸入波特率, cfgetospeed() 函數(shù)獲取輸出波特率。 cfsetispeed() 函數(shù)設(shè)置輸入波特率, cfsetospeed() 函數(shù)用于設(shè)置輸如掘出波特率,當(dāng)然 cfsetspeed() 函數(shù)擴(kuò)展為同時(shí)設(shè)置輸入和輸出波特率。
上述接口中的 speed_t 是一系列波特率的標(biāo)志位,例如常用的波特率就為 B115200,參考下述選項(xiàng):
設(shè)置奇渣灶核偶校驗(yàn)位可以通過修改 termios 結(jié)構(gòu)體中的 c_cflag 成員來實(shí)現(xiàn),若無校驗(yàn),則將 PARENB 位設(shè)為 0;若有校驗(yàn),則 PARENB 為 1。之后再根據(jù) PARODD 來區(qū)分奇偶校驗(yàn), PARODD 為 1 表示奇校驗(yàn), PARODD 為 0 表示偶校驗(yàn)。例如設(shè)置無奇偶校驗(yàn)位:
設(shè)置數(shù)據(jù)位可以通過修改 termios 結(jié)構(gòu)體中的 c_cflag 成員來實(shí)現(xiàn),CS5、CS6、CS7 和 CS8 分別代表數(shù)據(jù)位 5、6、7 和 8。不過在設(shè)置數(shù)據(jù)位之前,需要先用 CSIZE 來做屏蔽字段,清楚這幾個(gè)標(biāo)志位,例如設(shè)置數(shù)據(jù)位為 8 位:
設(shè)置停止位可以通過修改 termios 結(jié)構(gòu)體中的 c_cflag 成員來實(shí)現(xiàn), CSTOPB 位為 1 表示 2 位停止位, CSTOPB 位為 0 標(biāo)志 1 位停止位。例如設(shè)置停止位為 1 位:
設(shè)置硬件控制流可以通過修改 termios 結(jié)構(gòu)體中的 c_cflag 成員來實(shí)現(xiàn), CRTSCTS 為 1 表示使用硬件控制流,為 0 表示不使用硬件控制流。例如
使能
硬件控制流:
當(dāng)然,最后還需要用 tcflush() 拋棄存儲(chǔ)在 fd 里的未接收的數(shù)據(jù)。
再利用接口 tcsetattr() 函數(shù)將配置信息寫入文件描述符 fd :
這樣整個(gè)串口最常用的用法就配置完成了。
具體的配置使用可以參考我的項(xiàng)目 HCI-Middleware 里的 hci_transport_uart_linux.c 文件。
參考:
linux 串口編程
循環(huán)讀取串口輸入值時(shí),為什么必須加入換行符才能打印出信息?
應(yīng)該不是換行的問題,應(yīng)該是還在緩存里面,你加個(gè)flush就可以出來,不加可能要等一會(huì)才謹(jǐn)扒出來野晌磨
nread=30,而buff里面只有27個(gè)字符
可能是有\(zhòng)n或者空格
打印頌斗可以這樣,就清楚了
printf(“recevice = “,buf);
成都網(wǎng)站營銷推廣找創(chuàng)新互聯(lián),全國分站站群網(wǎng)站搭建更好做SEO營銷。
創(chuàng)新互聯(lián)(www.cdcxhl.com)四川成都IDC基礎(chǔ)服務(wù)商,價(jià)格厚道。提供成都服務(wù)器托管租用、綿陽服務(wù)器租用托管、重慶服務(wù)器托管租用、貴陽服務(wù)器機(jī)房服務(wù)器托管租用。
當(dāng)前文章:深度學(xué)習(xí)Linux C語言串口編程代碼解析 (linux c語言串口程序代碼)
標(biāo)題路徑:http://www.dlmjj.cn/article/ccdesdd.html


咨詢
建站咨詢
