Linux 串列埠程式設計的一些問題解決

2021-05-17 11:20:25 字數 2591 閱讀 9408

linux下串列埠程式設計的文章網上是滿天飛,但大都是出自一篇文章,而且寫的都是些基本的操作,像控制rts/cts等串列埠引腳狀態,接收傳送二進位制資料等,都沒有很好的說明,我在使用中遇到了些問題,寫出來,希望能對大家有所幫助,少走彎路,呵呵!

我使用的作業系統是redhat9,gcc版本是3.2.2

其實在linux下對串列埠的設定主要是通過termios這個結構體實現的,但是這個結構體卻沒有提供控制rts或獲得cts等串列埠引腳狀態的介面,可以通過ioctl系統呼叫來獲得/控制。

獲得:

ioctl(fd, tiocmget, &controlbits);

if (controlbits & tiocm_cts)

printf(「有訊號/n」);

else

printf(「無訊號/n」);

設定:

ioctl(fd, tiocmget, &ctrlbits);

if (flag)

ctrlbits |= tiocm_rts;

else

ctrlbits &= ~tiocm_rts;

ioctl(fd, tiocmset, &ctrlbits);

其實tiocm_rts有效後是把串列埠的rts設定為有訊號,但串列埠的電平為低時是有訊號,為高時為無訊號,和用tiocmget獲得的狀態正好相反,也就是說tiocmget/tiocmset只是獲得/控制串列埠的相應引腳是否有訊號,並不反應當前串列埠的真實電平高低。

網上許多流行的linux串列埠程式設計的版本中都沒對c_iflag(termios成員變數)這個變數進行有效的設定,這樣傳送ascii碼時沒什麼問題,但傳送二進位制資料時遇到0x0d,0x11和0x13卻會被丟掉。不用說也知道,這幾個肯定是特殊字元,被用作特殊控制了。關掉icrnl和ixon選項即可解決。

c_iflag &= ~(icrnl | ixon);

0x0d 回車符cr

0x11 ^q vstart字元

0x13 ^s vstop字元

icrnl 將輸入的cr轉換為nl  

ixon 使起動/停止輸出控制流起作用

在《unix環境高階程式設計 第二版》第18章第11小節看到把終端i/o設定為原始模式(串列埠通訊就是終端i/o的原始模式)時輸入屬性設定為

term.c_iflag &= ~(brkint | icrnl | inpck | istrip | ixon);

遮蔽了許多屬性,怪不得有人說如果是使用串列埠通訊c_iflag和c_oflag都設定為0就行了!

以下是我的設定的一些重要的串列埠屬性

term.c_cflag |= clocal | cread;

term.c_lflag &= ~(icanon | echo | echoe | isig);

term.c_oflag &= ~opost;

term.c_iflag &= ~(brkint | icrnl | inpck | istrip | ixon);

static void request_send(void)

static void clear_send(void)

int main(int argc, char *argv)

;//使用open函式開啟串列埠,獲得串列埠裝置檔案的檔案描述符

if((fd=open("/dev/ttyama1",o_rdwr| o_noctty))==-1)

tcgetattr(fd, &opt);

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

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

opt.c_cflag&=~csize;

//將資料位修改為8bit

opt.c_cflag |=cs8;

opt.c_cflag |=cbaud;

// 無校驗

opt.c_cflag &= ~parenb;

opt.c_cflag   |= ixon|ixoff|ixany;   //  軟體資料流控制

//   opt.c_cflag   |=  crtscts;   // 硬體資料流控制

// opt.c_cflag &= ~crtscts;   // 不使用資料流控制

tcsetattr(fd, tcsanow , &opt);

int status;

ioctl(fd, tiocmget, &status);

printf("status = %04x/n", status);

//  status &= ~tiocm_rts;   // rts 引腳高電平

status |= tiocm_rts;    // rts 引腳低電平

printf("status = %04x/n", status);

ioctl(fd, tiocmset, &status);

ioctl(fd, tiocmget, &status);

printf("status = %04x/n", status);

while(1)

}close(fd);

return 0;

}

關於串列埠的一些問題

最近在做串列埠通訊部分的 遇到了兩個奇怪的問題 1.demo之前能接收虛擬串列埠的資料,突然不能接收,排除了很久,分別在兩個專案上跑,發現同樣的 乙個專案能接收另乙個不能接收,再看一下兩個專案區別,發現是專案屬性 c c 生成中的安全屬性問題,選擇啟用安全檢查即可接收到資料 2.對於接收的資料,新建...

Linux下的一些問題

執行yum命令報一下錯誤 error rpmdb bdb0113 thread process 9818 140220803434304 failed bdb1507 thread died in berkeley db library error db5 error 30973 from dben...

linux安裝後的一些問題解決

1 中文亂碼問題 安裝這個兩個中文包,成功顯示中文網頁 2 修改linux螢幕解析度 找到合適的解析度 3 開機故障 在修改 etc selinux config selinux disable後開機出現 unabletoloadselinuxpolicy.machine is in enforci...