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

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


咨詢
建站咨詢
