linux应用程序串口操作及配置

linux的设计思想是一切皆文件,对于串口的访问,通过/dev/ttyxx实现对串口设备的访问.

1.串口基本操作

串口最基本的操作是open/read/write. 如下所示是最基本的串口操作程序, open函数打开设备节点,read函数读取串口数据,write函数向串口写入数据.实现终端接收到串口数据,再原封不动的发送给对端.在我们的实际应用中,串口一般外接各类串口模块,比如GPS等.会涉及到配置串口波特率、数据位、停止位等参数.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <asm/termios.h>

#define DEV_UART    "/dev/ttySAC0"
int main (int argc, char *argv[])
{
    int fd;
    int len, i,ret;
    char buf[100] = {0};

    fd = open(DEV_UART, O_RDWR | O_NOCTTY);
    if(fd < 0) {
        perror(DEV_UART);
        return -1;
    }

    while(1){
        len = read(fd, buf, sizeof(buf));
        if (len > 0){
            write(fd, buf, len);
        }
    }
    return 0;
}

2.串口参数设置

串口参数涉及串口波特率、数据位、停止位、奇偶检验位.linux下使用struct termios 结构体来描述这些属性.设置串口参数的流程为,tcgetattr()获取终端属性参数,然后设置串口参数,最后调用tcsetattr()设置终端属性.

struct termios {
    tcflag_t c_iflag;       /* input mode flags */
    tcflag_t c_oflag;       /* output mode flags */
    tcflag_t c_cflag;       /* control mode flags */
    tcflag_t c_lflag;       /* local mode flags */
    cc_t c_line;            /* line discipline */
    cc_t c_cc[NCCS];        /* control characters */
};

2.1. 波特率设置
cfgetispeed和cfgetospeed获取串口的输入输出波特率. cfsetispeed和cfsetospeed设置串口的输入输出波特率.
一般情况下,串口的输入输出波特率都设置为相同的值.

// 设置串口波特率
static void set_baudrate (struct termios *opt, unsigned int baudrate)
{
    cfsetispeed(opt, baudrate);
    cfsetospeed(opt, baudrate);
}

2.2. 数据位设置
数据位置是每个字节中的实际数据所占据的bit数.数据位通过修改struct termios结构体中的c_cflag成员变量实现.CS5、CS6、CS7和CS8分别表示数据位为5、6、7和8.设置数据位之前,先使用CSIZE做位屏蔽.

// 设置数据位.
static void set_data_bit (struct termios *opt, unsigned int databit)
{
    opt->c_cflag &= ~CSIZE;
    switch (databit) {
    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;
    }
}

2.3. 奇偶校验位
奇偶检验可以选择奇校验、偶检验或者不校验.

// 设置奇偶校验.
static void set_parity (struct termios *opt, char parity)
{
    switch (parity) {
    case 'N':                  /* no parity check */
        opt->c_cflag &= ~PARENB;
        break;
    case 'E':                  /* even */
        opt->c_cflag |= PARENB;
        opt->c_cflag &= ~PARODD;
        break;
    case 'O':                  /* odd */
        opt->c_cflag |= PARENB;
        opt->c_cflag |= ~PARODD;
        break;
    default:                   /* no parity check */
        opt->c_cflag &= ~PARENB;
        break;
    }
}

2.4.停止位设置

static void set_stopbit (struct termios *opt, const char *stopbit)
{
    if (0 == strcmp (stopbit, "1")) {
        opt->c_cflag &= ~CSTOPB; /* 1 stop bit */
    }   else if (0 == strcmp (stopbit, "1")) {
        opt->c_cflag &= ~CSTOPB; /* 1.5 stop bit */
    }   else if (0 == strcmp (stopbit, "2")) {
        opt->c_cflag |= CSTOPB;  /* 2 stop bits */
    } else {
        opt->c_cflag &= ~CSTOPB; /* 1 stop bit */
    }
}

3.测试函数

int main (int argc, char *argv[])
{
    int fd;
    int len;
    char buf[1024] = {0};
    struct termios opt;

    fd = open(DEV_UART, O_RDWR | O_NOCTTY);
    if(fd < 0) {
        perror(DEV_UART);
        return -1;
    }
        tcgetattr(fd, &opt);
        //设置波特率
    set_baudrate(&opt, B115200);
    opt.c_cflag          |= CLOCAL | CREAD;      /* | CRTSCTS */
    //设置数据位
    set_data_bit(&opt, 8);
    //设置校验位
    set_parity(&opt, 'N');
    //设置停止位
    set_stopbit(&opt, "1");
    tcsetattr (fd, TCSANOW, &opt);

    while(1){
        len = read(fd, buf, sizeof(buf));
        if (len > 0){
            write(fd, buf, len);
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值