zoukankan      html  css  js  c++  java
  • Linux下串口编程(二)

    相关内容:

      Linux下串口编程(一)

      Linux下串口编程(二)

    1、dev_uart.c

    #include "dev_uart.h"
    
    /*******************************************************************  
    *名称:             dev_uart_open 
    *功能:             打开串口并返回串口设备文件描述  
    *入口参数:         fd      文件描述符                    port    串口号(ttyS0,ttyS1,ttyS2)  
    *出口参数:正确返回为1,错误返回为0  
    *******************************************************************/    
    int 
    dev_uart_open(int fd,char *port)
    {        
        fd = open( port, O_RDWR|O_NOCTTY|O_NDELAY);        
        if (fd<0)        
        {            
            printf("******Can't Open uart*****
    ");           
            return -1;        
        }        
        //恢复串口为阻塞状态                                      
        if(fcntl(fd, F_SETFL, 0) < 0)        
        {            
            printf("******fcntl fail*****
    ");           
            return -1;       
        }             
        else        
        {            
            printf("*****fcntl=%d******
    ",fcntl(fd, F_SETFL,0));        
        }        
        //测试是否为终端设备            
        if(0 == isatty(STDIN_FILENO))        
        {            
            printf("*****standard input is not a terminal device*****
    ");            
            return -1;        
        }        
        else        
        {           
            printf("*****isatty success!*******
    ");        
        }                      
        printf("******fd->open=%d******
    ",fd);        
        return fd;    
    } 
    
    
    
    void dev_uart_close(int fd)    
    {    
        close(fd);    
    } 
    
    
    
    int
    dev_uart_set(int fd,int uart_speed,int flow_ctrl,int databits,int stopbits,int parity)    
    {              
        int   i;                
        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("tcgetattr err");                
            return -1;         
        }              
        //设置串口输入波特率和输出波特率        
        for ( i= 0;  i < sizeof(speed_arr) / sizeof(int);  i++)        
        {            
            if  (uart_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
    ");                     
                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
    ");                         
                return -1;         
            }         
        // 设置停止位         
        switch (stopbits)        
        {              
            case 1:                        
                options.c_cflag &= ~CSTOPB; break;             
            case 2:                        
                options.c_cflag |= CSTOPB; break;            
            default:                              
                printf("Unsupported stop bits
    ");                            
                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!
    ");              
            return -1;         
        }        
        return 1;     
    }    
    
    
    int
    dev_uart_read(int fd, char *rcv_buf,int data_len)    
    {        
        int len;
        len = read(fd,rcv_buf,data_len);         
        return len; 
        
    } 
    
    
    
    
    int
    dev_uart_write(int fd, char *send_buf,int data_len)    
    {        
        int len = 0;               
        len = write(fd,send_buf,data_len);        
        return len;            
                   
    }    

    2、dev_uart.h

    #ifndef  _DEV_UART_H
    #define  _DEV_UART_H 
    //串口相关的头文件    
    #include<stdio.h>      /*标准输入输出定义*/    
    #include<stdlib.h>     /*标准函数库定义*/    
    #include<unistd.h>     /*Unix 标准函数定义*/    
    #include<sys/types.h>     
    #include<sys/stat.h>       
    #include<fcntl.h>      /*文件控制定义*/    
    #include<termios.h>    /*PPSIX 终端控制定义*/    
    #include<errno.h>      /*错误号定义*/    
    #include<string.h>              //宏定义
    
    
    
    
    int 
    dev_uart_open(int fd,char *port);
    
    void 
    dev_uart_close(int fd) ;
    
    int
    dev_uart_set(int fd,int uart_speed,int flow_ctrl,int databits,int stopbits,int parity);
    
    
    int
    dev_uart_read(int fd, char *rcv_buf,int data_len);
    
    
    int
    dev_uart_write(int fd, char *send_buf,int data_len);
    
    
    
    #endif
    View Code

    2、uart_test.c  串口测试代码

    #include "pthread.h"
    #include "dev_uart.h"
    
    
    #define TIME_DIF    2    //2秒
    #define uart_buf_SIZE 200    //接收缓冲区数据长度
    
    
    char buf123[12]         ={0x00,0x10,0x00,0x24,0x06,0x00,0x01,0x00,0x01,0x00,0x01,0x0D};    
    
    
    
    static char uart_buf[uart_buf_SIZE];      //接收缓冲区
    static volatile char  uart_cnt = 0;                 //接收缓冲计数
    static volatile int flag = 1;            
    static volatile int fd = -1;
    
    
    
    int
    uart_read_proc(char *buf,unsigned int len)
    {
        int cnt;
            
        memcpy(uart_buf+uart_cnt, buf, len);
        uart_cnt += len;
                
        if (uart_cnt == 100)
        {
             for(cnt = 0;cnt<uart_cnt;cnt++)
                {
                    printf(" %02x",uart_buf[cnt]);
                    if(cnt%20 == 19)
                        printf("
    ");
                }
                printf("
    ");
    
                memset(uart_buf , 0,sizeof(uart_buf));
                uart_cnt = 0;
                flag = 1;    
                
                return 1;
                    
            }
        
    }
    
    
    
    
    int
    uart_read(int fd)    
    {
        char buf[200];
        int iRet;
        unsigned int len;
        int i = 30;
        
        memset(uart_buf , 0,sizeof(uart_buf));
        uart_cnt = 0;
        flag = -1;
    
        
        while(i > 0)
        {
            i--;
            if(flag == -1)
            {            
                memset(buf, 0, sizeof(buf));
                len = dev_uart_read(fd, buf, 30);
                if(len > 0)
                {
                    iRet = uart_read_proc(buf,len);
                }
                return iRet;
            }
            else 
                break;
        }
    }
    
    
    int
    uart_write(int fd)
    {
        int len = 0;
    
        len = dev_uart_write(fd,buf123, sizeof(buf123));
        if(len <= 0)
        {
            printf("*******hal_uart_write err*******
    ");
            return -1;
        }
        return len;
            
    }
    
    
    /****************************************************************************
     * @brief      
     ***************************************************************************/
    int main(void)
    {
        static unsigned int time_second = 0;
            char *dev = "/dev/ttyPS1";
            int iRet = 0;
        
            printf("Line %d
    ", __LINE__);
        
          fd = dev_uart_open(fd,dev);
    
            iRet = dev_uart_set(fd,115200,0,8,1,'N');    
        
            while(1)
            {
                usleep(200000);//延时200ms
                time_t time_now = time((time_t *)NULL);
                //-->定时查询串口数据
                if ((time_now - time_second) >= TIME_DIF)
                {
                    time_second = time_now;
                    uart_write(fd);        
                    uart_read(fd);        
                }
            }
        
        return 0;
    }
    View Code

    3、Makefile

    CROSS    =    
    LIB_PWD = $(shell pwd)
    TARGET_BIN = test
    
    
    
    CPP    = $(CROSS)g++ -std=c++11
    CC    = $(CROSS)gcc
    LD    = $(CROSS)ld
    
    
    CFLAGS  += -I$(shell pwd)
    
    CFLAGS  += -Wall -g  
    LDFLAGS += -lpthread
            
            
    SRCS = $(wildcard *.c)
    OBJS = $(patsubst %.c,%.o,$(SRCS))
    %.o: %.c
        $(CPP) $(CFLAGS) -o $@ -c $< 
        
    all:$(OBJS)
        $(CPP) -o $(TARGET_BIN)  $(OBJS) $(LDFLAGS)
        find . -name "*.o"  | xargs rm -f  
        
    clean:
        find . -name "*.o"  | xargs rm -f 
    View Code

    参考文档: POSIX操作系统的串行编程指南

          Linux 下串口编程入门

  • 相关阅读:
    JNI和NDK的关系
    JNI和NDK的关系
    Android SDK结构分析
    设计模式:单例模式
    编程规范:占位符
    设计模式:工厂模式
    代码整洁之道----读书笔记
    个人编程规范
    装饰器函数
    异常处理
  • 原文地址:https://www.cnblogs.com/listxue/p/13377161.html
Copyright © 2011-2022 走看看