zoukankan      html  css  js  c++  java
  • Linux串口

    可以参考http://www.cnblogs.com/lovemo1314/archive/2010/10/29/1864327.html

    《从实践中学嵌入式linux应用程序开发》(华清远见嵌入式学院)第2章、嵌入式文件和I/O编程

    设置串口属性的基本流程:

      • 保存原先串口配置

    使用tcgetattr(fd,&old_cfg)函数,该函数得到有fd指向的终端的配置参数,并将它们保存于termios结构变量old_cfg中。若调试成功,函数返回值为0,若调试失败,函数返回值为-1;

    if(tcgetattr(fd,&old_cfg != 0 )
    {
        perror("tcgetattr");
        return -1;
    }

    若调试成功,函数返回值为0,若调试失败,函数返回值为-1;

    • 激活选项

    CLOCAL和CREAD分别用于本地连接和接收使能,因此首先要通过位掩码的方式激活这两个选项。

    newtio.c_cflag |= CLOCAL | CREAD;

    调用cfmakeraw()函数可以将终端设置为原始模式,在后面的实例中,采用原始模式进行串口数据通信。

    cfmakeraw(&new_cfg);

    • 设置波特率

    cfsetispeed(&new_cfg,B115200);
    cfsetospeed(&new_cfg,B115200);
    • 设置字符大小

    new_cfg.c_cflag &= ~CSIZE;//用数据位掩码清空数据位设置
    new_cfg.c_cflag |= CS8;
    • 设置奇偶校验位

    //使能奇校验
    new_cfg.c_cflag |= (PARODD | PARENB);
    new_cfg.c_iflag |= INPCK;
    //使能偶校验
    new_cfg.c_cflag |= PARENB;
    new_cfg.c_cflag &= ~PARODD;//清除奇校验标志,配置为偶校验
    new_cfg.c_iflag |= INPCK;
    • 设置停止位

    new_cfg.c_cflag &= ~CSTOPB;//将停止位设置为一个bite
    new_cfg.c_cflag |= CSTOPB;//将停止位设置为两个bite
    • 设置最少字符和等待时间

    new_cfg.c_cc[VTIME] = 0;
    new_cfg.c_cc[VMIN] = 0;
    • 清除串口缓冲

    int tcdrain(int fd);//使程序阻塞,直到输出缓冲区的数据全部发送完毕
    int tcflow(int fd,int action);//用于暂停或从新开始输入
    int tcflush(int fd,int queue_selector);//用于清空输入/输出缓冲区
    • 激活配置

    if((tcsetattr(fd,TCSANOW,&new_cfg)) != 0)
    {
        perror("tcsetattr");
        return -1;
    }

    串口配置实例:

    int set_com_config(int fd,int baud_rate,int data_bits,char parity.int stop_bits)
    {
        struct termios new_cfg,old_cfg;
        int speed;
        
        if(tcgetattr(fd,&old_cfg != 0)
        {
            perror("tcgetattr");
            return -1;
        }
        new_cfg = old_cfg;
        cfmakeraw(&new_cfg);
        new_cfg.c_cflag &= ~CSIZE;
    
        switch(baud_rate)
        {
            case 2400:
            {
                speed = B2400;
            }
            break;
            case 4800:
                    {
                            speed = B4800;
                    }
            break;
            case 9600:
                    {
                            speed = B9600;
                    }
            break;
            case 19200:
                    {
                            speed = B19200;
                    }
            break;
            case 38400:
                    {
                            speed = B38400;
                    }
            break;
            case 115200:
                    {
                            speed = B115200;
                    }
            break;
        }
        cfsetispeed(&new_cfg,speed);
        cfsetospeed(&new_cfg,speed);
        
        switch(data_bits)
        {
            case 7:
            {
                new_cfg.c_cflag |= CS7;
            }
            break;
            case 8:
            {
                new_cfg.c_cflag |= CS8;
            }
            break;
        }
        
        switch(parity)
        {
            default:
            case 'n':
            case 'N':
            {
                new_cfg.c_cflag |= ~PARENB;
                new_cfg.c_iflag |= ~INPCK;
            }
            break;
            case 'o':
            case 'O':
            {
                new_cfg.c_cflag |= (PARODD | PARENB);
                new_cfg.c_iflag |= INPCK;
            }
            break;
            case 'e':
            case 'E':
            {
                new_cfg.c_cflag |= PARENB;
                new_cfg.c_cflag &= ~PARODD;
                new_cfg.c_iflag |= INPCK;
            }
            break;
            case 's':
            case 'S':
            {
                new_cfg.c_cflag &= ~PARENB;
                new_cfg.c_cflag &= ~CSTOPB;
            }
            break;
        }
        
        switch(stop_bits)
        {
            default:
            case 1:
            {
                new_cfg.c_cflag &= ~CSTOPB;
            }
            break;
            case 2:
            {
                new_cfg.c_cflag |= CSTOPB;
            }
            break;
        }
        
        new_cfg.c_cc[VTIME] = 0;
        new_cfg.c_cc[VMIN] = 1;
    
        tcflush(fd,TCIFLUSH);
        
        if(tcsetattr(fd,TCSANOW,&new_cfg)) != 0)
        {
            perror("tcsetattr");
            return -1;
    `    }
        return 0;
    }
    • 串口使用:

    1. 打开串口

    int open_port(int com_port)
    {
        int fd;
    #if(COM_TYPE == GNR_COM)
        char *dev[] = {"/dev/ttyS0","/dev/ttyS1","/dev/ttyS2"};
    #else
        char *dev[] = {"/dev/ttyUSB0","/dev/ttyUSB1","/dev/ttyUSB2"};
    #endif
        if((com_port < 0) || (com_port > MAX_COM_NUM))
        {
            return -1;
        }
            
        fd = open(dev[com_port - 1].O_RDWR|O_NOCTTY|O_NDELAY);
        if(fd < 0)
        {
            perror("open serial port");
            return -1;
        }
            
        if(fcntl(fd,F_SETFL,0) < 0)
        {
            perror("fcntl F_SETFL\n");
        }
            
        if(isatty(fd) == 0)
        {
            perror("This is not a terminal device");
        }
        return fd;
    }

    2.  读写串口

    /*com_writer.c*/
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<sys/types.h>
    #include<sys/stat.h>
    #include<error.h>
    #include"uart_api.h"
    
    int main(void)
    {
        int fd;
        char buff[BUFFER_SIZE];
        if((fd = open_port(HOST_COM_PORT)) < 0)
        {
            perror("open_port");
            return 1;
        }
    
        if(set_com_config(fd,115200,8,'N',1) < 0)
        {
            perror("set_com_config");
            return 1;
        }
        
        do{
            printf("input some words(enter 'quit' to exit):");
            menset(buff,0,BUFFER_SIZE);
            if(fgets(buff,BUFFER_SIZE,stdin) == NULL)
            {
                perror("fgets");
                break;
            }
            write(fd,buff,strlen(buff));
        }while(strncmp(buff,"quit",4));
        close(fd);
        return 0;
    }
    /*com_reader.c*/
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<sys/types.h>
    #include<sys/stat.h>
    #include<error.h>
    #include"uart_api.h"
    
    int main(void)
    {
        int fd;
        char buff[BUFFER_SIZE];
        if((fd = open_port(TARGET_COM_PORT)) < 0)
        {
            perror("open_port");
            return 1;
        }
    
        if(set_com_config(fd,115200,8,'N',1) < 0)
        {
            perror("set_com_config");
            return 1;
        }
        
        do{
            menset(buff,0,BUFFER_SIZE);
            if(read(fd,buff,BUFFER_SIZE) > 0)
            {
               printf("the received words are : %s",buff);
            }
        }while(strncmp(buff,"quit",4));
        close(fd);
        return 0;
    }
    作者:快乐出发0220 ;Android群:151319601 ; Linux群:96394158 ;转载请注明出处 http://klcf0220.cnblogs.com/ !!!
  • 相关阅读:
    2019-9-2-win10-uwp-判断本地ip
    2018-8-10-使用-Resharper-特性
    2018-8-10-WPF-checkbox文字下掉
    2018-8-10-调试-ms-源代码
    2018-8-10-cant-found-Microsoft.VSSDK.BuildTools.15.0.26201
    2019-9-18-WPF-如何调试-binding
    2018-8-10-WPF-控件继承树
    2018-8-10-sublime-Text-正则替换
    植物大战僵尸阳光冷却地址
    cs1.6 人物地址查询
  • 原文地址:https://www.cnblogs.com/klcf0220/p/3044615.html
Copyright © 2011-2022 走看看