Linux TTY 应用层

引用

1. 在linux上用man termios,可以找到详细的termios信息。

2. Linux串口编程_termios

https://blog.csdn.net/qingkongyizhicong/article/details/45222703

3. Python的串口通信(pyserial)

https://www.cnblogs.com/dongxiaodong/p/9992083.html

4. Python实现串口通信(pyserial)

https://www.cnblogs.com/-wenli/p/11261109.html


一. linux c应用实例

#include <stdio.h>                                                                                                 
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <pthread.h>

static int open_serial_file(int port)
{
    int serial_fd = 0;
    int string_length = 0;
    char device_name[20] = {0};

    string_length = sizeof(device_name);
    memset(device_name, 0x00, string_length);
    snprintf(device_name, string_length, "%s%d", "/dev/ttyS", port);

    printf("**device_name: %s***************", device_name);
    serial_fd = open(device_name, O_RDWR);
    if (serial_fd < 0) {
        printf("open uart device error!");
        return -1;
    }

    return serial_fd;
}

static int close_serial_file(int serial_fd)
{
    int ret = -1;

    if (serial_fd < 0) {
        printf("the serial fd error!");
        goto error;
    }

    ret = close(serial_fd);
        if (ret < 0){
        printf("close serial port error!");
    }

error:
    return ret;
}

/************************************************************
*函数说明
*       设置串口属性
*参数
*       serial_fd: 串口设备文件描述符; baudrate: 波特率; 
*      databits: 数据位数; stopbits: 停止位; parity: 奇偶校验位
* set_port_attr(serial_fd, B460800, 8, "1", 'n');
**************************************************************/
static int set_port_attr(int serial_fd, int baudrate, int databits, const char * stopbits, char parity)
{
    struct termios opt;
    int ret = 0;

    /*get the serial attribute*/
    if (tcgetattr(serial_fd, &opt) != 0) {
        printf("get the serial attribute error.");
        goto error;
    }

    opt.c_cflag |= CLOCAL | CREAD;

    /*set the serial baudrate*/
    cfsetispeed(&opt, baudrate);
    cfsetospeed(&opt, baudrate);

    /*set serial data bits*/
    opt.c_cflag &= ~CSIZE;
    switch (databits) {
    case 8:
        opt.c_cflag |= CS8;
        break;

    case 7:
        opt.c_cflag |= CS7;
        break;
        
    case 6:
        opt.c_cflag |= CS6;
        break;

    case 5:
        opt.c_cflag |= CS5;
        break;

    default:
        opt.c_cflag |= CS8;
        break;
    }

    /*set serial parity bits*/
    switch (parity) {
    case 'N':
    case 'n':
        opt.c_cflag &= ~PARENB;
        break;

    case 'E':
    case 'e':
        opt.c_cflag |= PARENB;
        opt.c_cflag &= ~PARODD;
        opt.c_iflag |= (INPCK | ISTRIP);
        break;

    case 'O':
    case 'o':
        opt.c_cflag |= PARENB;
        opt.c_cflag |= PARODD;
        opt.c_iflag |= (INPCK | ISTRIP);
        break;

    default:
        opt.c_cflag &= ~PARENB;
        opt.c_iflag &= ~INPCK;
        break;
    }

    /*set serial stop bits*/
    if (0 == strcmp(stopbits, "1")) {
        opt.c_cflag &= ~CSTOPB;

    } else if (0 == strcmp(stopbits, "1.5")) {
        opt.c_cflag &= ~CSTOPB;

    } else if (0 == strcmp(stopbits, "2")) {
        opt.c_cflag |= CSTOPB;

    } else {
        opt.c_cflag &= ~CSTOPB;	
    }

    /*other setting*/
    opt.c_iflag &= ~(IXON | IXOFF | IXANY);
    opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    opt.c_oflag &= ~OPOST;

    /*resolve the problem: send 0x0d,but receive 0x0a.*/
    opt.c_iflag &= ~(INLCR | ICRNL | IGNCR);
    opt.c_oflag &= ~(ONLCR | OCRNL | ONOCR | ONLRET); 

    /*设置有RTS/CTS硬件流控*/
    //	opt.c_cflag |= CRTSCTS; 

    /*clear the serial cache*/
    tcflush(serial_fd, TCIFLUSH);

    /*enable the serial setting*/
    if ((tcsetattr(serial_fd, TCSANOW, &opt)) != 0) {
        printf("set serial port attribute failed!");
        ret = -1;
    }

error: 
    return ret;
}

/************************************************************
 *函数说明
 *		串口接收函数
 *参数
 *      fd: 串口设备文件描述符
 *      siez: 每次读取的数据量(单位: 字节)
 *      rce_wait: 读取超时时间(单位: 秒)

 **************************************************************/
static void    can_serial_read_data(int fd, int size, int rcv_wait_time)
{
    int serial_fd;
    char *mesg = NULL;
    int r_status;
    int read_len = 0;
    int left_len = 0;
    unsigned char r_buff[512];
    serial_fd = fd;

    fd_set rfds;
    struct timeval tv;

    tv.tv_sec = rcv_wait_time;
    tv.tv_usec = 0;

    while (1) {
        FD_ZERO(&rfds);
        FD_SET(serial_fd, &rfds);
        tv.tv_sec = rcv_wait_time;
        tv.tv_usec = 0;
        
        if (rcv_wait_time == 0) 
            r_status = select(serial_fd + 1, &rfds, NULL, NULL, NULL);
        else 
            r_status = select(serial_fd + 1, &rfds, NULL, NULL, &tv);
        
        if (r_status > 0) {
            if (FD_ISSET(serial_fd, &rfds)) {
                read_len = read(serial_fd, r_buff, size);
                if (read_len < 0) {		
                    printf("serial read data error!");
                }
            }	
        } else if (r_status < 0) {
            mesg = strerror(errno);
            printf("select error, Mesg:%s.", mesg);
        } else if (0 == read_symbol) {
    
        }
    }
}


void main()
{
    int ret = 0;
    int fd = 0;
    fd = open_serial_file(1);
    if (fd < 0)
        printf("open serial fail.");

    set_port_attr(fd, B460800, 8, "1", 'n');
    close_serial_file
    
}

二. python pyserial应用实例

#!/usr/bin/python3
import serial
import time

def main():
    port_name = "/dev/ttyz1"
    time_val = 0.5

    p = serial.Serial(port_name, timeout=time_val)

    print("start write data")
    p.write('aa'.encode())

    print("start read data")
    p.readline()
    time.sleep(10)

    print("close the port")
    p.close()




if __name__ == "__main__":
    main()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值