/*配置串口*/
int set_com_config(int fd,int baud_rate,int data_bits, char parity, int stop_bits)
{
struct termios new_cfg,old_cfg;
int speed;
/*DESCRIPTION
The termios functions describe a general terminal interface that is
provided to control asynchronous communications ports.
*/
/*保存测试现有串口参数设置,在这里如果串口号等出错,会有相关的出错信息*/
if (tcgetattr(fd, &old_cfg) != 0) //tcgetattr()终端专用的函数
{
perror("tcgetattr");
return -1;
}
/*tcgetattr可以初始化一个终端对应的termios结构,tcgetattr函数原型如下:
*#include<termios.h>
*int tcgetattr(int fd, struct termios *termios_p);
*这个函数调用把当前终端接口变量的值写入termios_p参数指向的结构
*如果这些值其后被修改了,可以通过调用函数tcsetattr来重新配置。
*/
new_cfg = old_cfg;//这一行和下一行选一个表达即可,因为下一行是初始化操作
cfmakeraw(&new_cfg);
/*cfmakeraw(&new_cfg);初始化 termios结构体,将他的一些成员初始化为默认的设置*/
/*cfmakeraw 设置终端属性如下:
* termios_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
* termios_p->c_oflag &= ~OPOST;
* termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
* termios_p->c_cflag &= ~(CSIZE|PARENB);
* termios_p->c_cflag |= CS8;
*/
new_cfg.c_cflag &= ~CSIZE;
/*&= ~CSIZE:先屏蔽其他标志,清零。-- 初始化。然后设置位数。*/
/*波特率选择*/
switch (baud_rate)
{
case 2400:
{
speed = B2400;
}
break;
case 4800:
{
speed = B4800;
}
break;
case 9600:
{
speed = B9600;
}
break;
case 19200:
{
speed = B19200;
}
break;
case 38400:
{
speed = B38400;
}
break;
default:
case 115200:
{
speed = B115200;
}
break;
}
cfsetispeed(&new_ cfg, speed);
cfsetospeed(&new_cfg, speed);
/*cfsetospeed() 设置 termios_p 指向的 termios 结构中存储的输出波特率为 speed*/
/*cfsetispeed() 设置 termios 结构中存储的输入波特率为 speed。
*如果输入波特率被设为0,实际输入波特率将等于输出波特率。
*/
/*函数模型:
*int cfsetispeed(struct termios *termptr, speed_t speed);
*int cfsetospeed(struct termios *termptr, speed_t speed);
*struct termios *termptr:指向termios结构的指针
*speed_t speed:需要设置的波特率
*返回值:成功返回0,否则返回-1
*/
switch (data_bits) /*数据位*/
{
case 7:
{
new_cfg.c_cflag |= CS7;
}
break;
default:
case 8:
{
new_cfg.c_cflag |= CS8;
}
break;
}
switch (parity) /*奇偶位*/
{
default:
case 'n':
case 'N': //无奇偶校验位
{
new_cfg.c_cflag &= ~PARENB;
}
break;
case 'o':
case 'O'://奇校验
{
new_cfg.c_cflag |= (PARODD | PARENB);
/*PARENB:启用奇偶校验码的生成和检测功能。
*PARODD:只使用奇校验而不使用偶校验。
*/
new_cfg.c_iflag |= INPCK;
/*INPCK:对接收到的字符执行奇偶校检。*/
}
break;
case 'e':
case 'E'://偶校验
{
new_cfg.c_cflag |= PARENB;
new_cfg.c_cflag &= ~PARODD;
new_cfg.c_iflag |= INPCK;
}
break;
}
switch (stop_bits) /*停止位*/
{
default:
case 1:
{
new_cfg.c_cflag &= ~CSTOPB;
}
break;
case 2:
{
new_cfg.c_cflag |= CSTOPB;//CSTOPB :设置两个停止位,而不是一个。
}
}
/*设置等待时间和最小接收字符*/
new_cfg.c_cc[VTIME] = 0;
new_cfg.c_cc[VMIN] = 1;
/*处理未接收字符*/
tcflush(fd, TCIFLUSH); //清空flush: int tcflush(int fd, int queue_selector);TCIFLUSH1清除正收到的数据,且不会读出来
/*激活新配置*/
if ((tcsetattr(fd, TCSANOW, &new_cfg)) != 0)
{
perror("tcsetattr");
return -1;
}
/*函数原型:
*#include<termios.h>
*int tcsetattr(int fd , int actions , const struct termios *termios_h);
*参数actions控制修改方式,共有三种修改方式,如下所示:
*TCSANOW:立刻对值进行修改
*TCSADRAIN:等当前的输出完成后再对值进行修改
*TCSAFLUSH:等当前的输出完成之后,再对值进行修改,但丢弃还未从read调用返回的当前的可用的任何输入。
*/
return 0;
}
/*打开串口*/
int open_port(int com_port)
{
int fd,ret;
#if (COM_TYPE == GNR_COM) //条件编译,目标机/宿主机
char *dev[] = {"/dev/ttySAC0", "/dev/ttySAC1", "/dev/ttySAC2","/dev/ttySAC3"};
#else
char *dev[] = {"/dev/ttyUSB0", "/dev/ttyUSB1", "/dev/ttyUSB2"};
#endif
/*(1)针对宿主机的串口打开方法:
*fd = open("/dev/ttyUSB0",O_RDWR | O_NOCTTY | O_NDELAY);
*(2)针对目标机的串口打开方法:
*fd = open("/dev/ttySAC0",O_RDWR | O_NOCTTY | O_NDELAY);
*/
if ((com_port < 0) || (com_port > 4))
{
return -1;
}
/*串口减1*/
fd = open(dev[com_port - 1], O_RDWR|O_NOCTTY|O_NDELAY);
if (fd < 0)
{
perror("open serial port");
return(-1);
}
/*//判断串口的状态是否为阻塞状态 */
if (fcntl(fd, F_SETFL, 0) < 0)//利用fcntl()函数恢复串口为阻塞状态,用于等待串口数据的读入;
{
perror("fcntl F_SETFL\n");
}
//函数原型之一:int fcntl(int fd,int cmd,long arg);
//设置文件打开方式为arg指定方式。 获得/设置文件状态标记(cmd=F_GETFL或F_SETFL).
/*F_SETFL 将文件状态标志设置为第三个参数的值 (取为整型值),可以更改的几个标志是:O_APPEND,O_NONBLOCK,O_SYNC 和 O_ASYNC。
*而fcntl的文件状态标志总共有7个:O_RDONLY , O_WRONLY , O_RDWR , O_APPEND , O_NONBLOCK , O_SYNC和O_ASYNC
*(O_RDONLY,O_WRONLY,以及O_RDWR)这三种标志的值各是 0、1和2
*/
/*测试是否为终端设备*/
if(isatty(STDIN_FILENO) == 0)
printf("standard input is not a terminal device\n");
else
printf("isatty success!\n");
if(DEBUG)
printf("the isatty return is%d\n",isatty(STDIN_FILENO));
return fd;
}
#endif
Linux C --串口编程
最新推荐文章于 2025-04-21 21:20:16 发布