版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第第頁(yè)Linux下應(yīng)用層操作UART的四種方式:亞洲(程序員)盟主
串口文件
在(linux)中,針對(duì)所有的周邊設(shè)備都提供了設(shè)備文件供用戶訪問(wèn),所以如果要訪問(wèn)串口,只要打開(kāi)相關(guān)的設(shè)備文件即可。
在LInux下串口文件是位于/dev下的
COM1串口一為/dev/ttyS0
COM2串口2為/dev/ttyS1
或者
COM1串口一為/dev/tty(USB)0
COM2串口2為/dev/ttyUSB1
命令查詢串口:
~$ls/dev/ttyS*/dev/ttyS0/dev/ttyS12/dev/ttyS16/dev/ttyS2/dev/ttyS23/dev/ttyS27/dev/ttyS30/dev/ttyS6/dev/ttyS1/dev/ttyS13/dev/ttyS17/dev/ttyS20/dev/ttyS24/dev/ttyS28/dev/ttyS31/dev/ttyS7/dev/ttyS10/dev/ttyS14/dev/ttyS18/dev/ttyS21/dev/ttyS25/dev/ttyS29/dev/ttyS4/dev/ttyS8/dev/ttyS11/dev/ttyS15/dev/ttyS19/dev/ttyS22/dev/ttyS26/dev/ttyS3/dev/ttyS5/dev/ttyS9
方法1:輪詢
1.打開(kāi)串口
fd=open(port,O_RDWR|O_NOCTTY|O_NDELAY);if(fd==-1){perror("open_port:Unabletoopenserialport");return-1;}
2.配置串口
tcgetattr(fd,cfsetispeed(cfsetospeed(options.c_cflag|=(CLOCAL|CRE(AD));options.c_cflagoptions.c_cflagoptions.c_cflagoptions.c_cflag|=CS8;options.c_cflagtcsetattr(fd,TCSANOW,
其中,tcgetattr和tcsetattr函數(shù)用于獲取和設(shè)置串口參數(shù)。cfsetispeed和cfsetospeed函數(shù)用于設(shè)置串口的輸入和輸出波特率,這里設(shè)置為115200。options.c_cflag表示控制標(biāo)志位,用于配置串口控制參數(shù),具體含義如下:
CLOCAL:忽略調(diào)制解調(diào)器的狀態(tài)線,只允許本地使用串口。
CREAD:允許從串口讀取數(shù)據(jù)。
PARENB:?jiǎn)⒂闷媾夹r?yàn)。//返回接收個(gè)數(shù)wri(te)(fd,buf,strlen(buf));//返回發(fā)送長(zhǎng)度,負(fù)值表示發(fā)送失敗
4.關(guān)閉串口
close(fd);
完整示例
intopen_p(or)t(constchar*port){intfd;structterm(ios)options;//打開(kāi)串口設(shè)備fd=open(port,O_RDWR|O_NOCTTY|O_NDELAY);if(fd==-1){perror("open_port:Unabletoopenserialport");return-1;}//配置串口參數(shù)tcgetattr(fd,cfsetispeed(cfsetospeed(options.c_cflag|=(CLOCAL|CREAD);options.c_cflagoptions.c_cflagoptions.c_cflagoptions.c_cflag|=CS8;options.c_cflagtcsetattr(fd,TCSANOW,returnfd;}intmain(){intfd;charbuf[255];intn;//打開(kāi)串口設(shè)備fd=open_port("/dev/ttyUSB0");if(fd==-1){printf("openerr");exit(1);}while(1){//讀取串口數(shù)據(jù)n=read(fd,buf,sizeof(buf));if(n>0){printf("Received:%.*s",n,buf);}//發(fā)送串口數(shù)據(jù)strcpy(buf,"Hello,world!");n=write(fd,buf,strlen(buf));if(n
方法2:中斷讀取示例
上面給出的串口示例是使用輪詢的方式讀取串口數(shù)據(jù),這種方式在某些場(chǎng)景下可能會(huì)占用大量(CPU)資源。實(shí)際上,對(duì)于Linux系統(tǒng)來(lái)說(shuō),還可以使用中斷方式接收串口數(shù)據(jù),這樣可以大大減少CPU的占用率,并且能夠更快地響應(yīng)串口數(shù)據(jù)。
要使用中斷方式接收串口數(shù)據(jù),可以使用select函數(shù)來(lái)監(jiān)聽(tīng)串口文件描述符的可讀事件。當(dāng)串口數(shù)據(jù)可讀時(shí),select函數(shù)將返回,并且可以調(diào)用read函數(shù)來(lái)讀取串口數(shù)據(jù)。這種方式可以避免輪詢操作,只有在串口數(shù)據(jù)可讀時(shí)才會(huì)執(zhí)行讀取操作,因此能夠減少CPU的占用率。
以下是一個(gè)簡(jiǎn)單的使用中斷方式接收串口數(shù)據(jù)的示例程序:
#include#include#include#include#include#includeintmain(){intfd;structtermiosoptions;fd_set(rf)ds;//打開(kāi)串口設(shè)備fd=open("/dev/ttyUSB0",O_RDWR|O_NOCTTY);if(fd0){printf("Receiveddata:%.*s",n,buf);}}//關(guān)閉串口設(shè)備close(fd);return0;}
需要注意的是,在使用中斷方式接收串口數(shù)據(jù)時(shí),需要對(duì)串口文件描述符設(shè)置為非阻塞模式,以便在select函數(shù)返回時(shí)立即讀取串口數(shù)據(jù)??梢允褂胒cntl函數(shù)來(lái)設(shè)置文件描述符的標(biāo)志位,如下所示:
//設(shè)置串口文件描述符為非阻塞模式intflags=fcntl(fd,F_GE(TF)L,0);fcntl(fd,F_SETFL,flags|O_NONBLOCK);
方法3:(信號(hào))的方式接收數(shù)據(jù)
#include#include#include#include#include#includeintfd;voidsigio_handler(intsig){charbuf[256];intn=read(fd,buf,sizeof(buf));if(n>0){printf("Receiveddata:%.*s",n,buf);}}intmain(){structtermiosoptions;structsig(ac)tionsa;//打開(kāi)串口設(shè)備fd=open("/dev/ttyS0",O_RDWR|O_NOCTTY);if(fd
上述代碼中,使用了fcntl函數(shù)將串口文件描述符設(shè)置為異步通知模式,并使用SIGIO信號(hào)來(lái)通知程序串口數(shù)據(jù)已經(jīng)可讀。當(dāng)程序接收到SIGIO信號(hào)時(shí),會(huì)調(diào)用sigio_handler函數(shù)來(lái)讀取并處理串口數(shù)據(jù)。
在這段代碼中,sigemptyset(的作用是將信號(hào)處理函數(shù)在執(zhí)行時(shí)要屏蔽的信號(hào)集合清空,即將其設(shè)置為空集。
每個(gè)進(jìn)程都有一個(gè)信號(hào)屏蔽字,它表示了當(dāng)前被阻塞的信號(hào)集合。當(dāng)一個(gè)信號(hào)被阻塞時(shí),它將被加入到信號(hào)屏蔽字中,而當(dāng)信號(hào)被解除阻塞時(shí),它將被從信號(hào)屏蔽字中移除。如果信號(hào)處理函數(shù)在執(zhí)行時(shí)需要屏蔽其他的信號(hào),則可以使用sigaddset等函數(shù)將需要屏蔽的信號(hào)添加到信號(hào)屏蔽字中。但是,在本例中,我們需要處理的信號(hào)是SIGIO,它通常不需要被屏蔽,因此我們使用sigemptyset函數(shù)將信號(hào)屏蔽字清空,以確保在處理SIGIO信號(hào)時(shí)不會(huì)屏蔽任何其他信號(hào)。
在Linux系統(tǒng)中,使用sigaction函數(shù)注冊(cè)信號(hào)處理函數(shù)時(shí),可以設(shè)置一些標(biāo)志來(lái)指定信號(hào)處理的行為。例如,可以使用SA_RESTART標(biāo)志來(lái)指定當(dāng)系統(tǒng)調(diào)用被信號(hào)中斷時(shí)自動(dòng)重啟該系統(tǒng)調(diào)用。在本例中,由于我們并不需要設(shè)置任何標(biāo)志,因此將sa.sa_flags字段設(shè)置為0即可。這表示信號(hào)處理函數(shù)不需要任何特殊的行為,只需要按照默認(rèn)的方式處理信號(hào)即可。
方法4:使用線程接收串口數(shù)據(jù):
#include#include#include#include#include#includevoid*read_thread(void*arg){intfd=*(int*)arg;charbuf[256];intn;while(1){//讀取串口數(shù)據(jù)n=read(fd,buf,sizeof(buf));if(n>0){printf("Receiveddata:%.*s",n,buf);}}
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度產(chǎn)業(yè)園租賃及產(chǎn)業(yè)孵化基地建設(shè)合同4篇
- 2025年度拆除工程風(fēng)險(xiǎn)評(píng)估分包合同示范文本4篇
- 2025年LED路燈節(jié)能升級(jí)項(xiàng)目購(gòu)銷及維護(hù)合同3篇
- 2025年度商業(yè)街租賃合同標(biāo)準(zhǔn)范本4篇
- 2025年度彩鋼房拆除與裝配式建筑推廣合同范本3篇
- 2025年度廠房建設(shè)項(xiàng)目環(huán)境影響評(píng)價(jià)合同范本4篇
- 2024版招商引資居間合同協(xié)議書范本
- 2025年度電子游戲角色插畫開(kāi)發(fā)合同4篇
- 2025年度生物醫(yī)藥產(chǎn)業(yè)項(xiàng)目合作協(xié)議范本4篇
- 2025年下半年貴州高速公路集團(tuán)限公司統(tǒng)一公開(kāi)招聘119人高頻重點(diǎn)提升(共500題)附帶答案詳解
- 資產(chǎn)評(píng)估服務(wù)房屋征收項(xiàng)目測(cè)繪實(shí)施方案
- 2025年經(jīng)濟(jì)形勢(shì)會(huì)議講話報(bào)告
- 北師大版小學(xué)三年級(jí)上冊(cè)數(shù)學(xué)第五單元《周長(zhǎng)》測(cè)試卷(含答案)
- 國(guó)家安全責(zé)任制落實(shí)情況報(bào)告3篇
- 2024年度順豐快遞冷鏈物流服務(wù)合同3篇
- 六年級(jí)下冊(cè)【默寫表】(牛津上海版、深圳版)(漢譯英)
- 合同簽訂培訓(xùn)
- 電工基礎(chǔ)知識(shí)培訓(xùn)課程
- 鐵路基礎(chǔ)知識(shí)題庫(kù)單選題100道及答案解析
- 金融AI:顛覆與重塑-深化理解AI在金融行業(yè)的實(shí)踐與挑戰(zhàn)
評(píng)論
0/150
提交評(píng)論