本篇介紹了如何在linux系統下向串列埠傳送資料。包括read的阻塞和非阻塞。以及select方法。
在linux系統下,開啟串列埠是通過使用標準的檔案開啟函式操作的。
#include
/* 以讀寫的方式開啟 */
int fd = open( "/dev/ttyusb0",o_rdwr);
所有對串列埠的操作都是通過結構體 struct termios 和 幾個函式實現的。
tcgetattr //獲取屬性
tcsetattr //
設定屬性
cfgetispeed //
得到輸入速度
cfsetispeed //
設定輸入速度
cfgetospeed //
得到輸出速度
cfsetospedd //
設定輸出速度
tcdrain //
等待所有輸出都被傳輸
tcflow //
掛起傳輸或接收
tcflush //
刷清未決輸入和輸出
tcsendbreak //
送break字元
tcgetpgrp //
得到前台程序組id
tcsetpgrp //
設定前台程序組id
tcgetattr( 0,&oldstdio); //獲取預設的配置選項 儲存到oldstdio結構體中
tcgetattr( fd,&oldstdio); //獲取當前配置選項 儲存到oldstdio結構體中
tcsetattr( fd,tcsanow,&oldstdio); //tcsanow 修改立即生效
cfgetispeed( &oldstdio); //得到波特率
cfsetispeed(&oldstdio, b115200 ) //設定波特率為115200
即可使用read或open來操作串列埠的傳送與接收。測試**:
#include #include#include
#include
#include
int serial_send( int fd, char *data );
intmain()
tcgetattr( fd, &oldstdio);
cfsetispeed(&oldstdio, b115200);
tcsetattr( fd, tcsanow, &oldstdio);
tcflush( fd, tciflush );
num = serial_send( fd,"
serial baund is default \r\n");
close(fd);
return0;
}int serial_send( int fd, char *data )
在沒有資料讀取的時候,執行read函式會發生阻塞,執行下面的程式,在串列埠接收端沒有資料時,返回0,並不會發生阻塞。
#include #include#include
#include
#include
#include
const
char *serial_dev = "
/dev/ttyusb0";
typedef
struct
serial;
typedef
struct
vehicle;
vehicle serial_tx = };
serial serial_d = };
ints_fd;
int wait_flag = 0
;int serial_send( int fd, char *data );
int set_opt(int fd,int nspeed,int nbits,char nevent,int
nstop);
void * pthread_serial( void *arg )
;
s_fd = open( serial_dev, o_rdwr|o_noctty );
if( -1==s_fd )
pthread_exit(null);
ret = set_opt(s_fd,115200,8,'
n',1
);
if(ret == -1
)
while(1
)
else
}pthread_exit(null);
}int
main()
while(1
)
return0;
}int serial_send( int fd, char *data )
int set_opt(int fd,int nspeed,int nbits,char nevent,int
nstop)
bzero(&newtio,sizeof
(newtio));
//使能串列埠接收
newtio.c_cflag |= clocal |cread;
newtio.c_cflag &= ~csize;
newtio.c_lflag &=~icanon;//
原始模式
|=icanon;
//標準模式
//設定串列埠資料位
switch
(nbits)
//設定奇偶校驗位
switch
(nevent)
//設定串列埠波特率
switch
(nspeed)
//設定停止位
if(nstop == 1
) newtio.c_cflag &= ~cstopb;
else
if(nstop == 2
) newtio.c_cflag |=cstopb;
newtio.c_cc[vtime] = 1
; newtio.c_cc[vmin] = 0
; tcflush(fd,tciflush);
if(tcsetattr(fd,tcsanow,&newtio)!=0
)
return0;
}
可以使用select函式來判斷有沒有接收到資料。
int read_datas_tty(int fd,char *rcv_buf,int sec,intusec)
else
if(retval)
else
}return1;
}
將上面的函式放到read前面呼叫即可。
下面是我用在小車上的**:
#include #include#include
#include
#include
#include
#include
"serial.h
"const
char *serial_dev = "
/dev/ttyusb0";
typedef
struct
vehicle;
typedef
struct
uart;
vehicle motor = };
uart serial_usb=;;
void * pthread_serial_rx( void *arg )
else
if( retval)
}else
if( num>100
)
}pthread_exit(null);
}void * pthread_serial( void *arg )
serial_usb.fd =fd;
serial_usb.sec = 0
; serial_usb.usec = 1
; serial_usb.veh = &motor;
pthread_create( &pthread_id, null, &pthread_serial_rx, ( void *)&serial_usb );
while( 0==pthread_kill(pthread_id,0
) )
usleep(
5000
); }
printf(
"receive thread is quited\r\n");
pthread_exit(null);
}int
main()
printf(
"%d\r\n
",sizeof
(vehicle));
//serial_send( serial_usb.fd, "this is ok\r\n" );
while( 0==pthread_kill(pthread_id,0
) )
printf(
"serial thread is quited\r\n");
return0;
}
sd
linux下串列埠的阻塞和非阻塞操作
有兩個可以進行控制串列埠阻塞性 同時控制read和write 乙個是在開啟串列埠的時候,open函式是否帶o ndelay 第二個是可以在開啟串列埠之後通過fcntl 函式進行控制。阻塞的定義 對於read,block指當串列埠輸入緩衝區沒有資料的時候,read函式將會阻塞在這裡,移植到串列埠輸入緩...
linux下串列埠的阻塞和非阻塞操作
有兩個可以進行控制串列埠阻塞性 同時控制read和write 乙個是在開啟串列埠的時候,open函式是否帶o ndelay 第二個是可以在開啟串列埠之後通過fcntl 函式進行控制。阻塞的定義 對於read,block指當串列埠輸入緩衝區沒有資料的時候,read函式將會阻塞在這裡,移植到串列埠輸入緩...
linux下串列埠的阻塞和非阻塞操作
有兩個可以進行控制串列埠阻塞性 同時控制read和write 乙個是在開啟串列埠的時候,open函式是否帶o ndelay 第二個是可以在開啟串列埠之後通過fcntl 函式進行控制。阻塞的定義 對於read,block指當串列埠輸入緩衝區沒有資料的時候,read函式將會阻塞在這裡,移植到串列埠輸入緩...