久久婷婷香蕉热狠狠综合,精品无码国产自产拍在线观看蜜,寡妇房东在做爰3,中文字幕日本人妻久久久免费,国产成人精品三上悠亚久久

當前位置:首頁 > 嵌入式培訓 > 嵌入式學習 > 講師博文 > 資深程序員告訴(su)你串口(kou)配置(zhi)的詳(xiang)細流程,不容錯過(guo)

資(zi)深(shen)程序(xu)員(yuan)告訴你(ni)串口(kou)配置的(de)詳細流程,不(bu)容錯過 時間:2018-06-20      來源:未(wei)知

1,按照通(tong)信的(de)基本方式分(fen)類(lei),可(ke)以分(fen)為以下兩類(lei):

1)并(bing)行通(tong)信

2)串行通信兩種。

并(bing)行通(tong)信是(shi)指利用多條數據傳(chuan)輸(shu)(shu)線將(jiang)一個(ge)資料的各位(wei)同時傳(chuan)送。它的特點是(shi)傳(chuan)輸(shu)(shu)速度

快,適用于(yu)短距離通信,但要求傳輸速(su)度(du)較(jiao)高的應用場合(he)。

串行通信是指利(li)(li)用一條傳(chuan)輸(shu)線將資料一位(wei)位(wei)地順序傳(chuan)送。特點是通信線路簡單,利(li)(li)用

簡單的(de)線(xian)纜就可實現通信(xin),降低成本,適用于遠距離通信(xin),但傳輸(shu)速度慢(man)的(de)應用場合。

那(nei)么接下來(lai)我們就(jiu)來(lai)分析串口設置(zhi):

一(yi)般情況下(xia),我們對(dui)串(chuan)口中最基本的包(bao)括(kuo):波特率設置,校驗位和停止位設置。然而(er)串(chuan)口的設置主要(yao)是設置struct termios結(jie)構體的各成員值,如下(xia)所示(shi):

struct termio

{

unsigned short c_iflag; /* 輸入模式標志 */

unsigned short c_oflag; /* 輸出(chu)模式標志(zhi) */

unsigned short c_cflag; /* 控制模(mo)式標志(zhi)*/

unsigned short c_lflag; /*本地模(mo)式標志 */

unsigned char c_line; /* line discipline */

unsigned char c_cc[NCC]; /* control characters */

};

在這個結(jie)構中最(zui)為重要的是c_cflag,通(tong)過對(dui)它(ta)的賦值,用戶(hu)可以設置波(bo)特率、字符大小、

數(shu)據位(wei)、停止(zhi)位(wei)、奇偶校驗(yan)位(wei)和(he)硬件流控等(deng)。另外c_iflag 和(he)c_cc 也是比較常用(yong)的標志。

波特率:即每秒傳輸的(de)位(wei)數,一般情況下(xia)有以(yi)下(xia)幾種:

B0 0波特率(放棄DTR)

B1800 1800波特率

B2400 2400波特率(lv)

B4800 4800波特率(lv)

B9600 9600波特率

B19200 19200波特率

B38400 38400波特率

B57600 57600波特率

B115200 115200波特率

int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)

{

struct termios newtio,oldtio;

/*保存(cun)測試現(xian)有串口(kou)參數(shu)設置,在(zai)這里如(ru)果串口(kou)號等出錯,會(hui)有相關的(de)出錯信息*/

if ( tcgetattr( fd,&oldtio) != 0)

{

perror("SetupSerial 1");

return -1;

}

bzero( &newtio, sizeof( newtio ) );

/*步驟一,設置字(zi)符大小*/

newtio.c_cflag |= CLOCAL | CREAD;

newtio.c_cflag &= ~CSIZE;

/*設置停止位*/

switch( nBits )

{

case 7:

newtio.c_cflag |= CS7;

break;

case 8:

newtio.c_cflag |= CS8;

break;

}

/*設置奇偶校(xiao)驗位*/

switch( nEvent )

{

case 'O': //奇(qi)數

newtio.c_cflag |= PARENB;

newtio.c_cflag |= PARODD;

newtio.c_iflag |= (INPCK | ISTRIP);

break;

case 'E': //偶數

newtio.c_iflag |= (INPCK | ISTRIP);

newtio.c_cflag |= PARENB;

newtio.c_cflag &= ~PARODD;

break;

case 'N': //無奇偶校(xiao)驗位

newtio.c_cflag &= ~PARENB;

break;

}

/*設置波(bo)特率*/

switch( nSpeed )

{

case 2400:

cfsetispeed(&newtio, B2400);

cfsetospeed(&newtio, B2400);

break;

case 4800:

cfsetispeed(&newtio, B4800);

cfsetospeed(&newtio, B4800);

break;

case 9600:

cfsetispeed(&newtio, B9600);

cfsetospeed(&newtio, B9600);

break;

case 115200:

cfsetispeed(&newtio, B115200);

cfsetospeed(&newtio, B115200);

break;

case 460800:

cfsetispeed(&newtio, B460800);

cfsetospeed(&newtio, B460800);

break;

default:

cfsetispeed(&newtio, B9600);

cfsetospeed(&newtio, B9600);

break;

}

/*設(she)置停止(zhi)位(wei)*/

if( nStop == 1 )

newtio.c_cflag &= ~CSTOPB;

else if ( nStop == 2 )

newtio.c_cflag |= CSTOPB;

/*設置等待時(shi)間和最小(xiao)接(jie)收字符*/

newtio.c_cc[VTIME] = 0;

newtio.c_cc[VMIN] = 0;

/*處(chu)理未接(jie)收字符*/

tcflush(fd,TCIFLUSH);

/*激活(huo)新(xin)配置*/

if((tcsetattr(fd,TCSANOW,&newtio))!=0)

{

perror("com set error");

return -1;

}

printf("set done!\n");

return 0;

}

