• linux串口示例


    最近看了下linux的串口,发现还是蛮容易的

    做一些总结和记录

    【这篇文章也重在备份和记录,代码都是套用别人的 ,所以基本只是罗列了些代码,但保证代码可用】

    其实串口操作也就那么几步

    1.打开串口

    2.设置参数

    3.发送接收

    4.按需关闭

    而根据函式提供的形式,

    一般设置参数分两步进行【其实就是那么配置下,分几步都行,只是配合后面的代码了】

    [1]设置波特率

    [2]设置数据格式

    下面还是罗列一些代码

    打开串口

    int OpenDev(char *Dev)

    {

    int fd = open( Dev, O_RDWR );

    if (-1 == fd)

    {

    perror("Can't Open Serial Port");

    return -1;

    }

    else

    return fd;

    }

    O_RDWR就是可读写的意思设置波特率

    Code

    int speed_arr[] = { B38400, B19200, B9600, B4800, B2400, B1200, B300,

    B38400, B19200, B9600, B4800, B2400, B1200, B300, };

    int name_arr[] = {38400, 19200, 9600, 4800, 2400, 1200, 300, 38400,

    19200, 9600, 4800, 2400, 1200, 300, };

    void set_speed(int fd, int speed){

    int i;

    int status;

    struct termios Opt;

    tcgetattr(fd, &Opt);

    for ( i= 0; i < sizeof(speed_arr) / sizeof(int); i++) {

    if (speed == name_arr[i]) {

    tcflush(fd, TCIOFLUSH);

    cfsetispeed(&Opt, speed_arr[i]);

    cfsetospeed(&Opt, speed_arr[i]);

    status = tcsetattr(fd, TCSANOW, &Opt);

    if (status != 0) {

    perror("tcsetattr fd1");

    return;

    }

    tcflush(fd,TCIOFLUSH);

    }

    }

    }

    设置参数是用到了一个专用的结构体struct termios其实也没啥说的,就是通过它去配置串口参数罢了

    注意tcflush,他是清空buffer用的,关于buffer这东西,里面其实挺饶,这里不多说明,只是要注意它清空的buffer并不是printf那类函式中所谓的缓冲。

    另外那两个数组,其实可以弄的简单些,只不过懒得改了

    有点像画刷的使用,旧的一般都爱保存起来,最后还要还原。

    设置数据格式

    int set_Parity(int fd,int databits,int stopbits,int parity)

    {

    struct termios options;

    if ( tcgetattr( fd,&options) != 0) {

    perror("SetupSerial 0");

    return -1;

    }

    options.c_cflag &= ~CSIZE;

    switch (databits)

    {

    case 7:

    options.c_cflag |= CS7;

    break;

    case 8:

    options.c_cflag |= CS8;

    break;

    default:

    fprintf(stderr,"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:

    fprintf(stderr,"Unsupported parity\n");

    return -1;

    }

    switch (stopbits)

    {

    case 1:

    options.c_cflag &= ~CSTOPB;

    break;

    case 2:

    options.c_cflag |= CSTOPB;

    break;

    default:

    fprintf(stderr,"Unsupported stop bits\n");

    return -1;

    }

    if (parity != 'n')

    options.c_iflag |= INPCK;

    tcflush(fd,TCIFLUSH);

    options.c_cc[VTIME] = 150;

    options.c_cc[VMIN] = 0;

    if (tcsetattr(fd,TCSANOW,&options) != 0)

    {

    perror("SetupSerial 3");

    return -1;

    }

    return 0;

    }

    和前面的函式不同这里直接对struct termios进行操作,进而配置了数据位长度,校验位,停止位,超时等信息

    最后整合下,列出一个测试用例

    #include <stdio.h>

    #include <stdlib.h>

    #include <unistd.h>

    #include <sys/types.h>

    #include <sys/stat.h>

    #include <fcntl.h>

    #include <termios.h>

    #include <errno.h>

    int speed_arr[] = { B38400, B19200, B9600, B4800, B2400, B1200, B300,

    B38400, B19200, B9600, B4800, B2400, B1200, B300, };

    int name_arr[] = {38400, 19200, 9600, 4800, 2400, 1200, 300, 38400,

    19200, 9600, 4800, 2400, 1200, 300, };

    void set_speed(int fd, int speed){

    int i;

    int status;

    struct termios Opt;

    tcgetattr(fd, &Opt);

    for ( i= 0; i < sizeof(speed_arr) / sizeof(int); i++) {

    if (speed == name_arr[i]) {

    tcflush(fd, TCIOFLUSH);

    cfsetispeed(&Opt, speed_arr[i]);

    cfsetospeed(&Opt, speed_arr[i]);

    status = tcsetattr(fd, TCSANOW, &Opt);

    if (status != 0) {

    perror("tcsetattr fdl");

    return;

    }

    tcflush(fd,TCIOFLUSH);

    }

    }

    }

    int set_Parity(int fd,int databits,int stopbits,int parity)

    {

    struct termios options;

    if ( tcgetattr( fd,&options) != 0) {

    perror("SetupSerial 1");

    return -1;

    }

    options.c_cflag &= ~CSIZE;

    switch (databits)

    {

    case 7:

    options.c_cflag |= CS7;

    break;

    case 8:

    options.c_cflag |= CS8;

    break;

    default:

    fprintf(stderr,"Unsupported data size\n"); return 0;

    }

    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:

    fprintf(stderr,"Unsupported parity\n");

    return -1;

    }

    switch (stopbits)

    {

    case 1:

    options.c_cflag &= ~CSTOPB;

    break;

    case 2:

    options.c_cflag |= CSTOPB;

    break;

    default:

    fprintf(stderr,"Unsupported stop bits\n");

    return -1;

    }

    if (parity != 'n')

    options.c_iflag |= INPCK;

    tcflush(fd,TCIFLUSH);

    options.c_cc[VTIME] = 150;

    options.c_cc[VMIN] = 0;

    if (tcsetattr(fd,TCSANOW,&options) != 0)

    {

    perror("SetupSerial 3");

    return -1;

    }

    return 0;

    }

    int OpenDev(char *Dev)

    {

    int fd = open( Dev, O_RDWR );

    if (-1 == fd)

    {

    perror("Can't Open Serial Port");

    return -1;

    }

    else

    return fd;

    }

    int main(int argc, char **argv){

    int fd;

    int nread;

    char buff[6];

    char *dev = "/dev/ttyS0";

    fd = OpenDev(dev);

    set_speed(fd,9600);

    if (set_Parity(fd,8,1,'N') == FALSE) {

    printf("Set Parity Error\n");

    exit (0);

    }

    while (1) {

    write(fd,"hello",5);

    nread = read(fd, buff, 5);

    tcflush(fd,TCIOFLUSH);

    buff[nread+1] = '\0';

    printf( "%s", buff);

    }

    //close(fd);

    // exit (0);

    }

    这个测试将发送hello字符并接受,主要是为了测试自发自收用的如果有串口的话,可以使用跳线帽将2,3脚端接来完成此测试可以看到终端中不断出现hellohello……就对了!我的是现代化的笔记本。。。。。XD怎会有串口的存在所以整了张卡,据说比usb转接线稳定,目前还没发现稳定到哪里去

  • 相关阅读:
    Graylog安装操作
    CF1012C Hills
    MySQL 加锁处理分析
    2.22考试
    int(1)和int(11)是否有区别?
    「LibreOJ NOI Round #1」验题
    MySQL一致性非锁定读
    [学习笔记]凸优化/WQS二分/带权二分
    MySQL latch小结
    [八省联考2018]林克卡特树lct——WQS二分
  • 原文地址:https://www.cnblogs.com/top5/p/1570422.html
Copyright © 2020-2023  润新知