linux串口收发程序

最近在测试一个开发板的串口是否可以正常使用,开发板使用了linux系统,因此就写了个串口的收发程序来测试。

1.首先使用open函数打开串口,在linux中一切设备都被当做文件来看待,测试的串口所对应的文件为  /dev/ttySAC。

fd = open("/dev/ttySAC2",O_RDWR|O_NOCTTY);

得到了一个文件描述符fd。

2.然后就是对这个串口进行设置,设置其波特率、数据位、校验位、停止位。

tcgetattr(fd,&opt);

cfsetispeed(&opt,B115200);

cfsetospeed(&opt,B115200);

   opt.c_cflag |= (CLOCAL | CREAD);                  

// 无校验 8位数据位1位停止位

       opt.c_cflag &= ~PARENB;                         

       opt.c_cflag &= ~CSTOPB;

       opt.c_cflag &= ~CSIZE;

// 8个数据位

       opt.c_cflag |= CS8;

// 原始数据输入

       opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);

       opt.c_oflag &= ~(OPOST);

// 设置等待时间和最小接收字符数

       opt.c_cc[VTIME]    = 0;                          

       opt.c_cc[VMIN]     = 0;  

// 处理未接收的字符

       tcflush(fd, TCIFLUSH);  
       tcsetattr(fd,TCSANOW,&opt);

其中opt的类型为

struct termios {

tcflag_t c_iflag; /* 输入参数 */

tcflag_t c_oflag; /* 输出参数 */

tcflag_t c_cflag; /* 控制参数*/

tcflag_t c_ispeed; /* 输入波特率 */

tcflag_t c_ospeed; /* 输出波特率 */

cc_t c_line; /* 线控制 */

cc_t c_cc[NCCS]; /* 控制字符*/

};

个人感觉比较重要的是对于

opt.c_cc[VTIME]    = 0;                          

 opt.c_cc[VMIN]     = 0;   的设置

MIN指定了一个read返回前的最小字节数,TIME指定等待数据到达的分秒数。

共有下面四种情形:

A.MIN>0,TIME>0

注意:这个时候的TIME为字节间定时,只在第一个字节被接收时启动。在该定时器超时之前,若已接收到MIN个字节,则read返回MIN个字节。如果在接收到MIN个字节之前,定时器已经超时,则read返回MIN个字节。如果在接到MIN个字节之前,该定时器已经超时,则read返回已经接收到的字节数,因为定时器实在接收到一个字节之后开始启动,所以最少会返回一个字节。如果一只收不到数据,那么read这个函数就会一直阻塞

B.MIN=0,TIME>0

TIME指定了一个调用read时的读定时器,当接收到一个字节时或者超时后才会返回。

C.MIN>0,TIME=0

在接收到MIN个字节之前永远不会返回,有可能永远阻塞在这里。

D.MIN=0,TIME=0

如果有数据的时候,read最多会返回所要求的字节数。如果无数据,则read会立即返回0.这种情况类似于recv的最后一个option为MSG_DONTWAIT时的情形。

在这里都设置为0,说明read执行之后,如果没有读到数据,会立即返回。

3.然后就是读取和接收串口数据了

while(1)
    {        
                if(write(fd,wb,6)!=6)
                    printf("write error\n");
                retv=read(fd,buf,1024);   
                
                if(retv==-1)
                    
                 printf("read failed\n");
                
                if(retv>0)
                 {
                     printf("receive data is %s\n",buf);
                
                 }
                 usleep(10000);
        }        
首先向串口中写入数据,然后再从串口中读取数据,这时候只需要把这个串口的发送的引脚和接收的引脚相连,那么这个串口就能接收到自己发送的数据。并且休眠10ms。

完整程序如下:

#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>      /*错误号定义*/
#define FALSE -1
#define TRUE 0
int set_Parity(int fd,int databits,int stopbits,int parity);
int main()
{
char buf[1024];
char wb[6]="hello";
int fd,flag_close,retv;
struct  termios opt;
fd = open("/dev/ttySAC2",O_RDWR|O_NOCTTY);
if(fd==-1)
	{
	   printf("open failed\n");
	   exit (0);
	}
else
		printf("open success\n");

tcgetattr(fd,&opt);

cfsetispeed(&opt,B115200); 

cfsetospeed(&opt,B115200);

   opt.c_cflag |= (CLOCAL | CREAD);                   

 

// 无校验 8位数据位1位停止位

       opt.c_cflag &= ~PARENB;                         

       opt.c_cflag &= ~CSTOPB;

       opt.c_cflag &= ~CSIZE;

 

// 8个数据位

       opt.c_cflag |= CS8;

 

// 原始数据输入

       opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); 

       opt.c_oflag &= ~(OPOST);

 

// 设置等待时间和最小接收字符数

       opt.c_cc[VTIME]    = 0;                          

       opt.c_cc[VMIN]     = 0;   

 

// 处理未接收的字符

       tcflush(fd, TCIFLUSH);  
       tcsetattr(fd,TCSANOW,&opt);                         

printf("start send\n");
	while(1)
	{		
				if(write(fd,wb,6)!=6)
					printf("write error\n");
				retv=read(fd,buf,1024);   
				
				if(retv==-1)
					
				 printf("read failed\n");
				
				if(retv>0)
				 {
				     printf("receive data is %s\n",buf);
				
				 }
				 usleep(10000);
		}		 

flag_close = close(fd);

if(flag_close == -1)   
  printf("Close the Device failed\n");
return 0;

}




评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值