在(zai)配置完串口的相(xiang)關屬性(xing)后,就可對串口進行打(da)開(kai),讀寫操作了。其使(shi)用方(fang)式與文(wen)件操作一樣(yang),區別在(zai)于串口是一個(ge)終(zhong)端設備(bei)。

2,打(da)開串口(kou):

串口位于/dev中,可作為標準文件(jian)的形式(shi)打開,其(qi)中:

串(chuan)口1 /dev/ttyS0

串口2 /dev/ttyS1

fd = open( "/dev/ttyS0", O_RDWR|O_NOCTTY|O_NDELAY);

Open函數中除(chu)普(pu)通參(can)(can)數外,另有兩個參(can)(can)數O_NOCTTY和O_NDELAY。

O_NOCTTY: 通知linix系統,這個程序不會成為這個端口的控制終(zhong)端。

O_NDELAY: 通知Linux系統不(bu)關(guan)心DCD信號(hao)線(xian)所處(chu)的狀態(端口(kou)的另一端是否激活(huo)或者停(ting)止(zhi))。

然(ran)后,恢復串口的(de)狀態為阻塞狀態,用于(yu)等待串口數(shu)據的(de)讀入。用fcntl函數(shu):

fcntl(fd, F_SETFL, 0);

接(jie)著,測試打(da)開(kai)的(de)文件描述府是(shi)否引(yin)用一個終端設備,以進一步(bu)確認串(chuan)口是(shi)否正確打(da)開(kai)。

isatty(STDIN_FILENO);

串口的讀寫與(yu)普通文件一樣,使用read,write函數。

read(fd,buff,8);

write(fd,buff,8);

3,linux串口編程需(xu)要的頭(tou)文件

#include //標準輸入(ru)輸出定義

#include //標準(zhun)函數庫定義

#include //Unix標準函數定義(yi)

#include

#include

#include //文件控制定義

#include //POSIX中(zhong)斷控制定(ding)義

#include //錯(cuo)誤號定義

4,設(she)置數據位、停(ting)止位和校(xiao)驗位

以下是幾(ji)個(ge)數據位(wei)、停(ting)止位(wei)和校驗位(wei)的(de)設置方法(fa):(以下均(jun)為1位(wei)停(ting)止位(wei))

8位數(shu)據位、無(wu)校驗位:

Opt.c_cflag &= ~PARENB;

Opt.c_cflag &= ~CSTOPB;

Opt.c_cflag &= ~CSIZE;

Opt.c_cflag |= CS8;

7位數據(ju)位、奇(qi)校驗:

Opt.c_cflag |= PARENB;

Opt.c_cflag |= PARODD;

Opt.c_cflag &= ~CSTOPB;

Opt.c_cflag &= ~CSIZE;

Opt.c_cflag |= CS7;

7位數(shu)據位、偶校(xiao)驗:

Opt.c_cflag |= PARENB;

Opt.c_cflag &= ~PARODD;

Opt.c_cflag &= ~CSTOPB;

Opt.c_cflag &= ~CSIZE;

Opt.c_cflag |= CS7;

7位數據位、Space校驗(yan):

Opt.c_cflag &= ~PARENB;

Opt.c_cflag &= ~CSTOPB;

Opt.c_cflag &= ~CSIZE;

Opt.c_cflag |= CS7;

5,某(mou)些設置項(xiang)

在上(shang)面我們看到一些比較特殊的設(she)置,下面簡述一下他們的作用。

c_cc數組的VSTART和VSTOP元素被設定成DC1和DC3,代表ASCII標準的XON和XOFF字(zi)符(fu),如果在(zai)傳輸這兩個字(zi)符(fu)的時(shi)候就(jiu)傳不過去,需要把軟件流控(kong)制屏蔽,即:

Opt.c_iflag &= ~ (IXON | IXOFF | IXANY);

 有時(shi)候,在(zai)(zai)用write發送數據時(shi)沒有鍵(jian)入(ru)回車,信息就(jiu)發送不出(chu)去,這主要(yao)是(shi)因為我們在(zai)(zai)輸入(ru)輸出(chu)時(shi)是(shi)按照規范模式接收到回車或換(huan)行才發送,而更多情(qing)況(kuang)下我們是(shi)不必鍵(jian)入(ru)回車或換(huan)行的。此(ci)時(shi)應轉換(huan)到行方式輸入(ru),不經處理直接發送,設置(zhi)如下:

