午夜网站国产欧美_加勒比视频亚洲无码_91亚洲人人在字幕国产_18禁止美女爆乳免费网站_被消防员c哭高h野外糙汉动漫_午夜精品视频在线无码_gogowww人体大胆裸体午液_2021自拍偷区亚洲综合第一页_国产欧美一区二区精品性色超碰_99國產精品無碼

Hi,您好,歡迎來到西安盛圖軟件科技有限公司!

Linux下的串口通信

發(fā)布時間:2022-01-07 11:19:10

點擊上方藍字關(guān)注我們

Linux下的串口通信

串行接口簡稱串口,也稱串行通信接口或串行通訊接口(通常指COM口,在設(shè)備管理器中可以查看到),是采用串行通信方式的擴展接口。串行接口(SerialInterface)是指數(shù)據(jù)一位一位地順序傳送。其特點是通信線路簡單,只要一對傳輸線就可以實現(xiàn)雙向通信(可以直接利用電話線作為傳輸線),從而大大降低了成本,特別適用于遠距離通信,但傳送速度較慢,可以用于交換機、電腦主板接口等。


在Linux系統(tǒng)中,一切接文件,因此串口設(shè)備是通過串口終端設(shè)備文件來訪問的,也就是通過訪問/dev/ttyS0、/dev/ttyS1、/dev/ttyS2、/dev/ttyS3這些設(shè)備文件實現(xiàn)對串口的訪問。對串口進行讀寫要經(jīng)過下面幾個步驟。


1
打開串口

與打開文件類似,打開串口同樣使用open函數(shù)。注意對于串口的打開操作,必須使用O_NOCTTY參數(shù)。該參數(shù)表示:如果打開的是一個終端設(shè)備,程序不會成為對應這個端口的控制終端。如果沒有使用該標志,任何一個輸入(例如,鍵盤中止信號等)都將影響進程。具體代碼如下:

#include

#include

#include

int main(void)

{

int fd;

//使用open函數(shù)打開串口,獲得串口設(shè)備文件的文件描述符

if((fd=open("/dev/ttyS0",O_RDWR|O_NOCTTY))==-1)

{

perror("Cannot open theserial port");

return 1;

}

}

……


2
 設(shè)置串口通信參數(shù)

串口通信參數(shù)指的是波特率、數(shù)據(jù)位、奇偶校驗位和停止位。對串口實現(xiàn)控制的時候同樣要用到termio結(jié)構(gòu)體。

1.波特率設(shè)置

獲得端口波特率信息是通過cfgetispeed函數(shù)和cfgetospeed函數(shù)來實現(xiàn)的。cfgetispeed函數(shù)用于獲得結(jié)構(gòu)體termios_p中的輸入波特率信息,而cfgetospeed函數(shù)用于獲得結(jié)構(gòu)體termios_p中的輸出波特率信息。這兩個函數(shù)的具體信息如表1所示。

頭文件

#include

#include

函數(shù)形式

speed_t cfgetispeed(const struct termios *termios_p);

speed_t cfgetospeed(const struct termios *termios_p);

返回值

成功

失敗

是否設(shè)置errno

返回termios_p結(jié)構(gòu)中的輸入/輸出端口的波特率

?1

表1 cfgetispeed函數(shù)和cfgetospeed函數(shù)


cfsetispeed函數(shù)和cfsetospeed函數(shù)用于設(shè)置端口的輸入/輸出波特率。一般情況下,輸入和輸出波特率是相等的。cfsetispeed函數(shù)和cfsetospeed函數(shù)的函數(shù)聲明信息如表2所示。


頭文件

函數(shù)形式

int cfsetispeed(struct termios *termios_p, speed_t speed);

int cfsetospeed(struct termios *termios_p, speed_t speed);

返回值

成功

失敗

是否設(shè)置errno

返回termios_p結(jié)構(gòu)中的輸入/輸出端口的波特率

?1

表2  cfsetispeed函數(shù)和cfsetospeed函數(shù)

cfsetispeed函數(shù)和cfsetospeed函數(shù)會修改結(jié)構(gòu)體termios_p中的波特率信息,其中參數(shù)speed可以使用表3中所列出的宏。



宏  定  義

波特率(單位:bit/s)

宏  定  義

波特率(單位:bit/s)

B0

0

B1800

1800

B50

50

B2400

2400

B75

75

B4800

4800

B110

110

B9600

9600

B134

134

B19200

19200

B150

150

B38400

38400

B200

200

B57600

57600

B300

300

B115200

115200

B600

600

B230400

230400

B1200

1200



表3  speed參數(shù)常用波特率信息


使用cfsetispeed函數(shù)和cfsetospeed函數(shù)進行串口波特率設(shè)置具體代碼如下所示:

#include    //頭文件定義

#include

#include < termios.h >

……

struct termios opt;          /*定義指向termios結(jié)構(gòu)類型的指針opt*/

……

//獲得串口指向termios結(jié)構(gòu)的指針

tcgetattr(fd, &Opt);

cfsetispeed(&opt,B9600); /*指定輸入波特率,9600bps*/

cfsetospeed(&opt,B9600);/*指定輸出波特率,9600bps*/

//將修改后的termios數(shù)據(jù)設(shè)置到串口中

