Linux tty串口测试程序

FROM:http://blog.csdn.net/hanglinux/article/details/44978745

在程序中,很容易配置串口的属性,这些属性定义在结构体struct termios中。

关于termios的详细介绍,可以另行查资料,或者参考:详解Linux下的串口通讯开发:http://blog.itpub.NET/24790158/viewspace-1041147/


[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #include<stdio.h>  
  2. #include<stdlib.h>  
  3. #include<string.h>  
  4. #include<sys/types.h>  
  5. #include<sys/stat.h>  
  6. #include<fcntl.h>  
  7. #include<unistd.h>  
  8. #include<termios.h>  
  9. #include<string.h>  
  10.   
  11. int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)  
  12. {  
  13.      struct termios newtio,oldtio;  
  14.      if  ( tcgetattr( fd,&oldtio)  !=  0) {  
  15.       perror("SetupSerial 1");  
  16.       return -1;  
  17.      }  
  18.      bzero( &newtio, sizeof( newtio ) );  
  19.      newtio.c_cflag  |=  CLOCAL | CREAD; //CLOCAL:忽略modem控制线  CREAD:打开接受者  
  20.      newtio.c_cflag &= ~CSIZE; //字符长度掩码。取值为:CS5,CS6,CS7或CS8  
  21.   
  22.      switch( nBits )  
  23.      {  
  24.      case 7:  
  25.       newtio.c_cflag |= CS7;  
  26.       break;  
  27.      case 8:  
  28.       newtio.c_cflag |= CS8;  
  29.       break;  
  30.      }  
  31.   
  32.      switch( nEvent )  
  33.      {  
  34.      case 'O':  
  35.       newtio.c_cflag |= PARENB; //允许输出产生奇偶信息以及输入到奇偶校验  
  36.       newtio.c_cflag |= PARODD;  //输入和输出是奇及校验  
  37.       newtio.c_iflag |= (INPCK | ISTRIP); // INPACK:启用输入奇偶检测;ISTRIP:去掉第八位  
  38.       break;  
  39.      case 'E':  
  40.       newtio.c_iflag |= (INPCK | ISTRIP);  
  41.       newtio.c_cflag |= PARENB;  
  42.       newtio.c_cflag &= ~PARODD;  
  43.       break;  
  44.      case 'N':   
  45.       newtio.c_cflag &= ~PARENB;  
  46.       break;  
  47.      }  
  48.   
  49.      switch( nSpeed )  
  50.      {  
  51.      case 2400:  
  52.       cfsetispeed(&newtio, B2400);  
  53.       cfsetospeed(&newtio, B2400);  
  54.       break;  
  55.      case 4800:  
  56.       cfsetispeed(&newtio, B4800);  
  57.       cfsetospeed(&newtio, B4800);  
  58.       break;  
  59.      case 9600:  
  60.       cfsetispeed(&newtio, B9600);  
  61.       cfsetospeed(&newtio, B9600);  
  62.       break;  
  63.      case 115200:  
  64.       cfsetispeed(&newtio, B115200);  
  65.       cfsetospeed(&newtio, B115200);  
  66.       break;  
  67.      case 460800:  
  68.       cfsetispeed(&newtio, B460800);  
  69.       cfsetospeed(&newtio, B460800);  
  70.       break;  
  71.      default:  
  72.       cfsetispeed(&newtio, B9600);  
  73.       cfsetospeed(&newtio, B9600);  
  74.       break;  
  75.      }  
  76.   
  77.      if( nStop == 1 )  
  78.       newtio.c_cflag &=  ~CSTOPB; //CSTOPB:设置两个停止位,而不是一个  
  79.      else if ( nStop == 2 )  
  80.      newtio.c_cflag |=  CSTOPB;  
  81.        
  82.      newtio.c_cc[VTIME]  = 0; //VTIME:非cannoical模式读时的延时,以十分之一秒位单位  
  83.      newtio.c_cc[VMIN] = 0; //VMIN:非canonical模式读到最小字符数  
  84.      tcflush(fd,TCIFLUSH); // 改变在所有写入 fd 引用的对象的输出都被传输后生效,所有已接受但未读入的输入都在改变发生前丢弃。  
  85.      if((tcsetattr(fd,TCSANOW,&newtio))!=0) //TCSANOW:改变立即发生  
  86.      {  
  87.       perror("com set error");  
  88.       return -1;  
  89.      }  
  90.      printf("set done!\n\r");  
  91.      return 0;  
  92. }  
  93.   
  94. int main(void)  
  95. {  
  96.      int fd1,nset,nread,ret;  
  97.      char buf[100]={"test com data!...........\n"};  
  98.      char buf1[100];  
  99.   
  100.      fd1 = open( "/dev/ttySAC0", O_RDWR);  
  101.      if (fd1 == -1)  
  102.       exit(1);  
  103.      printf("open  SAC0 success!!\n");  
  104.   
  105.      nset = set_opt(fd1, 9600, 8, 'N', 1);  
  106.      if (nset == -1)  
  107.       exit(1);  
  108.      printf("SET  SAC0 success!!\n");  
  109.      printf("enter the loop!!\n");  
  110.   
  111.      while (1)  
  112.   
  113.      {   
  114.        memset(buf1, 0, sizeof(buf1));  
  115.        ret = write(fd1, buf, 100);  
  116.        if( ret > 0){  
  117.           printf("write success!  wait data receive\n");  
  118.        }  
  119.        nread = read(fd1, buf1, 100);  
  120.        if(nread > 0){  
  121.         printf("redatad: nread = %s\n\n\r", buf1);  
  122.        }  
  123.        sleep(1);  
  124.       //nread = read(fd1, buf1,1);  
  125.       //if(buf1[0] == 'q')  
  126.        //break;  
  127.      }  
  128.  close(fd1);  
  129.   
  130.  return 0;  
  131. }  
