linux串口通信(二):自定义串口函数(有错)


一、串口函数详解

1.UART0_Open()

功能:

打开串口并返回串口设备文件描述

原型

int UART0_Open(
	int fd,
	char* port
);

参数:

  • fd:文件描述符
  • port:串口号(ttyS0,ttyS1,ttyS2)
  • 出口参数:正确返回为1,错误返回为-1

例子:

步骤:

  • 打开串口
  • 若串口成功打开,则输出提示信息,并设置为非阻塞状态
  • 若串口未打开,则恢复为阻塞状态
  • 测试是否为终端设备
int UART0_Open(int fd, char* port)
{    
    fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY);    
    if (fd < 0)    
    {    
        printf("Can't Open Serial Port\n");    
        return -1;
    }    
    //恢复串口为阻塞状态                                   
    if(fcntl(fd, F_SETFL, 0) < 0)    
    {    
        printf("fcntl failed!\n");    
        return -1;    
    }         
    else    
    {    
        printf("Open Serial Port Succeed!");
    }
    return 1;    
}   

2.UART0_Close()

功能

关闭串口并返回串口设备文件描述

原型

void UART0_Close(int fd);

参数:

  • fd:文件描述符

例子

void UART0_Close(int fd)    
{
	close(fd);
}

3.UART0_Set()

功能

设置串口数据位,停止位和效验位

原型

int UART0_Set(
	int fd,
	int speed,
	int flow_ctrl,
	int databits,
	int stopbits,
	int parity
);

参数:

  • fd:文件描述符
  • speed:串口速度
  • flow_ctrl:数据流控制
  • databits:数据位,取值为7或者8
  • stopbits:停止位,取值为1或者2
  • parity:效验类型,取值为N,E,O,S
  • 出口参数:正确返回为1,错误返回为-1

例子

步骤:

  • 定义波特率,状态变量,串口结构体
  • 得到与fd指向对象的相关参数,测试串口是否可用
  • 设置串口输入波特率和输出波特率
  • 修改控制模式,保证程序不会占用串口和能够从串口中读取数据
  • 设置数据流控制
  • 设置标志位,并屏蔽其他标志位
  • 设置校验位
  • 设置停止位
  • 修改输出模式
  • 设置等待时间和最小接收字符
  • 激活配置 (将修改后的termios数据设置到串口中)
int UART0_Set(int fd, int speed, int flow_ctrl, int databits, int stopbits, int parity)  
{
    int   i;    
    int   status;    
    int   speed_arr[] = { B115200, B19200, B9600, B4800, B2400, B1200, B300}; 
    int   name_arr[] = {115200,  19200,  9600,  4800,  2400,  1200,  300};    
             
    struct termios options;    
       
    /*  tcgetattr(fd,&options)得到与fd指向对象的相关参数,并将它们保存于options,该函数还可以测试配置是否正确,
        该串口是否可用等。若调用成功,函数返回值为0,若调用失败,函数返回值为1.  */    
    if( tcgetattr(fd, &options) != 0)    
    {    
        printf("SetupSerial 1\n");
        return -1;     
    }    
      
    //设置串口输入波特率和输出波特率    
    for ( i= 0;  i < sizeof(speed_arr) / sizeof(int);  i++)    
    {    
        if  (speed == name_arr[i])    
        {                 
            cfsetispeed(&options, speed_arr[i]);     
            cfsetospeed(&options, speed_arr[i]);      
        }    
    } 

	//修改控制模式,保证程序不会占用串口    
    options.c_cflag |= CLOCAL;    
    
    //修改控制模式,使得能够从串口中读取输入数据    
    options.c_cflag |= CREAD;    
      
    //设置数据流控制    
    switch(flow_ctrl)    
    {    
        case 0 ://不使用流控制
        {
              options.c_cflag &= ~CRTSCTS;    
              break;       
        }  
        case 1 ://使用硬件流控制
        {
              options.c_cflag |= CRTSCTS;    
              break;
        }
        case 2 ://使用软件流控制
        {
              options.c_cflag |= IXON | IXOFF | IXANY;    
              break;    
        }
    }
    
    //设置数据位    
    //屏蔽其他标志位    
    options.c_cflag &= ~CSIZE;    
    switch (databits)    
    {      
        case 5    :
        {
                     options.c_cflag |= CS5;    
                     break;    
        }
        case 6    :    
        {
                     options.c_cflag |= CS6;    
                     break;    
        }
        case 7    :        
        {
                 options.c_cflag |= CS7;    
                 break;    
        }
        case 8:        
        {
                 options.c_cflag |= CS8;    
                 break;      
        }
        default:       
        {
                 printf("Unsupported data size\n");    
                 return -1;
        }
    }    
    //设置校验位    
    switch (parity)    
    {      
        case 'n':    
        case 'N': //无奇偶校验位
                 options.c_cflag &= ~PARENB;     
                 options.c_iflag &= ~INPCK;        
                 break;     
        case 'o':      
        case 'O'://设置为奇校验        
                 options.c_cflag |= (PARODD | PARENB);     
                 options.c_iflag |= INPCK;                 
                 break;     
        case 'e':     
        case 'E'://设置为偶校验      
                 options.c_cflag |= PARENB;           
                 options.c_cflag &= ~PARODD;           
                 options.c_iflag |= INPCK;          
                 break;    
        case 's':    
        case 'S': //设置为空格     
                 options.c_cflag &= ~PARENB;    
                 options.c_cflag &= ~CSTOPB;    
                 break;     
        default:      
                 printf("Unsupported parity\n");        
                 return -1;     
    }     

    // 设置停止位     
    switch (stopbits)    
    {      
        case 1:       
			options.c_cflag &= ~CSTOPB;
			break;     
        case 2:       
			options.c_cflag |= CSTOPB;
			break;
        default:       
			printf("Unsupported stop bits\n");     
			return -1; 
    }    
       
    //修改输出模式,原始数据输出    
    options.c_oflag &= ~OPOST;    
      
    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);    
    //options.c_lflag &= ~(ISIG | ICANON);    
       
    //设置等待时间和最小接收字符    
    options.c_cc[VTIME] = 1; /* 读取一个字符等待1*(1/10)s */      
    options.c_cc[VMIN] = 1; /* 读取字符的最少个数为1 */    
       
    //如果发生数据溢出,接收数据,但是不再读取 刷新收到的数据但是不读    
    tcflush(fd, TCIFLUSH);    
       
    //激活配置 (将修改后的termios数据设置到串口中)    
    if (tcsetattr(fd,TCSANOW,&options) != 0)      
    {    
        printf("com set error!\n");      
        return -1;     
    }    
    return 1;     
}    

