您的位置:首页 > 运维架构 > Linux

The Linux Serial Programming

2014-04-07 15:16 501 查看
用C程式模擬minicom,下面已經改成可以在我電腦跑的程式

把BAUDRATE 改成B115200

把MODEMDEVICE 改成/dev/ttyUSB0

 

轉載自http://www.linux.org.tw/CLDP/OLD/Serial-Programming-HOWTO-3.html

========================================================================
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>

/* 鮑率設定被定義在 <asm/termbits.h>, 這在 <termios.h> 被引入 */
#define BAUDRATE B115200
/* 定義正確的序列埠 */
#define MODEMDEVICE "/dev/ttyUSB0"
#define _POSIX_SOURCE 1 /* POSIX 系統相容 */

#define FALSE 0
#define TRUE 1

volatile int STOP=FALSE;

main()
{
int fd,c, res;
struct termios oldtio,newtio;
char buf[255];
/*
開啟數據機裝置以讀取並寫入而不以控制 tty 的模式
因為我們不想程式在送出 CTRL-C 後就被殺掉.
*/
fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY );
if (fd <0) {perror(MODEMDEVICE); exit(-1); }

tcgetattr(fd,&oldtio); /* 儲存目前的序列埠設定 */
bzero(&newtio, sizeof(newtio)); /* 清除結構體以放入新的序列埠設定值 */

/*
BAUDRATE: 設定 bps 的速度. 你也可以用 cfsetispeed 及 cfsetospeed 來設定.
CRTSCTS : 輸出資料的硬體流量控制 (只能在具完整線路的纜線下工作
參考 Serial-HOWTO 第七節)
CS8     : 8n1 (8 位元, 不做同位元檢查,1 個終止位元)
CLOCAL  : 本地連線, 不具數據機控制功能
CREAD   : 致能接收字元
*/
newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;

/*
IGNPAR  : 忽略經同位元檢查後, 錯誤的位元組
ICRNL   : 比 CR 對應成 NL (否則當輸入訊號有 CR 時不會終止輸入)
在不然把裝置設定成 raw 模式(沒有其它的輸入處理)
*/
newtio.c_iflag = IGNPAR | ICRNL;

/*
Raw 模式輸出.
*/
newtio.c_oflag = 0;

/*
ICANON  : 致能標準輸入, 使所有回應機能停用, 並不送出信號以叫用程式
*/
newtio.c_lflag = ICANON;

/*
初始化所有的控制特性
預設值可以在 /usr/include/termios.h 找到, 在註解中也有,
但我們在這不需要看它們
*/
newtio.c_cc[VINTR]    = 0;     /* Ctrl-c */
newtio.c_cc[VQUIT]    = 0;     /* Ctrl-\ */
newtio.c_cc[VERASE]   = 0;     /* del */
newtio.c_cc[VKILL]    = 0;     /* @ */
newtio.c_cc[VEOF]     = 4;     /* Ctrl-d */
newtio.c_cc[VTIME]    = 0;     /* 不使用分割字元組的計時器 */
newtio.c_cc[VMIN]     = 1;     /* 在讀取到 1 個字元前先停止 */
newtio.c_cc[VSWTC]    = 0;     /* '\0' */
newtio.c_cc[VSTART]   = 0;     /* Ctrl-q */
newtio.c_cc[VSTOP]    = 0;     /* Ctrl-s */
newtio.c_cc[VSUSP]    = 0;     /* Ctrl-z */
newtio.c_cc[VEOL]     = 0;     /* '\0' */
newtio.c_cc[VREPRINT] = 0;     /* Ctrl-r */
newtio.c_cc[VDISCARD] = 0;     /* Ctrl-u */
newtio.c_cc[VWERASE]  = 0;     /* Ctrl-w */
newtio.c_cc[VLNEXT]   = 0;     /* Ctrl-v */
newtio.c_cc[VEOL2]    = 0;     /* '\0' */

/*
現在清除數據機線並啟動序列埠的設定
*/
tcflush(fd, TCIFLUSH);
tcsetattr(fd,TCSANOW,&newtio);

/*
終端機設定完成, 現在處理輸入訊號
在這個範例, 在一行的開始處輸入 'z' 會退出此程式.
*/
while (STOP==FALSE) {     /* 迴圈會在我們發出終止的訊號後跳出 */
/* 即使輸入超過 255 個字元, 讀取的程式段還是會一直等到行終結符出現才停止.
如果讀到的字元組低於正確存在的字元組, 則所剩的字元會在下一次讀取時取得.
res 用來存放真正讀到的字元組個數 */
res = read(fd,buf,255);
buf[res]=0;             /* 設定字串終止字元, 所以我們能用 printf */
printf(":%s:%d\n", buf, res);
if (buf[0]=='z') STOP=TRUE;
}
/* 回存舊的序列埠設定值 */
tcsetattr(fd,TCSANOW,&oldtio);
}


 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: