Linux C --串口编程

/*配置串口*/
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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值