用arm-linux-gcc交叉编译后在开发板上运行,将9口串口的2 3短接:

[python]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. # ./com   
  2. open  SAC0 success!!  
  3. set done!  
  4. SET  SAC0 success!!  
  5. enter the loop!!  
  6. write success!  wait data receive  
  7. write success!  wait data receive  
  8. write success!  wait data receive  
  9. write success!  wait data receive  
  10. write success!  wait data receive  
  11. write success!  wait data receive  
  12. redatad: nread = test com data!...........  
  13.   
  14.   
  15. write success!  wait data receive  
  16. redatad: nread = test com data!...........  
  17.   
  18.   
  19. write success!  wait data receive  
  20. redatad: nread = test com data!...........  
### 回答1: linux串口回环测试程序是一种测试串口通信功能的程序,通过将发送的数据回传给接收端进行验证,以确定串口是否正常工作。 要实现该测试程序,首先需要打开串口设备文件。在Linux中,串口设备文件通常位于/dev目录下,如/dev/ttyS0代表第一个串口设备。可以使用open()函数来打开串口设备文件,例如open("/dev/ttyS0", O_RDWR)。 接下来,需要设置串口的参数,包括波特率、数据位、停止位等。可以使用termios结构体和tcsetattr函数来设置串口参数,例如: struct termios oldTio, newTio; tcgetattr(fd, &oldTio); newTio = oldTio; cfsetispeed(&newTio, B9600); // 设置波特率为9600 cfsetospeed(&newTio, B9600); newTio.c_cflag &= ~PARENB; // 不启用奇偶校验 newTio.c_cflag &= ~CSTOPB; // 停止位为1 newTio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // 关闭标准模式和回显 tcsetattr(fd, TCSANOW, &newTio); 然后,可以使用read()函数从串口读取接收到的数据,并使用write()函数将该数据发送回串口。可以使用一个循环来实现不断进行回环测试,例如: while (1) { char buffer[256]; int bytesRead = read(fd, buffer, sizeof(buffer)); write(fd, buffer, bytesRead); } 最后,需要关闭串口设备文件,可以使用close()函数来关闭已打开的串口设备文件,例如close(fd)。 通过运行该回环测试程序,可以验证串口设备是否正常工作,是否能正常发送和接收数据。 ### 回答2: Linux串口回环测试程序是一种用于测试串口通信功能的程序。串口是一种用于将数据通过物理电缆传输的通信接口,常用于连接计算机与外部设备。 Linux系统提供了一种简单而有效的方法来测试串口的功能,即通过发送数据并接收相同数据来完成回环测试。以下是一个实现简单串口回环测试的示例程序: 1. 首先,打开终端并进入Linux系统。 2. 使用命令行工具编写一个C语言程序,实现串口回环测试。 ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <termios.h> int main() { int serial_port; char data[10] = "Hello!"; // 打开串口设备文件 serial_port = open("/dev/ttyS0", O_RDWR); if (serial_port < 0) { printf("无法打开串口设备文件。\n"); return -1; } // 配置串口 struct termios tty; tcgetattr(serial_port, &tty); cfsetospeed(&tty, B9600); cfsetispeed(&tty, B9600); tty.c_cflag &= ~PARENB; tty.c_cflag &= ~CSTOPB; tty.c_cflag &= ~CSIZE; tty.c_cflag |= CS8; tty.c_cflag &= ~CRTSCTS; tty.c_cflag |= CREAD | CLOCAL; tty.c_iflag &= ~(IXON | IXOFF | IXANY); tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); tty.c_oflag &= ~OPOST; tcsetattr(serial_port, TCSANOW, &tty); // 发送数据 write(serial_port, &data, sizeof(data)); // 接收数据 char receivedData[10]; read(serial_port, &receivedData, sizeof(receivedData)); // 检查数据 if (strcmp(data, receivedData) == 0) { printf("串口回环测试成功!\n"); } else { printf("串口回环测试失败。\n"); } // 关闭串口 close(serial_port); return 0; } ``` 3. 保存程序并编译为可执行文件,例如命名为"serial_test"。 4. 运行程序,它将打开串口设备文件,并将数据发送到串口。然后,它将等待接收到来自串口的相同数据,并将其与发送的数据进行比较。如果两者相同,则表示串口回环测试成功,否则表示失败。 需要注意的是,在代码中使用的串口设备文件"/dev/ttyS0"是一个示例,实际使用时应根据不同的系统和串口配置来修改。 串口回环测试程序对于验证串口通信的可靠性和正确性非常有用。 ### 回答3: Linux串口回环测试程序可以通过打开两个串口设备,一个作为发送端口,一个作为接收端口,实现数据的发送和接收。具体步骤如下: 1. 首先,在终端中输入以下命令,加载UART设备驱动: ``` sudo modprobe serial ``` 2. 使用`ls /dev/tty*`命令查看系统中的串口设备,记下发送端口和接收端口的设备名称,例如`/dev/ttyUSB0`和`/dev/ttyUSB1`。 3. 创建一个C语言源文件,例如`serial_test.c`,编写串口回环测试程序的代码。 4. 在代码中,首先使用`open()`函数打开发送端口和接收端口的设备文件,成功打开后会返回一个文件描述符。 5. 接下来,使用`ioctl()`函数设置串口的通信参数,例如波特率、数据位、停止位和奇偶校验位等。这里可以使用`struct termios`结构体来设置通信参数。 6. 然后,利用`tcflush()`函数刷新发送端口和接收端口的输入输出缓冲区。 7. 接下来,进入一个循环,从发送端口读取数据,并将读取到的数据写入接收端口。可以使用`read()`函数和`write()`函数分别进行读取和写入操作。 8. 最后,使用`close()`函数关闭发送端口和接收端口的设备文件,释放资源。 9. 编译并运行程序,可以使用以下命令进行编译和执行: ``` gcc -o serial_test serial_test.c ./serial_test ``` 通过以上步骤,就可以实现Linux串口回环测试程序,用于测试串口的通信功能是否正常。在测试时,可以通过发送一些数据,并检查接收端是否能够正确接收到相同的数据,以验证串口的回环功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值