linux设置非标准波特率200000bit/s

参考 http://blog.chinaunix.net/uid-9543173-id-1988980.html

参考 http://blog.csdn.net/w_ww_w/article/details/25792815

combuad_recv.cpp

#include <stdio.h>      /*标准输入输出定义*/
#include <stdlib.h>     /*标准函数库定义*/
#include <unistd.h>     /*Unix 标准函数定义*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>      /*文件控制定义*/
#include <termios.h>    /*PPSIX 终端控制定义*/
#include <errno.h>      /*错误号定义*/
#include <string.h>


#include <sys/ioctl.h>
#include <linux/serial.h>


#define FALSE   -1
#define TRUE   0


/*
设置串口
最基本的设置串口包括波特率设置,效验位和停止位设置。
串口的设置主要是设置 struct termios 结构体的各成员值。


struct termio
{
unsigned short  c_iflag; // 输入模式标志
unsigned short  c_oflag; // 输出模式标志
unsigned short  c_cflag; // 控制模式标志
unsigned short  c_lflag; // local mode flags
unsigned char  c_line; // line discipline
unsigned char  c_cc[NCC];   // control characters
};
*/


/**
*@brief  设置串口通信速率
*@param  fd     类型 int  打开串口的文件句柄
*@param  speed  类型 int  串口速度
*@return  void
*/
static int speed_arr[] = { B200, B300, B600, B1200, B1800, B2400, B4800, B9600, B19200, B38400, B57600, B115200, /*B200000,*/ B230400 };
static int name_arr[] =  {  200,  300,  600,  1200,  1800,  2400,  4800,  9600,  19200,  38400,  57600,  115200, /*200000,*/ 230400 };
static int set_speed(int fd, int speed)
{
int   i;
int   status;
struct termios   Opt;
int baud_rate;


tcgetattr(fd, &Opt);


for (i = 0; i < sizeof(speed_arr)/sizeof(int); i++)
{
if(speed == name_arr[i])
{
baud_rate = speed_arr[i];


if(baud_rate <= B38400)
{
cfsetispeed(&Opt, baud_rate);
cfsetospeed(&Opt, baud_rate);
}
else
{
Opt.c_cflag |= CBAUDEX;
baud_rate -= 4096; /*baud_rate取值为1 ~ 5,分别对应B57600/B115200/B3000000/B6000000/B12000000*/
cfsetispeed(&Opt, baud_rate);
cfsetospeed(&Opt, baud_rate);
}


tcflush(fd, TCIOFLUSH);
cfsetispeed(&Opt, speed_arr[i]);
cfsetospeed(&Opt, speed_arr[i]);
status = tcsetattr(fd, TCSANOW, &Opt);
if  (status != 0)
{
perror("tcsetattr fd");
return FALSE;
}
tcflush(fd,TCIOFLUSH);


return TRUE;
}
}


fprintf(stderr, "Unsupported speed\n");


return FALSE;
}


// uart_set_info
// 设置为特诉波特率,比如200000
int set_speci_baud(int fd, int baud)
{
struct serial_struct ss, ss_set;
struct termios Opt;
tcgetattr(fd, &Opt);


cfsetispeed(&Opt, B38400);
cfsetospeed(&Opt, B38400);


tcflush(fd, TCIFLUSH);/*handle unrecevie char*/
tcsetattr(fd, TCSANOW, &Opt);


if((ioctl(fd, TIOCGSERIAL, &ss)) < 0)
{
printf("BAUD: error to get the serial_struct info:%s\n", strerror(errno));
return -1;
}


ss.flags = ASYNC_SPD_CUST;
ss.custom_divisor = ss.baud_base / baud;
if((ioctl(fd, TIOCSSERIAL, &ss)) < 0)
{
printf("BAUD: error to set serial_struct:%s\n", strerror(errno));
return -2;
}


ioctl(fd, TIOCGSERIAL, &ss_set);
printf("BAUD: success set baud to %d,custom_divisor=%d,baud_base=%d\n",
      baud, ss_set.custom_divisor, ss_set.baud_base);


return 0;
}