Opt.c_lflag &= ~ (ICANON | ECHO | ECHOE | ISIG);

還存在這樣的情況:發送字(zi)(zi)符0X0d的時(shi)候,往往接收(shou)端得(de)到的字(zi)(zi)符是0X0a,原因是因為(wei)在串口設置中c_iflag和(he)c_oflag中存在從NL-CR和(he)CR-NL的映射,即串口能(neng)把回車和(he)換行(xing)當成同一個字(zi)(zi)符,可以進行(xing)如下設置屏蔽之(zhi):

Opt.c_iflag &= ~ (INLCR | ICRNL | IGNCR);

Opt.c_oflag &= ~(ONLCR | OCRNL);

注(zhu)意:控制符VTIME和(he)VMIN之間有復雜的關系(xi)。VTIME定義(yi)要(yao)求等(deng)待的時間(百(bai)毫米,通(tong)常是unsigned char變量),而VMIN定義(yi)了(le)要(yao)求等(deng)待的最(zui)小字節(jie)數(shu)(相(xiang)比之下,read函數(shu)的第三個參數(shu)指定了(le)要(yao)求讀的最(zui)大字節(jie)數(shu))。

如果VTIME=0,VMIN=要求等待(dai)讀取(qu)的最小字節數,read必須在讀取(qu)了VMIN個字節的數據或者收(shou)到一個信號才會返回。

 如果VTIME=時間(jian)量,VMIN=0,不管能否讀取(qu)到數據,read也要(yao)等待VTIME的時間(jian)量。

如果VTIME=時間量,VMIN=要求等(deng)待(dai)讀(du)取(qu)的(de)最小字節數(shu),那么將從(cong)read讀(du)取(qu)第一個(ge)字節的(de)數(shu)據時開始計時,并(bing)會在讀(du)取(qu)到(dao)VMIN個(ge)字節或者VTIME時間后返回。

如果VTIME=0,VMIN=0,不管能否讀取到數據,read都(dou)會(hui)立即返(fan)回

讀寫串口

發送數(shu)(shu)據方(fang)式如下(xia),write函數(shu)(shu)將返回寫的位數(shu)(shu)或者當錯誤時為-1。

char buffer[1024];

int length;

int nByte;

nByte = write(fd, buffer, length);

讀取(qu)數據方(fang)式如(ru)下(xia),原始(shi)數據模式下(xia)每個(ge)read函數將返回(hui)實際串(chuan)口(kou)收(shou)到(dao)的字符(fu)數,如(ru)果串(chuan)口(kou)中沒有(you)字符(fu)可(ke)用,回(hui)叫將會阻(zu)塞直到(dao)以下(xia)幾種情況:有(you)字符(fu)進入;一個(ge)間隔計時器失效;錯誤發(fa)送。

在(zai)(zai)打開串口(kou)成(cheng)功后,使用fcntl(fd, F_SETFL, FNDELAY)語句,可以使read函數(shu)立(li)即(ji)返回而不阻塞。FNDELAY選項(xiang)使read函數(shu)在(zai)(zai)串口(kou)無(wu)字(zi)符時(shi)立(li)即(ji)返回且為0。

char buffer[1024];

int length;

int readByte;

readByte = read(fd, buffer, len);

注 意:設置(zhi)為(wei)原始模式傳輸(shu)數(shu)(shu)據(ju)的話(hua),read函(han)數(shu)(shu)返回的字符(fu)數(shu)(shu)是實(shi)際串口收到的字符(fu)數(shu)(shu)。Linux下直接用(yong)(yong)read讀(du)串口可(ke)能(neng)會造成堵塞,或(huo)者(zhe)(zhe)數(shu)(shu)據(ju)讀(du)出錯 誤,此時可(ke)使(shi)用(yong)(yong)tcntl或(huo)者(zhe)(zhe)select等函(han)數(shu)(shu)實(shi)現(xian)異步(bu)讀(du)取。用(yong)(yong)select先(xian)查詢(xun)com口,再(zai)用(yong)(yong)read去讀(du)就可(ke)以避(bi)免上述錯誤。

6,關閉(bi)串口(kou)

串口(kou)作為文件來處理,所以一般的關(guan)閉(bi)文件函數即(ji)可:

close(fd);

上一篇:socket進程間通信方式大總結,還有典型實例哦

下一篇:linux進程間通信-FIFO,讓你全方位理解

熱點文章推(tui)薦
華清學員就業榜單
高薪學(xue)員經驗(yan)分享
熱點新(xin)聞(wen)推(tui)薦
前(qian)臺(tai)專線:010-82525158 企業(ye)培訓洽談(tan)專線:010-82525379 院校(xiao)合(he)作洽談專線:010-82525379 Copyright © 2004-2022 北京華清遠見科技集團有限公司 版權所有 ,,京公海網安備11010802025203號

回到頂部