linux 串口测试程序

 

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<termios.h>
#include<string.h>

int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)
{
 struct termios newtio,oldtio;
 if  ( tcgetattr( fd,&oldtio)  !=  0) {
  perror("SetupSerial 1");
  return -1;
 }
 bzero( &newtio, sizeof( newtio ) );
 newtio.c_cflag  |=  CLOCAL | CREAD;
 newtio.c_cflag &= ~CSIZE;

 switch( nBits )
 {
 case 7:
  newtio.c_cflag |= CS7;
  break;
 case 8:
  newtio.c_cflag |= CS8;
  break;
 }

 switch( nEvent )
 {
 case 'O':
  newtio.c_cflag |= PARENB;
  newtio.c_cflag |= PARODD;
  newtio.c_iflag |= (INPCK | ISTRIP);
  break;
 case 'E':
  newtio.c_iflag |= (INPCK | ISTRIP);
  newtio.c_cflag |= PARENB;
  newtio.c_cflag &= ~PARODD;
  break;
 case 'N': 
  newtio.c_cflag &= ~PARENB;
  break;
 }

 switch( nSpeed )
 {
 case 2400:
  cfsetispeed(&newtio, B2400);
  cfsetospeed(&newtio, B2400);
  break;
 case 4800:
  cfsetispeed(&newtio, B4800);
  cfsetospeed(&newtio, B4800);
  break;
 case 9600:
  cfsetispeed(&newtio, B9600);
  cfsetospeed(&newtio, B9600);
  break;
 case 115200:
  cfsetispeed(&newtio, B115200);
  cfsetospeed(&newtio, B115200);
  break;
 case 460800:
  cfsetispeed(&newtio, B460800);
  cfsetospeed(&newtio, B460800);
  break;
 default:
  cfsetispeed(&newtio, B9600);
  cfsetospeed(&newtio, B9600);
  break;
 }
 if( nStop == 1 )
  newtio.c_cflag &=  ~CSTOPB;
 else if ( nStop == 2 )
 newtio.c_cflag |=  CSTOPB;
 newtio.c_cc[VTIME]  = 0;
 newtio.c_cc[VMIN] = 0;
 tcflush(fd,TCIFLUSH);
 if((tcsetattr(fd,TCSANOW,&newtio))!=0)
 {
  perror("com set error");
  return -1;
 }
// printf("set done!\n\r");
 return 0;
}

int main(void)
{
 int fd1,fd2,nset1,nset2,nread;
 char buf[100];
 char buf1[1];
 char *buff = "Hello\n\r";

 fd1 = open( "/dev/ttySAC0", O_RDWR);
 if (fd1 == -1)
  exit(1);
 printf("open  SAC0 success!!\n");

 fd2 = open( "/dev/ttyUSB0", O_RDWR);
 if (fd2 == -1)
  exit(1);

 printf("open  USB0 success!!\n");

 nset1 = set_opt(fd1, 9600, 8, 'N', 1);
 if (nset1 == -1)
  exit(1);
 printf("SET  SAC0 success!!\n");

 nset2 = set_opt(fd2, 9600, 8, 'N', 1);
 if (nset2 == -1)
  exit(1);
 printf("SET  USB0 success!!");

 while (1)

 { 
  printf("enter the loop!!\n");
  nread = read(fd2, buf1, 1);
  printf("nread = %d\n",nread);
  if (nread > 0)
  printf("read success!!\n");
  if (nread > 0)
   {
   write(fd1, buf, 1);
      printf("write success!!\n");
   }
  //nread = read(fd1, buf1,1);
  //if(buf1[0] == 'q')
   //break;
 }
 close(fd1);
 close(fd2);
 return 0;
}

 

有两个可以进行控制串口阻塞性(同时控制read和write):一个是在打开串口的时候,open函数是否带O_NDELAY;第二个是可以在打开串口之后通过fcntl()函数进行控制。

阻塞的定义:

       对于read,block指当串口输入缓冲区没有数据的时候,read函数将会阻塞在这里,移植到串口输入缓冲区中有数据可读取,read读到了需要的字节数之后,返回值为读到的字节数;

对于write,block指当串口输出缓冲区满,或剩下的空间小于将要写入的字节数,则write将阻塞,一直到串口输出缓冲区中剩下的空间大于等于将要写入的字节数,执行写入操作,返回写入的字节数。

非阻塞的定义:

对于read,no block指当串口输入缓冲区没有数据的时候,read函数立即返回,返回值为0。

对于write,no block指当串口输出缓冲区满,或剩下的空间小于将要写入的字节数,则write将进行写操作,写入当前串口输出缓冲区剩下空间允许的字节数,然后返回写入的字节数。

 

通过对 newtio.c_cc[VTIME]  = 0;  newtio.c_cc[VMIN] = 0;两处也可以设置阻塞。

options.c_cc[VTIME] = 0; /* 等待100ms* 该值等待时间就返回 */

options.c_cc[VMIN] = 1; /* 接收到该值数量字节就返回 */


两个都为非零时任意一个条件达到都返回
如果两个条件都为零,则马上返回
如果一个为非零,则仅仅关注该非零条件

下面是一个简单的Linux串口测试程序的源码示例: ```c #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <termios.h> int main() { int fd; struct termios options; fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY); // 打开串口设备 if (fd == -1) { perror("无法打开串口"); exit(EXIT_FAILURE); } fcntl(fd, F_SETFL, 0); // 获取当前串口的配置 tcgetattr(fd, &options); // 设置串口的波特率 cfsetispeed(&options, B9600); cfsetospeed(&options, B9600); // 设置数据位、停止位和奇偶校验位 options.c_cflag &= ~CSIZE; options.c_cflag |= CS8; options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; // 应用配置到串口 tcsetattr(fd, TCSANOW, &options); // 向串口发送数据 char buffer[] = "Hello, Serial Port!"; write(fd, buffer, sizeof(buffer)); // 从串口接收数据 char read_buffer[256]; int num_bytes = read(fd, read_buffer, sizeof(read_buffer)); read_buffer[num_bytes] = '\0'; printf("接收到的数据:%s\n", read_buffer); close(fd); return 0; } ``` 在以上示例中,程序首先打开了一个串口设备(在这里使用的是/dev/ttyS0,你可以根据实际情况修改)。然后,它获取了当前串口的配置,对其进行了相应的设置(如波特率、数据位、停止位和奇偶校验位等),并将配置应用到串口。程序接着向串口发送了一串数据,并从串口接收了数据。最后,程序关闭了串口设备。如果程序无法打开串口或者在读写串口时出现错误,它会打印相应的错误信息。 这只是一个简单的串口测试程序示例,你可以根据自己的需求对其进行修改和扩展。另外,请注意在编译时链接所需的头文件和库文件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值