/**
*@brief   设置串口数据位,停止位和效验位
*@param  fd     类型  int  打开的串口文件句柄
*@param  databits 类型  int 数据位   取值 为 7 或者8
*@param  stopbits 类型  int 停止位   取值为 1 或者2
*@param  parity  类型  int  效验类型 取值为N,E,O,,S
*/
static int set_parity(int fd, int databits, int stopbits, int parity)
{
struct termios options;
if(tcgetattr( fd,&options) != 0)
{
perror("SetupSerial 1");
return(FALSE);
}


options.c_cflag &= ~CSIZE;
switch (databits) /*设置数据位数*/
{
case 7:
options.c_cflag |= CS7;
break;
case 8:
options.c_cflag |= CS8;
break;
default:
fprintf(stderr,"Unsupported data size\n");
return (FALSE);
}


switch (parity)
{
case 'n':
case 'N':
options.c_cflag &= ~PARENB;   /* Clear parity enable */
options.c_iflag &= ~INPCK;     /* Enable parity checking */
break;
case 'o':
case 'O':
options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/
options.c_iflag |= INPCK;             /* Disnable parity checking */
break;
case 'e':
case 'E':
options.c_cflag |= PARENB;     /* Enable parity */
options.c_cflag &= ~PARODD;   /* 转换为偶效验*/
options.c_iflag |= INPCK;       /* Disnable parity checking */
break;
case 'S':
case 's':  /*as no parity*/
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
break;
default:
fprintf(stderr,"Unsupported parity\n");
return (FALSE);
}


/* 设置停止位*/
switch (stopbits)
{
case 1:
options.c_cflag &= ~CSTOPB;
break;
case 2:
options.c_cflag |= CSTOPB;
break;
default:
fprintf(stderr,"Unsupported stop bits\n");
return (FALSE);
}


// important
options.c_cflag |= CLOCAL | CREAD;
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
options.c_oflag &= ~OPOST;
options.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);


/* Set input parity option */
if (parity != 'n')
options.c_iflag |= INPCK;
tcflush(fd, TCIFLUSH);
options.c_cc[VTIME] = 10; /* 设置超时*/
options.c_cc[VMIN] = 0; /* Update the options and do it NOW */


if (tcsetattr(fd, TCSANOW, &options) != 0)
{
perror("SetupSerial 3");
return (FALSE);
}


return (TRUE);
}


static int open_dev(const char *dev)
{
int fd = open(dev, O_RDWR);         //| O_NOCTTY | O_NDELAY
if (-1 == fd)
{
perror("can't open serial port");
return -1;
}
else
{
return fd;
}
}


ssize_t Read1(int fd, char *ptr)
{
static int read_cnt = 0;
static char *read_ptr = NULL;
static char read_buf[1024];

if (read_cnt <= 0) 
{
again:
if (-1 == (read_cnt = read(fd, read_buf,
sizeof(read_buf)))) 
{
if (EINTR == errno)
{
fprintf(stdout, "[lgw] we received a int signal. \n");
goto again;
}

return -1;
}
else if (0 == read_cnt)
{
return 0;
}

read_ptr = read_buf;
}

--read_cnt;
*ptr = *read_ptr++;

return 1;
}


int main(int argc, char *argv[])
{
int fd;
char *dev;

int cnt = -1, i = 0;
unsigned char recv_buff[512] = { 0 };
char c;



if(2 != argc)
{
printf("Usage: %s <rs232_dev>\n", argv[0]);
return -1;
}


dev = (char *)argv[1];
if((fd = open_dev(dev)) < 0)
{
printf("can't open port %s \n", dev);
return -1;
}


if((fd = open_dev(dev)) < 0)
{
printf("can't open port %s \n", dev);
return -1;
}
else
{
if(set_speci_baud(fd, 200000) < 0)
{
printf("Set Speed Error set_speci_baud\n");
return -1;
}

// if(set_speed(fd, 115200) < 0)
// {
// printf("Set Speed Error set_speed\n");
// return -1;
// }

if(set_parity(fd, 8, 1, 'N') < 0)
{
printf("Set Parity Error\n");
return -1;
}
}


for(i = 0; i < 50; i++)
{
if(1 == Read1(fd, &c))
{
fprintf(stderr, "c[%c] = 0x%02x \n", c, (unsigned char)c);
}
}

close(fd);

return 0;

}