4.UART0_Init()

功能

串口初始化

原型

int UART0_Init(
	int fd, 
	int speed,
	int flow_ctrl,
	int databits,
	int stopbits,
	int parity
);

参数:

  • fd:文件描述符
  • speed:串口速度
  • flow_ctrl:数据流控制
  • databits:数据位,取值为7或者8
  • stopbits:停止位,取值为1或者2
  • parity:效验类型,取值为N,E,O,S
  • 出口参数:正确返回为1,错误返回为-1

例子

步骤:

  • 设置串口数据帧格式
int UART0_Init(int fd, int speed, int flow_ctrl, int databits, int stopbits, int parity)
{    
    int err;    
    //设置串口数据帧格式
    if (UART0_Set(fd, 115200, 0, 8, 1, 'N') == -1)
    {                                                             
        return -1;    
    }    
    else    
    {    
        return 1;    
    }    
}

5.UART0_Send()

功能

发送数据

原型

int UART0_Recv(
	int fd, 
	char* rcv_buf,
	int data_len
);

参数:

  • fd:文件描述符
  • send_buf:存放串口发送数据
  • data_len:一帧数据的个数
  • 出口参数:正确返回为1,错误返回为-1

例子

int UART0_Send(int fd, char* send_buf, int data_len)
{    
    int len = 0;   
    len = write(fd, send_buf, data_len);    
    if (len == data_len)    
    {    
        printf("Data sent is %s\n", send_buf);  
        return 1;    
    }         
    else       
    {           
        tcflush(fd,TCOFLUSH);    
        return -1;    
    }          
}

6.UART0_Recv()

功能

接收串口数据

原型

int UART0_Recv(
	int fd, 
	char* rcv_buf,
	int data_len
);

参数:

  • fd:文件描述符
  • rcv_buf:接收串口中数据存入rcv_buf缓冲区中
  • data_len:一帧数据的长度
  • 出口参数:正确返回为读取到的字符个数,错误返回为-1

例子

步骤:

  • 使用select实现串口的多路通信