tcsetattr(fd,TCANOW,&Opt);

……


2.數(shù)據(jù)位

數(shù)據(jù)位指的是每字節(jié)中實際數(shù)據(jù)所占的比特數(shù)。要修改數(shù)據(jù)位可以通過修改termios結(jié)構(gòu)體中c_cflag成員來實現(xiàn)。CS5、CS6、CS7和CS8分別表示數(shù)據(jù)位為5、6、7和8。值得注意的是,在設(shè)置數(shù)據(jù)位時,必須先使用CSIZE做位屏蔽。具體設(shè)置代碼如下:

#include    //頭文件定義

#include

#include< termios.h >

……

structtermios opt;          /*定義指向termios結(jié)構(gòu)類型的指針opt*/

.......

//獲得串口指向termios結(jié)構(gòu)的指針

tcgetattr(fd,&Opt);

//屏蔽其他標志

Opt.c_cflag&=~CSIZE;

//將數(shù)據(jù)位修改為8bit

Opt.c_cflag|=CS8;

//將修改后的termios數(shù)據(jù)設(shè)置到串口中

tcsetattr(fd,TCANOW,&Opt);

……


3.奇偶校驗位

奇偶校驗可以選擇偶校驗、奇校驗、空格等方式,也可以不使用校驗。如果要設(shè)置為偶校驗的話,首先要將termios結(jié)構(gòu)體中c_cflag設(shè)置PARENB標志,并清除PARODD標志。如果要設(shè)置奇校驗,要同時設(shè)置termios結(jié)構(gòu)體中c_cflag設(shè)置PARENB標志和PARODD標志。如果不想使用任何校驗的話,清除termios結(jié)構(gòu)體中c_cflag的PARENB位。表4所示為設(shè)置奇偶校驗的具體方法。


設(shè)    置

具 體 代 碼

無校驗

opt.c_cflag &= ~PARENB;

奇校驗

opt.c_cflag |= (PARODD | PARENB);

偶校驗

opt.c_cflag &= ~ PARENB;

opt.c_cflag &= ~PARODD;

空格

opt.c_cflag &= ~PARENB;

opt.c_cflag &= ~CSTOPB;

表4 設(shè)置奇偶校驗位

下面給出將串口通信的奇偶校驗設(shè)置為偶校驗的例子,具體代碼如下:

#include   //頭文件定義

#include

#include < termios.h >

……

struct termios opt;          /*定義指向termios結(jié)構(gòu)類型的指針opt*/

……

//獲得串口指向termios結(jié)構(gòu)的指針

tcgetattr(fd, &Opt);

opt.c_cflag &= ~ PARENB;

opt.c_cflag &= ~PARODD;

//將修改后的termios數(shù)據(jù)設(shè)置到串口中

tcsetattr(fd,TCANOW,&Opt);

……


4.數(shù)據(jù)流控制

數(shù)據(jù)流控制指是使用何種方法來標志數(shù)據(jù)傳輸?shù)拈_始和結(jié)束??梢赃x擇不使用數(shù)據(jù)流控制、使用硬件進行流控制和使用軟件進行流控制。數(shù)據(jù)流控制設(shè)置如表5所示。


設(shè)    置

具 體 代 碼

不使用數(shù)據(jù)流控制

opt.c_cflag &= ~CRTSCTS

硬件

opt.c_cflag   |=  CRTSCTS

軟件

opt.c_cflag   | = IXON|IXOFF|IXANY

表5 數(shù)據(jù)流控制設(shè)置


由于使用硬件流控制需要相應連接的電纜,常用的流控制方法還是使用軟件進行流控制。下面給出了設(shè)置不使用數(shù)據(jù)流控制的相關(guān)代碼:

#include   //頭文件定義

#include

#include < termios.h >

……

struct termios opt;          /*定義指向termios結(jié)構(gòu)類型的指針opt*/

……

//獲得串口指向termios結(jié)構(gòu)的指針

tcgetattr(fd, &opt);

opt.c_cflag &= ~CRTSCTS…

//將修改后的termios數(shù)據(jù)設(shè)置到串口中

tcsetattr(fd,TCANOW,&Opt);

……


3
讀寫串口

讀寫串口是通過使用read函數(shù)和write函數(shù)實現(xiàn)的。在Linux系統(tǒng)中,對設(shè)備的讀寫類似于對文件的讀寫。下面給出對串口的寫操作的代碼:

……

int len;

//待發(fā)送數(shù)據(jù)

char sbuf[]={Hello,thisis a Serial_Port test!/n};

int send_len=sizeof(sbuf);

//發(fā)送緩沖區(qū)字節(jié)數(shù)定義

len= write(fd,sbuf,send_len);//

if(n == -1)

printf("Wirte sbuferror./n");

……


4
關(guān)閉串口

在完成對設(shè)備文件讀寫操作后,需要調(diào)用close函數(shù)關(guān)閉該文件描述符。

以上就是關(guān)于Linux下串口文件的相關(guān)知識,你學會了嗎?

西安盛圖科技
高端IT培訓第一品牌


上一篇:程序員編程入門須知
下一篇:4類程序員直呼好用的嵌入式開發(fā)輔助工具

歡迎登錄盛圖科技

歡迎注冊盛圖科技

已有賬號,立即登錄