zoukankan      html  css  js  c++  java
  • UART 串口示例代码

    /* uart_tx.c */
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <errno.h>
    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <getopt.h>
    #include <termios.h>
    
    #define TEST_LEN (1024 * 400)
    static char *dev_name = "/dev/ttyS2";
    static int baud_rate = 9600;
    static struct option opts[] = {
        {"device", required_argument, NULL, 'd'},
        {"baud", required_argument, NULL, 'b'},
        {"help", no_argument, NULL, 'h'},
    };
    
    static void parse_cmd(int argc, char *argv[])
    {
        int ch;
    
        while ((ch = getopt_long(argc, argv, "d:b:l:h", opts, NULL)) != -1) {
            switch (ch) {
            case 'd':
                //printf("dev_name: %s
    ", optarg);
                dev_name = optarg;
                break;
            case 'b':
                //printf("baud_rate: %s
    ", optarg);
                baud_rate = atoi(optarg);
                break;
            case 'h':
                printf("Usage: %s -d dev_name -b baud_rate
    ", argv[0]);
                printf("like:
    ");
                printf("	 %s -d /dev/ttyS2
    ", argv[0]);
                printf("	 %s --device /dev/ttyS2 -b 9600
    ", argv[0]);
                break;
            default:
                printf("Unknown option or invalid format!
    ");
                printf("Pls: %s --help for more info
    ", argv[0]);
                break;
            }
        }
    }
    
    int set_serial(int fd, int baud_rate, int nBits, char nEvent, int nStop)
    {
        struct termios tty_cfg;
    
        memset(&tty_cfg, 0, sizeof(tty_cfg));
        tty_cfg.c_cflag |= (CLOCAL|CREAD); /* CREAD 开启串行数据接收,CLOCAL并打开本地连接模式 */
        tty_cfg.c_cflag &= ~CSIZE; /* 设置数据位 */
    
        switch(baud_rate) {
        case 2400:
            cfsetispeed(&tty_cfg, B2400);
            cfsetospeed(&tty_cfg, B2400);
            break;
        case 4800:
            cfsetispeed(&tty_cfg, B4800);
            cfsetospeed(&tty_cfg, B4800);
            break;
        case 9600:
            cfsetispeed(&tty_cfg, B9600);
            cfsetospeed(&tty_cfg, B9600);
            break;
        case 115200:
            cfsetispeed(&tty_cfg, B115200);
            cfsetospeed(&tty_cfg, B115200);
            break;
        case 460800:
            cfsetispeed(&tty_cfg, B460800);
            cfsetospeed(&tty_cfg, B460800);
            break;
        default:
            cfsetispeed(&tty_cfg, B9600);
            cfsetospeed(&tty_cfg, B9600);
            break;
        }
    
        switch(nBits) {
        case 7:
            tty_cfg.c_cflag |= CS7;
            break;
        case 8:
            tty_cfg.c_cflag |= CS8;
            break;
        }
    
        switch(nEvent) {
        case '0':  /* 奇校验 */
            tty_cfg.c_cflag |= PARENB; /* 开启奇偶校验 */
            tty_cfg.c_iflag |= (INPCK | ISTRIP); /*INPCK打开输入奇偶校验;ISTRIP去除字符的第八个比特  */
            tty_cfg.c_cflag |= PARODD; /*启用奇校验(默认为偶校验)*/
            break;
        case 'E': /*偶校验*/
            tty_cfg.c_cflag |= PARENB; /*开启奇偶校验  */
            tty_cfg.c_iflag |= ( INPCK | ISTRIP); /*打开输入奇偶校验并去除字符第八个比特*/
            tty_cfg.c_cflag &= ~PARODD; /*启用偶校验*/
            break;
        case 'N': /*无奇偶校验*/
            tty_cfg.c_cflag &= ~PARENB;
            break;
        }
    
        /* 设置停止位;若停止位为1,则清除CSTOPB,若停止位为2,则激活CSTOPB */
        if(nStop == 1)
            tty_cfg.c_cflag &= ~CSTOPB; /*默认为一位停止位; */
        else if( nStop == 2)
            tty_cfg.c_cflag |= CSTOPB; /* CSTOPB表示送两位停止位 */
    
        /* flow control option */
        tty_cfg.c_cflag |= CRTSCTS;
    
        /* 设置最少字符和等待时间,对于接收字符和等待时间没有特别的要求时*/
        tty_cfg.c_cc[VTIME] = 0; /* 非规范模式读取时的超时时间;*/
        tty_cfg.c_cc[VMIN]  = 0; /* 非规范模式读取时的最小字符数*/
        tcflush(fd, TCIFLUSH); /* tcflush清空终端未完成的输入/输出请求及数据;TCIFLUSH表示清空正收到的数据,且不读取出来 */
    
        /*激活配置使其生效*/
        if((tcsetattr(fd, TCSANOW, &tty_cfg)) != 0) {
            printf("com set error");
            exit(1);
        }
    
        return 0;
    }
    
    char buff[TEST_LEN];
    
    int main(int argc, char *argv[])
    {
        int fd=0;
        int cnt=0;
        int sum=0;
        static int num=0;
        char *p=NULL;
    
        parse_cmd(argc, argv);
        printf("TX: dev_name=%s, baud_rate=%d
    ", dev_name, baud_rate);
    
        fd = open(dev_name,O_RDWR|O_NOCTTY|O_NDELAY);
        if(fd < 0) {
            printf("Can't Open %s
    ", dev_name);
            return -1;
        }
    
        set_serial(fd, baud_rate, 8, 'N', 1);
        sleep(1);
    
        memset(buff, 0x55, TEST_LEN);
        //printf("start send: %ds
    ", time(NULL));
        p = &buff[0];
        while(1) {
            cnt = write(fd, p, (TEST_LEN-sum));
            if(cnt < 0) {
                //sleep(1);
                continue;
            }
            sum += cnt;
            if(sum >= TEST_LEN)
                break;
            p += cnt;
            printf("TX%d: cnt = %d, sum = %d
    ", num++, cnt, sum);
        }
        
        printf("send %d: %ds
    ", sum, time(NULL));
        
        close(fd);
        return 0;
    }
    /* uart_rx.c */
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <errno.h>
    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <getopt.h>
    #include <termios.h>
    
    #define TEST_LEN (1024 * 400)
    static char *dev_name = "/dev/ttyS2";
    static int baud_rate = 9600;
    static struct option opts[] = {
        {"device", required_argument, NULL, 'd'},
        {"baud", required_argument, NULL, 'b'},
        {"help", no_argument, NULL, 'h'},
    };
    
    static void parse_cmd(int argc, char *argv[])
    {
        int ch;
    
        while ((ch = getopt_long(argc, argv, "d:b:l:h", opts, NULL)) != -1) {
            switch (ch) {
            case 'd':
                //printf("dev_name: %s
    ", optarg);
                dev_name = optarg;
                break;
            case 'b':
                //printf("baud_rate: %s
    ", optarg);
                baud_rate = atoi(optarg);
                break;
            case 'h':
                printf("Usage: %s -d dev_name -b baud_rate
    ", argv[0]);
                printf("like:
    ");
                printf("	 %s -d /dev/ttyS2
    ", argv[0]);
                printf("	 %s --device /dev/ttyS2 -b 9600
    ", argv[0]);
                break;
            default:
                printf("Unknown option or invalid format!
    ");
                printf("Pls: %s --help for more info
    ", argv[0]);
                break;
            }
        }
    }
    
    int set_serial(int fd, int baud_rate, int nBits, char nEvent, int nStop)
    {
        struct termios tty_cfg;
    
        memset(&tty_cfg, 0, sizeof(tty_cfg));
        tty_cfg.c_cflag |= (CLOCAL|CREAD); /* CREAD 开启串行数据接收,CLOCAL并打开本地连接模式 */
        tty_cfg.c_cflag &= ~CSIZE; /* 设置数据位 */
    
        switch(baud_rate) {
        case 2400:
            cfsetispeed(&tty_cfg, B2400);
            cfsetospeed(&tty_cfg, B2400);
            break;
        case 4800:
            cfsetispeed(&tty_cfg, B4800);
            cfsetospeed(&tty_cfg, B4800);
            break;
        case 9600:
            cfsetispeed(&tty_cfg, B9600);
            cfsetospeed(&tty_cfg, B9600);
            break;
        case 115200:
            cfsetispeed(&tty_cfg, B115200);
            cfsetospeed(&tty_cfg, B115200);
            break;
        case 460800:
            cfsetispeed(&tty_cfg, B460800);
            cfsetospeed(&tty_cfg, B460800);
            break;
        default:
            cfsetispeed(&tty_cfg, B9600);
            cfsetospeed(&tty_cfg, B9600);
            break;
        }
    
        switch(nBits) {
        case 7:
            tty_cfg.c_cflag |= CS7;
            break;
        case 8:
            tty_cfg.c_cflag |= CS8;
            break;
        }
    
        switch(nEvent) {
        case '0':  /* 奇校验 */
            tty_cfg.c_cflag |= PARENB; /* 开启奇偶校验 */
            tty_cfg.c_iflag |= (INPCK | ISTRIP); /*INPCK打开输入奇偶校验;ISTRIP去除字符的第八个比特  */
            tty_cfg.c_cflag |= PARODD; /*启用奇校验(默认为偶校验)*/
            break;
        case 'E': /*偶校验*/
            tty_cfg.c_cflag |= PARENB; /*开启奇偶校验  */
            tty_cfg.c_iflag |= ( INPCK | ISTRIP); /*打开输入奇偶校验并去除字符第八个比特*/
            tty_cfg.c_cflag &= ~PARODD; /*启用偶校验*/
            break;
        case 'N': /*无奇偶校验*/
            tty_cfg.c_cflag &= ~PARENB;
            break;
        }
    
        /* 设置停止位;若停止位为1,则清除CSTOPB,若停止位为2,则激活CSTOPB */
        if(nStop == 1)
            tty_cfg.c_cflag &= ~CSTOPB; /*默认为一位停止位; */
        else if( nStop == 2)
            tty_cfg.c_cflag |= CSTOPB; /* CSTOPB表示送两位停止位 */
    
        /* flow control option */
        tty_cfg.c_cflag |= CRTSCTS;
    
        /* 设置最少字符和等待时间,对于接收字符和等待时间没有特别的要求时*/
        tty_cfg.c_cc[VTIME] = 0; /* 非规范模式读取时的超时时间;*/
        tty_cfg.c_cc[VMIN]  = 0; /* 非规范模式读取时的最小字符数*/
        tcflush(fd, TCIFLUSH); /* tcflush清空终端未完成的输入/输出请求及数据;TCIFLUSH表示清空正收到的数据,且不读取出来 */
    
        /*激活配置使其生效*/
        if((tcsetattr(fd, TCSANOW, &tty_cfg)) != 0) {
            printf("com set error");
            exit(1);
        }
    
        return 0;
    }
    
    void dump_data(char *buf)
    {
        int i;
    
        for(i=0; i<TEST_LEN; i++) {
            if(i%16 == 0)
                printf("
    ");
            printf("0x%x, ", buf[i]);
        }
    }
    
    char buff[TEST_LEN];
    
    int main(int argc, char *argv[])
    {
        int fd=0;
        int cnt=0;
        int sum=0;
        static int num=0;
        char *p=NULL;
    
        parse_cmd(argc, argv);
        printf("RX: dev_name=%s, baud_rate=%d
    ", dev_name, baud_rate);
    
        fd = open(dev_name,O_RDWR|O_NOCTTY|O_NDELAY);
        if(fd < 0) {
            printf("Can't Open %s
    ", dev_name);
            return -1;
        }
    
        set_serial(fd, baud_rate, 8, 'N', 1);
        sleep(1);
    
        memset(buff, 0x0, TEST_LEN);
        //printf("start recv: %ds
    ", time(NULL));
        p = &buff[0];
        while(1) {
            cnt = read(fd, p, TEST_LEN);
            if(cnt <= 0) {
                //sleep(1);
                continue;
            }
            sum += cnt;
            if(sum >= TEST_LEN)
                break;
            p += cnt;
            printf("RX%d: cnt = %d, sum = %d
    ", num++, cnt, sum);
        }
        printf("recv %d: %ds
    ", sum, time(NULL));
        p = NULL;
        close(fd);
    
        //dump_data(buff);    
    
        return 0;
    }
  • 相关阅读:
    CBR(基于案例的推理)的产生和Roger Schank=Schank教授在他的著作中提出了以“记忆组织包"
    php 设计模式
    php 常用资源
    自然语言处理著作或期刊名称2
    北京师范大学语言学及应用语言学研究生培养方案
    !!! Analysis & Design 很好的汇总+zcl的 UML 体会
    睡眠的方法
    !!!【php100教程】
    机器翻译和自然语言信息处理专业硕士研究生培养方案
    愧薪
  • 原文地址:https://www.cnblogs.com/vedic/p/11201431.html
Copyright © 2011-2022 走看看