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

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

2014-05-14 11:47 316 查看
参考 http://blog.chinaunix.net/uid-9543173-id-1988980.html

参考 /article/8410601.html

////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;

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