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...