LINUX下usb串口编程自发自收数据

首先,我是一个初学者,编程之前准备一个USB串口(我用的是有9个针的串口型号是U232-P9 converter),然后用一个我不知道名字的什么线把串口上的两排线中的5根针的那一排线的2,3个针连接起来。

插到笔记本的USB接口上。

ls /dev

你会发现比插上USB串口之前运行该命令时多了一个ttyUSB0 的设备

现在可以使用以下命令查找有效的串口设备:

sudo cat /proc/devices

会出现这个: 188ttyUSB

安装minicom

sudo apt-get install minicom

安装好后设置

sudo minicom -s

出现如下界面

┌──[configuration]────┐
│ Filenames and paths │
│ File transfer protocols │
Serial port setup
│ Modem and dialing │
│ Screen and keyboard │
│ Save setup as ttyS0 │
Save setup as..
│ Exit │
Exit from Minicom
└───────────────┘

选则Serial port setup │进入如下界面:

┌────────────────────────────────────────────┐
│ A - Serial Device : /dev/ttyS8 │
│ B - Lockfile Location : /var/lock │
│ C - Callin Program : │
│ D - Callout Program : │
│ E - Bps/Par/Bits : 115200 8N1 │
│ F - Hardware Flow Control : No │
│ G - Software Flow Control : No │
│ │
│ Change which setting? │
└───────────────────────────────────────────┘

修改A设置里的/dev/ttyS8 为新添加的串口/dev/ttyUSB0

退出该界面,选择 Save setup as.. 保存为ttyUSB0

选择Exit from Minicom 退出;

现在尝试连接该串口:

sudo minicom ttyUSB0

如果正确地进入一个什么都不能操作的界面,那大概就算成功了,直接关闭终端退出,看我们下面的程序:

还是那句话,源码之下了无秘密:

 

#include       /*标准输入输出定义*/
#include      /*标准函数库定义*/
#include      /*Unix 标准函数定义*/
#include   
#include    
#include       /*文件控制定义*/
#include     /*PPSIX 终端控制定义*/
#include       /*错误号定义*/
#include 

#define FALSE -1
#define TRUE 0
#define LENGTH 32

int speed_arr[] = {B38400,B19200,B9600,B4800,B2400,B1200,B300,B38400,B19200,B9600,B4800,B2400,B1200,B300};

int name_arr[] = {38400,19200,9600,4800,2400,1200,300,38400,19200,9600,4800,2400,1200,300};

int OpenDev(char *Dev);
void set_speed(int fd, int speed);
int set_Parity(int fd, int databits, int stopbits, int parity);

int main(int argc, char **argv)
{
	int fd;
	int nread;
	char *dev  = "/dev/ttyUSB0"; //USB串口
	fd = OpenDev(dev);
	tcflush(fd, TCIFLUSH);
	set_speed(fd,38400);
	if (set_Parity(fd,8,1,'N') == FALSE)  
	{
		printf("Set Parity Error\n");
		exit (0);
	}
   	char send[LENGTH];
	char recv[LENGTH];
	fgets(send,LENGTH,stdin);
	printf("send: %s", send);
	write(fd, send, LENGTH);
	//while (1) //循环读取数据
	//{   
		while((nread = read(fd,recv,LENGTH)) > 0)
		{
			//printf("Len:  %d\n", nread);
			recv[nread] = 0;
			//printf("recv:%s\n", buff);
			if (fputs(recv, stdout) == EOF)
				printf("fputs error");
		}
	//}
	close(fd);  
	return 0;
}

/**
 * *@brief  设置串口通信速率
 * *@param  fd     类型 int  打开串口的文件句柄
 * *@param  speed  类型 int  串口速度
 * *@return  void
 * */
void set_speed(int fd, int speed)
{
	int   i; 
	int   status; 
	struct termios   Opt;
	tcgetattr(fd, &Opt); 
	for ( i= 0;  i < sizeof(speed_arr) / sizeof(int);  i++) 
	{ 
	      if  (speed == name_arr[i]) 
	      {     
	            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;     
	            }    
	            tcflush(fd,TCIOFLUSH);   
	      }  
	}
}

/**
 * *@brief   设置串口数据位,停止位和效验位
 * *@param  fd     类型  int  打开的串口文件句柄
 * *@param  databits 类型  int 数据位   取值 为 7 或者8
 * *@param  stopbits 类型  int 停止位   取值为 1 或者2
 * *@param  parity  类型  int  效验类型 取值为N,E,O,S
 * */
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); 
	} 
	/* Set input parity option */ 
	if (parity != 'n')   
		options.c_iflag |= INPCK; 
	tcflush(fd,TCIFLUSH);
	options.c_cc[VTIME] = 150; /* 设置超时15 seconds*/   
	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);  
}

/**********************************************************************
 * 代码说明:使用usb串口测试的,发送的数据是字符,
 * 但是没有发送字符串结束符号,所以接收到后,后面加上了结束符号。
  * **********************************************************************/
/*********************************************************************/

int OpenDev(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;
}
 

刚弄好,就写了这篇日志,主要记录一下,免得以后忘了,总的来说,只要把设备弄好了,能找到设备,之后的编程过程就相对简单一点,跟读取文件一样,不过我发线这个收发数据时不是狠稳定,而且数据的长度设置以及串口的各项参数设置目前我尚未弄懂,此处的内容狠肤浅,我主要参考的两篇文章:

http://www.ibm.com/developerworks/cn/linux/l-serials/

http://blog.china.alibaba.com/blog/zhiqing20091027/article/b0-i8851708.html

你可能感兴趣的:(嵌入式)