combuad_send.cpp
#include <stdio.h>      /*标准输入输出定义*/
#include <stdlib.h>     /*标准函数库定义*/
#include <unistd.h>     /*Unix 标准函数定义*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>      /*文件控制定义*/
#include <termios.h>    /*PPSIX 终端控制定义*/
#include <errno.h>      /*错误号定义*/
#include <string.h>


#include <sys/ioctl.h>
#include <linux/serial.h>


#define FALSE   -1
#define TRUE   0


/*
设置串口
最基本的设置串口包括波特率设置,效验位和停止位设置。
串口的设置主要是设置 struct termios 结构体的各成员值。


struct termio
{
unsigned short  c_iflag; // 输入模式标志
unsigned short  c_oflag; // 输出模式标志
unsigned short  c_cflag; // 控制模式标志
unsigned short  c_lflag; // local mode flags
unsigned char  c_line; // line discipline
unsigned char  c_cc[NCC];   // control characters
};
*/


/**
*@brief  设置串口通信速率
*@param  fd     类型 int  打开串口的文件句柄
*@param  speed  类型 int  串口速度
*@return  void
*/
static int speed_arr[] = { B200, B300, B600, B1200, B1800, B2400, B4800, B9600, B19200, B38400, B57600, B115200, /*B200000,*/ B230400 };
static int name_arr[] =  {  200,  300,  600,  1200,  1800,  2400,  4800,  9600,  19200,  38400,  57600,  115200, /*200000,*/ 230400 };
static int set_speed(int fd, int speed)
{
int   i;
int   status;
struct termios   Opt;
int baud_rate;


tcgetattr(fd, &Opt);


for (i = 0; i < sizeof(speed_arr)/sizeof(int); i++)
{
if(speed == name_arr[i])
{
baud_rate = speed_arr[i];


if(baud_rate <= B38400)
{
cfsetispeed(&Opt, baud_rate);
cfsetospeed(&Opt, baud_rate);
}
else
{
Opt.c_cflag |= CBAUDEX;
baud_rate -= 4096;/*baud_rate取值为1 ~ 5,分别对应B57600/B115200/B3000000/B6000000/B12000000*/
cfsetispeed(&Opt, baud_rate);
cfsetospeed(&Opt, baud_rate);
}


tcflush(fd, TCIOFLUSH);
cfsetispeed(&Opt, speed_arr[i]);
cfsetospeed(&Opt, speed_arr[i]);
status = tcsetattr(fd, TCSANOW, &Opt);
if  (status != 0)
{
perror("tcsetattr fd");
return FALSE;
}
tcflush(fd,TCIOFLUSH);


return TRUE;
}
}


fprintf(stderr, "Unsupported speed\n");


return FALSE;
}


// uart_set_info
// 设置为特诉波特率,比如200000
int set_speci_baud(int fd, int baud)
{
struct serial_struct ss, ss_set;
struct termios Opt;
tcgetattr(fd, &Opt);


cfsetispeed(&Opt, B38400);
cfsetospeed(&Opt, B38400);


tcflush(fd, TCIFLUSH);/*handle unrecevie char*/
tcsetattr(fd, TCSANOW, &Opt);


if((ioctl(fd, TIOCGSERIAL, &ss)) < 0)
{
printf("BAUD: error to get the serial_struct info:%s\n", strerror(errno));
return -1;
}


ss.flags = ASYNC_SPD_CUST;
ss.custom_divisor = ss.baud_base / baud;
if((ioctl(fd, TIOCSSERIAL, &ss)) < 0)
{
printf("BAUD: error to set serial_struct:%s\n", strerror(errno));
return -2;
}


ioctl(fd, TIOCGSERIAL, &ss_set);
printf("BAUD: success set baud to %d,custom_divisor=%d,baud_base=%d\n",
      baud, ss_set.custom_divisor, ss_set.baud_base);


return 0;
}


