`
yuanyu5237
  • 浏览: 162797 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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

#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

分享到:
评论

相关推荐

    linux下串口程序,实现串口回环自发自收,测试串口

    linux下串口程序,实现串口回环自发自收,测试串口

    Linux 串口回环自发自收测试程序

    linux下串口驱动的自发自收测试程序。测试可用。操作方便,运行平台在linux系统平台下,操作也很简单。可以当做串口通用模板。

    linux下串口自发自收例程

    linux下串口自发自收例程

    STM32 串口2自发自收

    本文将详细讲解如何实现STM32的串口2自发自收功能,以及涉及到的相关知识点。 首先,STM32F103系列是基于ARM Cortex-M3内核的微控制器,它具有多个串行通信接口,如USART(通用同步/异步收发传输器)和UART(通用...

    串口自收自发-stm32f103_bicyclelyg_STM32F103_STM32自发自收_

    在标题和描述中提到的“串口自收自发”功能,是指通过串行通信接口(Serial Peripheral Interface, SPI)或通用异步收发传输器(Universal Asynchronous Receiver/Transmitter, UART)实现数据的自动发送和接收。...

    STM32 串口1自发自收

    STM32串口1自发自收是嵌入式开发中的常见应用场景,主要涉及STM32F10X系列芯片的串行通信功能。在本文中,我们将深入探讨如何配置和使用STM32F103的串口1进行数据的发送与接收。 首先,STM32F103是一款基于ARM ...

    简单的串口自发自收程序,采用虚拟串口,便于调试

    本篇文章将详细讲解基于“简单的串口自发自收程序”的相关知识点,包括串口的基本概念、自发自收的含义、虚拟串口的应用以及如何进行串口调试。 首先,串口,即串行通信接口,是一种按照串行方式传输数据的接口,...

    SPI自发自收实验.zip_pilotoy9_spi 自发自收_spi自发自收_stm32f407 spi 自发自收

    在STM32F407中实现SPI自发自收功能,意味着微控制器既可以作为主设备发送数据,也可以作为从设备接收数据,这种功能在需要双向通信的场合非常有用。 SPI协议的基本工作原理是主设备通过SCK(时钟信号)线控制通信的...

    51单片机串口自发自收汇编小程序

    关于串口自发自收的汇编小程序,是51单片机的,收发成功在数码管上显示Good.

    VB串口自发自收程序

    VB串口自发自收程序,只要把串口2-3脚短接就可以了,简单易学

    vb编写的串口自发自收程序

    在这个“vb编写的串口自发自收程序”中,我们可以探讨VB如何与串口进行交互,实现数据的发送与接收。 1. **串口基础知识** - **串口通信**:串口,也称为串行接口,是一种通信协议,它将数据逐位按顺序传输。常见...

    单片机串口通信——自发自收

    ATmega16单片机的自发自收的串口通信

    自发自收串口-labview程序.vi

    labview串口实现自发自收的小程序

    微机原理 串口自发自收程序

    本篇文章将详细介绍一个简单的串口自发自收程序,该程序用于发送和接收ASCII码字符,并且遵循特定的数据格式:每个字有一个逻辑“1”起始位,8位ASCII码数据位,以及1个逻辑“1”停止位,传输波特率为9600baud。...

    串口 自发自收 数据对比

    本程序通过异步读写串口,将串口的发送和接收短接在一起,对发送的数据与接收的数据进行对比,如果收发的数据相等,将DTR设置为高电平,查看DSR是否为高电平,如果为高电平,则弹出“测试通过”对话框,否则弹出...

    Visual C++2008情况下实现串口的自发自收功能

    这是自己通过学习写的一个关于Visual C++2008的串口实现案例,是一个完整的工程,可以直接在visual studio 2008上运行,默认的情况是发送固定的几个数据,要想改的话可以很方便的修改发送的数据,

    PIC18F25K80串口自发自收_PIC18F25K80串口自发自收_PIC18F25k80_

    - **自发送与自接收**:在自发自收模式下,设备既是发送方也是接收方,可以用于测试串口通信链路或模拟通信环境。 **3. 串口自发自收的实现** - **硬件设置**:设置PIC18F25K80的UART模块,连接TX和RX引脚,确保...

    串口自收自发

    labview串口的程序编写,串口的自收自发适合初学者labview串口的程序编写,串口的自收自发适合初学者labview串口的程序编写,串口的自收自发适合初学者

    【课题7】利用8251实现串行口自发自收,并显示。

    【课题7】利用8251实现串行口自发自收,并显示。 二、课程设计任务与目标 设计要求: 1. 按“A”键:清除数码管显示,并通过小键盘输入四位16进制数,同时显示在右侧四个数码管上。 2. 按“B”键:执行串行发送,...

    can自发自收

    "can自发自收"指的是CAN节点能够发送数据并同时接收自己发送的数据,这对于测试和验证CAN网络通信的正确性是非常重要的。 在CAN-RS232网桥中,CAN网络与传统的RS232串行接口进行通信转换。RS232是一种古老的通信...

Global site tag (gtag.js) - Google Analytics