新聞中心
在Linux系統(tǒng)的編程中,經(jīng)常需要使用串口來進(jìn)行通信,不過這種串口通信是高度依賴設(shè)備的,所以通常在編寫程序時(shí)需要使用一些控制串口的函數(shù),其中 tcsetattr 函數(shù)就是常用的一種。

tcsetattr 函數(shù)可以設(shè)置串口的一些參數(shù),包括波特率、數(shù)據(jù)位、停止位、校驗(yàn)位等等。在本文中,我們將會(huì)深入了解 tcsetattr 函數(shù)的設(shè)置與應(yīng)用。
1. tcsetattr 函數(shù)的基本原理
tcsetattr 函數(shù)的作用是設(shè)置串口的一些參數(shù),主要包括以下幾個(gè)方面:
① 設(shè)置波特率
波特率表示每秒鐘傳輸?shù)奈粩?shù),也就是串口通信的速度。設(shè)置波特率可以使用以下代碼:
“`c
struct termios options;
tcgetattr(fd,&options); // 獲取串口的屬性
cfsetspeed(&options,B115200); // 設(shè)置波特率為115200
tcsetattr(fd,TCSANOW,&options); // 生效
“`
其中,cfsetspeed 函數(shù)是設(shè)置波特率的函數(shù),之一個(gè)參數(shù)為 termios 結(jié)構(gòu)體的指針,第二個(gè)參數(shù)為設(shè)置的波特率值。
② 設(shè)置數(shù)據(jù)位
數(shù)據(jù)位表示每個(gè)字符所占用的位數(shù),常用的數(shù)據(jù)位有 5、6、7、8 位。設(shè)置數(shù)據(jù)位可以使用以下代碼:
“`c
options.c_cflag &= ~CSIZE; // 清除原有的數(shù)據(jù)位設(shè)置
options.c_cflag |= CS8; // 設(shè)置數(shù)據(jù)位為 8 位
“`
其中,CSIZE 是一個(gè)宏定義,表示數(shù)據(jù)位,CS8 表示數(shù)據(jù)位為 8 位。
③ 設(shè)置停止位
停止位用于表示兩個(gè)字符之間的間隔時(shí)間,常用的停止位有 1、1.5、2 位。設(shè)置停止位可以使用以下代碼:
“`c
options.c_cflag &= ~CSTOPB; // 設(shè)置停止位為 1 位
“`
其中,CSTOPB 是一個(gè)宏定義,表示停止位,將其賦為 0 就是設(shè)置停止位為 1 位。
④ 設(shè)置校驗(yàn)位
校驗(yàn)位用于檢測數(shù)據(jù)是否傳輸錯(cuò)誤,常用的校驗(yàn)位有 None、Even、Odd。設(shè)置校驗(yàn)位可以使用以下代碼:
“`c
options.c_cflag &= ~(PARENB | PARODD); // 設(shè)置校驗(yàn)位為 None
“`
其中,PARENB 和 PARODD 是宏定義,表示是否啟用奇偶校驗(yàn),將其都賦為 0 就是設(shè)置校驗(yàn)位為 None。
2. tcsetattr 函數(shù)的使用方法
tcsetattr 函數(shù)有以下幾個(gè)參數(shù):
① fd:文件描述符,即需要進(jìn)行串口通信的設(shè)備文件。
② optional_actions:控制讀寫行為的標(biāo)志,有以下幾種值:
– TCSANOW:設(shè)立后立即生效。
– TCSADRN:設(shè)立后數(shù)據(jù)傳輸完畢生效。
– TCSAFLUSH:設(shè)立后數(shù)據(jù)傳輸完畢生效,并清空輸入輸出緩沖區(qū)。
③ termios_p:包含串口配置信息的結(jié)構(gòu)體指針。該結(jié)構(gòu)體在使用之前需要進(jìn)行初始化。
我們需要?jiǎng)?chuàng)建一個(gè) termios 結(jié)構(gòu)體,該結(jié)構(gòu)體包含了串口的很多屬性。下面是一個(gè)示例代碼:
“`c
struct termios options;
if(tcgetattr(fd,&options) != 0){
perror(“tcgetattr error”);
return;
}
“`
其中 tcgetattr 函數(shù)用于獲取串口的屬性,具體用法在上文已經(jīng)提到。
接下來,我們需要設(shè)置該結(jié)構(gòu)體中的各項(xiàng)屬性。例如,設(shè)置波特率可以使用以下代碼:
“`c
// 設(shè)置波特率
cfsetspeed(&options,B115200);
“`
其中,cfsetspeed 函數(shù)用于設(shè)置波特率,之一個(gè)參數(shù)為 termios 結(jié)構(gòu)體的指針,第二個(gè)參數(shù)為設(shè)置的波特率值。
然后,我們需要設(shè)置數(shù)據(jù)位、停止位、校驗(yàn)位等屬性,具體用法在上文已經(jīng)提到,這里不再贅述。
我們需要使用 tcsetattr 函數(shù)將設(shè)置的屬性生效。以下是一個(gè)示例代碼:
“`c
// 將設(shè)置的屬性生效
if(tcsetattr(fd,TCSANOW,&options) != 0){
perror(“tcsetattr error”);
return;
}
“`
其中,之一個(gè)參數(shù)是文件描述符,第二個(gè)參數(shù)是控制讀寫行為的標(biāo)志(生效方式),第三個(gè)參數(shù)是包含串口配置信息的結(jié)構(gòu)體指針。
3. tcsetattr 函數(shù)的錯(cuò)誤處理
在使用 tcsetattr 函數(shù)時(shí),有異常情況時(shí)需要進(jìn)行錯(cuò)誤處理,以避免程序崩潰或其他嚴(yán)重后果。
調(diào)用 tcgetattr 函數(shù)獲取串口屬性時(shí),讀取失敗會(huì)返回 -1,并設(shè)置 errno 錯(cuò)誤碼。因此,我們需要進(jìn)行錯(cuò)誤處理,以下是一個(gè)示例代碼:
“`c
if(tcgetattr(fd,&options) != 0){
perror(“tcgetattr error”);
return;
}
“`
其中,perror 函數(shù)用于打印錯(cuò)誤信息,該函數(shù)會(huì)將錯(cuò)誤信息打印到屏幕上,并且在結(jié)尾處添加一個(gè)換行符。
調(diào)用 tcsetattr 函數(shù)設(shè)置串口屬性時(shí),如果設(shè)置失敗也會(huì)返回 -1,并設(shè)置 errno 錯(cuò)誤碼。因此,我們需要進(jìn)行錯(cuò)誤處理,以下是一個(gè)示例代碼:
“`c
if(tcsetattr(fd,TCSANOW,&options) != 0){
perror(“tcsetattr error”);
return;
}
“`
同樣是使用 perror 函數(shù)打印錯(cuò)誤信息。
4.
tcsetattr 函數(shù)是在 Linux 系統(tǒng)下進(jìn)行串口通信時(shí),必不可少的一個(gè)函數(shù)。它可以設(shè)置串口的一些屬性,包括波特率、數(shù)據(jù)位、停止位、校驗(yàn)位等等,從而實(shí)現(xiàn)不同的通信效果。
在使用 tcsetattr 函數(shù)時(shí),需要對(duì)函數(shù)的參數(shù)及其用法有所了解,同時(shí)需要進(jìn)行錯(cuò)誤處理,以保證程序的健壯性。
相關(guān)問題拓展閱讀:
- Linux下串口通信丟字節(jié)的問題是怎么樣解決
- linux 嵌入式系統(tǒng)中,更改串口波特率,無法生效
Linux下串口通信丟字節(jié)的問題是怎么樣解決
int con=atoi(portstr);
unsigned char Port_file_name;
int fd0,rc;
struct termios ts0;
switch (con)
{ //選項(xiàng)O_NOCTTY 表示不能把本串口當(dāng)成控制終端,否則用戶的鍵盤輸入信息將影響程序的執(zhí)行
//O_NDELAY表示瞎判打開串口的時(shí)候,程序并不關(guān)心另一端悔則的串口是否在使用中
case 1: fd0=open(“/dev/ttyM0”,O_RDWR | O_NOCTTY | O_NDELAY); break;
case 2: fd0=open(“/dev/ttyM1”,O_RDWR | O_NOCTTY | O_NDELAY); break;
case 3: fd0=open(“/dev/ttyM2”,O_RDWR | O_NOCTTY | O_NDELAY); break;
case 4: fd0=open(“/dev/ttyM3”,O_RDWR | O_NOCTTY | O_NDELAY); break;
case 5: fd0=open(“/dev/ttyM4”,O_RDWR | O_NOCTTY | O_NDELAY); break;
case 6: fd0=open(“/dev/ttyM5”,O_RDWR | O_NOCTTY | O_NDELAY); break;
case 7: fd0=open(“/dev/ttyM6”,O_RDWR | O_NOCTTY | O_NDELAY); break;
case 8: fd0=open(“/dev/ttyM7”,O_RDWR | O_NOCTTY | O_NDELAY); break;
default : fd0=open(“/dev/ttyM0”,O_RDWR | O_NOCTTY | O_NDELAY); break;
}
tcgetattr(fd0,&ts0);
bzero(&ts0,sizeof(struct termios));
switch (gytype)
{
case 1:{ts0.c_cflag |= B300 | CS7 | CLOCAL | CREAD | PARENB ;
ts0.c_cflag &= ~PARODD; // 轉(zhuǎn)換為偶效驗(yàn)
ts0.c_iflag |= INPCK; // Disnable parity checking
break; }
case 2:{ts0.c_cflag |= B1200 | CS8 | CLOCAL | CREAD | PARENB ;
ts0.c_cflag &= ~PARODD; //磨前改 轉(zhuǎn)換為偶效驗(yàn)
ts0.c_iflag |= INPCK; // Disnable parity checking
break;
}
case 3:{
ts0.c_cflag |= B9600 | CS8 | CLOCAL | CREAD ;
ts0.c_cflag &= ~PARENB; // Clear parity enable
ts0.c_iflag &= ~INPCK; // Enable parity checking
break;
}
case 4:{ts0.c_cflag |= B9600 | CS8 | CLOCAL | CREAD | PARENB ;
ts0.c_cflag &= ~PARODD; // 轉(zhuǎn)換為偶效驗(yàn)
ts0.c_iflag |= INPCK; // Disnable parity checking
break;
}
}
ts0.c_lflag &= ~ECHO;
ts0.c_lflag &= ~ECHONL;
ts0.c_iflag &= ~IXOFF;
ts0.c_iflag &= ~IXON;
ts0.c_cflag &= ~CSIZE;
switch (gytype)
{
case 1:{ts0.c_cflag |= CS7 ; break;}
case 2:{ts0.c_cflag |= CS8 ; break;}
case 3:{ts0.c_cflag |= CS8 ; break;}
case 4:{ts0.c_cflag |= CS8 ; break;}
}
ts0.c_lflag &= ~ICANON; //如果設(shè)置使能規(guī)范輸入,否則使用原始數(shù)據(jù)(本文使用)
ts0.c_oflag &= ~ONLCR; //如果設(shè)置將NL轉(zhuǎn)換成CR-NL后輸出
ts0.c_iflag &= ~INLCR; //如果設(shè)置將接收到的NL(換行)轉(zhuǎn)換成CR(回車)。
ts0.c_cc = 0; //最少可讀數(shù)據(jù)
ts0.c_cc = 0; //等待數(shù)據(jù)時(shí)間(10秒的倍數(shù))
ts0.c_cflag &= ~CSTOPB; //如果設(shè)置則使用兩個(gè)停止位 ,如果取消則使用一個(gè)停止位
ts0.c_iflag |= IGNBRK; //如果設(shè)置則忽略接收到的break信號(hào)
ts0.c_lflag &= ~IEXTEN; //如果設(shè)置則啟用實(shí)現(xiàn)自定義的輸入處理
ts0.c_lflag |= NOFLSH; //如果設(shè)置則禁止產(chǎn)生SIGINT,SIGQUIT和SIGSUSP信號(hào)時(shí)刷新輸入和輸出隊(duì)列
switch (gytype)
{
case 1:{rc = cfsetospeed(&ts0,B300);break; }
case 2:{rc = cfsetospeed(&ts0,B1200);break; }
case 3:{rc = cfsetospeed(&ts0,B9600);break; }
case 4:{rc = cfsetospeed(&ts0,B9600);break; }
}
rc = tcsetattr(fd0,TCSAFLUSH,&ts0);
linux 嵌入式系統(tǒng)中,更改串口波特率,無法生效
如果是自己寫的驅(qū)動(dòng),先檢查驅(qū)動(dòng)是唯睜唯否支持
波特率
的修改。
如果支持:
stty -F /dev/ttyS0 speedcs8 -parenb -cstopb -echo 修改 波特早爛率N 1
下位機(jī)采指培用相同的配置,并在linux終端輸入echo “hello” > /dev/ttyS0 看看是否能通信。
關(guān)于linux tcsetattr的介紹到此就結(jié)束了,不知道你從中找到你需要的信息了嗎 ?如果你還想了解更多這方面的信息,記得收藏關(guān)注本站。
香港服務(wù)器選創(chuàng)新互聯(lián),2H2G首月10元開通。
創(chuàng)新互聯(lián)(www.cdcxhl.com)互聯(lián)網(wǎng)服務(wù)提供商,擁有超過10年的服務(wù)器租用、服務(wù)器托管、云服務(wù)器、虛擬主機(jī)、網(wǎng)站系統(tǒng)開發(fā)經(jīng)驗(yàn)。專業(yè)提供云主機(jī)、虛擬主機(jī)、域名注冊(cè)、VPS主機(jī)、云服務(wù)器、香港云服務(wù)器、免備案服務(wù)器等。
分享題目:解析linuxtcsetattr中的設(shè)置與應(yīng)用(linuxtcsetattr)
網(wǎng)站路徑:http://m.fisionsoft.com.cn/article/djopejj.html


咨詢
建站咨詢