/**
*@brief   设置串口数据位,停止位和效验位
*@param  fd     类型  int  打开的串口文件句柄
*@param  databits 类型  int 数据位   取值 为 7 或者8
*@param  stopbits 类型  int 停止位   取值为 1 或者2
*@param  parity  类型  int  效验类型 取值为N,E,O,,S
*/
static int set_parity(int fd, int databits, int stopbits, int parity)
{
struct termios options;
if(tcgetattr( fd,&options) != 0)
{
perror("SetupSerial 1");
return(FALSE);
}


options.c_cflag &= ~CSIZE;
switch (databits) /*设置数据位数*/
{
case 7:
options.c_cflag |= CS7;
break;
case 8:
options.c_cflag |= CS8;
break;
default:
fprintf(stderr,"Unsupported data size\n");
return (FALSE);
}


switch (parity)
{
case 'n':
case 'N':
options.c_cflag &= ~PARENB;   /* Clear parity enable */
options.c_iflag &= ~INPCK;     /* Enable parity checking */
break;
case 'o':
case 'O':
options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/
options.c_iflag |= INPCK;             /* Disnable parity checking */
break;
case 'e':
case 'E':
options.c_cflag |= PARENB;     /* Enable parity */
options.c_cflag &= ~PARODD;   /* 转换为偶效验*/
options.c_iflag |= INPCK;       /* Disnable parity checking */
break;
case 'S':
case 's':  /*as no parity*/
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
break;
default:
fprintf(stderr,"Unsupported parity\n");
return (FALSE);
}


/* 设置停止位*/
switch (stopbits)
{
case 1:
options.c_cflag &= ~CSTOPB;
break;
case 2:
options.c_cflag |= CSTOPB;
break;
default:
fprintf(stderr,"Unsupported stop bits\n");
return (FALSE);
}


// important
options.c_cflag |= CLOCAL | CREAD;
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
options.c_oflag &= ~OPOST;
options.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);


/* Set input parity option */
if (parity != 'n')
options.c_iflag |= INPCK;
tcflush(fd, TCIFLUSH);
options.c_cc[VTIME] = 10; /* 设置超时*/
options.c_cc[VMIN] = 0; /* Update the options and do it NOW */


if (tcsetattr(fd, TCSANOW, &options) != 0)
{
perror("SetupSerial 3");
return (FALSE);
}


return (TRUE);
}


static int open_dev(const char *dev)
{
int fd = open(dev, O_RDWR);         //| O_NOCTTY | O_NDELAY
if (-1 == fd)
{
perror("can't open serial port");
return -1;
}
else
{
return fd;
}
}


int main(int argc, char *argv[])
{
int fd;
char *dev;


char send_buff[512] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
int cnt = -1;

if(2 != argc)
{
printf("Usage: %s <rs232_dev>\n", argv[0]);
return -1;
}


dev = (char *)argv[1];
if((fd = open_dev(dev)) < 0)
{
printf("can't open port %s \n", dev);
return -1;
}


if((fd = open_dev(dev)) < 0)
{
printf("can't open port %s \n", dev);
return -1;
}
else
{
if(set_speci_baud(fd, 200000) < 0)
{
printf("Set Speed Error set_speci_baud\n");
return -1;
}

// if(set_speed(fd, 115200) < 0)
// {
// printf("Set Speed Error set_speed\n");
// return -1;
// }

if(set_parity(fd, 8, 1, 'N') < 0)
{
printf("Set Parity Error\n");
return -1;
}
}

cnt = write(fd, send_buff, 256);
if(cnt < 0)
{
printf("Wirte sbuf error.\n");
}
else
{
printf("Wirte:%s \tcnt:%d\n", send_buff, cnt);
}

close(fd);

return 0;
}





评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值