int UART0_Recv(int fd, char* rcv_buf, int data_len)
{    
    int len,fs_sel;    
    fd_set fs_read;    
       
    struct timeval time;    
       
    FD_ZERO(&fs_read);    
    FD_SET(fd, &fs_read);    
       
    time.tv_sec = 10;    
    time.tv_usec = 0;    
       
    //使用select实现串口的多路通信    
    fs_sel = select(fd + 1, &fs_read, NULL, NULL, &time);    
    printf("fs_sel = %d\n",fs_sel);    
    if(fs_sel)    
    {    
        len = read(fd, rcv_buf, data_len);    
        return len;    
    }    
    else    
    {    
        return -1;    
    }         
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 好用的Qt串口网口通信层可以提供稳定、高效的串口和网口通信功能。Qt是一个跨平台的应用程序开发框架,具有丰富的功能和易用性。在Qt中,可以使用SerialPort模块来实现串口通信,可以方便地设置串口参数、发送和接收数据。通过Qt的串口通信功能,可以实现与外部设备的数据交互。 另外,Qt还提供了Network模块,用于实现网口通信。在网口通信层中,可以使用Qt的Socket类来创建TCP或UDP连接,实现数据的发送和接收。Qt的网口通信功能具有可靠的网络协议支持和良好的错误处理机制,可以满足复杂的网络通信需求。 好用的Qt串口网口通信层还应具备良好的可扩展性和兼容性。Qt的模块化设计使得开发人员可以根据自己的需求轻松地扩展功能,并且可以方便地在不同平台上进行开发和部署。此外,Qt的开源特性也为开发者提供了更多的灵活性和自由度。 总结起来,好用的Qt串口网口通信层应具备稳定、高效的串口和网口通信功能,拥有丰富的功能和易用性,并且具备良好的可扩展性和兼容性。这样的通信层能够满足开发者在串口和网口通信方面的需求,并且能够简化开发流程,提高开发效率。 ### 回答2: 好用的QT串口网口通信层是指一种基于QT开发框架的串口和网口通信的中间层,它能够简化开发人员在QT项目中进行串口和网口通信的工作。这个通信层具有以下几个特点: 1. 方便易用:好用的QT串口网口通信层提供了一套简洁的API,使得开发人员可以快速地在QT项目中进行串口和网口通信的实现。只需简单的调用几个函数或方法,即可完成通信的配置和数据的发送与接收。 2. 可扩展性强:好用的QT串口网口通信层支持多种串口和网口通信协议,如RS232、RS485、TCP/IP等。开发人员可以根据实际需求选择相应的协议,并进行灵活的配置和定制。 3. 跨平台支持:QT是一个跨平台的开发框架,好用的QT串口网口通信层也能够在不同的操作系统上运行,如Windows、Linux、macOS等。这使得开发人员可以在不同的平台上进行串口和网口通信的开发,提高了项目的移植性和可扩展性。 4. 可靠稳定:好用的QT串口网口通信层经过严格的测试和验证,具有良好的稳定性和可靠性。它能够处理各种异常情况,如数据丢失、错误校验等,并提供相应的错误处理机制,保证通信的稳定性和可靠性。 总之,好用的QT串口网口通信层能够为开发人员提供便捷的串口和网口通信功能,使得在QT项目中进行通信的实现更加简单高效。无论是在工业控制、物联网、嵌入式开发等领域,都可以广泛应用这个通信层来满足不同的通信需求。 ### 回答3: 好用的Qt串口和网络通信层涵盖了Qt框架中用于串口和网络通信的库和类。Qt提供了一套全面的工具和接口,使我们可以轻松地在Qt应用程序中实现串口和网络通信功能。以下是为什么它被认为是好用的主要原因: 1. 易于使用:Qt提供了易于理解和使用的API,使开发人员能够在不浪费太多时间的情况下迅速上手。其文档和示例代码对于初学者来说也非常友好,可以快速学习和理解。 2. 跨平台性:Qt是一个跨平台的框架,具有卓越的跨平台能力。通过使用Qt的串口和网络通信层,我们可以轻松实现在不同操作系统上的串口和网络通信,而无需担心处理平台间的差异。 3. 强大的功能:Qt提供了丰富的功能和工具,包括读取和写入串口数据、配置串口参数、网络套接字等。无论是简单的串口通信还是复杂的网络通信,Qt都能够满足我们的需求。 4. 高效和稳定:Qt串口和网络通信层是经过优化和测试的,确保其高效性和稳定性。它可以处理大量的数据传输和并发连接,以满足大部分应用程序的需求。 5. 可扩展性:Qt提供了强大的可扩展性,可以通过自定义类和功能来满足特定的通信需求。我们可以基于Qt串口和网络通信层构建自己的高级通信功能,实现更复杂和特定的应用需求。 总之,Qt串口和网络通信层是一个功能强大且易于使用的工具,为我们的应用程序提供了可靠和高效的串口和网络通信功能。无论是用于连接硬件设备、远程监控还是其他通信需求,Qt提供的这一层都能满足我们的期望。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值