Linux应用编程之串口

来源:互联网 发布:淘宝聚划算报名 编辑:程序博客网 时间:2024/06/17 00:13
  • 如何找到串口设备号
  • 串口之打开操作
  • 串口之初始化
  • 串口之发送
  • 串口之接收

如何找到串口设备号

如果你使用的是开发板搭载Linux系统进行的串口编程,你可以通过原理图进行查看 
如果你电脑安装的linux系统,那么插上串口,通过dmesg命令进行查看 
本文例子使用/dev/ttyS0


串口之打开操作

#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>int main(){    int fd;    char *com = "/dev/ttyS0";    if((fd = open(com,O_RDWR|O_CREAT,0777))<0){        //fd返回-1打开失败    }else{        //打开成功    }    return 0;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

串口之初始化

  • 了解termio结构体
  • 常用初始化函数 
    • tcgetattr函数
    • cfgetispeed函数
    • cfgetospeed函数
    • cfsetispeed函数
    • cfsetospeed函数
    • tcflush函数
    • tcsetattr函数
  • 初始化步骤 
    • 读取当前参数
    • 修改参数
    • 配置参数

了解termio结构体

struct termios{           tcflag_t c_iflag;//输入模式           tcflag_t c_oflag;//输出模式           tcflag_t c_cflag;//控制模式           tcflag_t c_lflag;//本地模式           cc_t     c_cc[NCCS];//控制字符};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

c_iflag参数如下:

键值说明IGNBRK忽略BREAK键输入BRKINT如果设置了IGNBRK,BREAK键输入将被忽略IGNPAR忽略奇偶校验错误PARMRK标识奇偶校验错误INPCK允许输入奇偶校验ISTRIP去除字符的第8个比特INLCR将输入的NL(换行)转换成CR(回车)IGNCR忽略输入的回车ICRNL将输入的回车转化成换行(如果IGNCR未设置的情况下)IUCLC将输入的大写字符转换成小写字符(非POSIX)IXON允许输出时对XON/XOFF流进行控制IXANY输入任何字符将重启停止的输出IXOFF允许输入时对XON/XOFF流进行控制IMAXBEL当输入队列满的时候开始响铃

c_oflag参数如下:

键值说明OPOST处理后输出OLCUC将输入的小写字符转换成大写字符(非POSIX)ONLCR将输入的NL(换行)转换成CR(回车)及NL(换行)OCRNL将输入的CR(回车)转换成NL(换行)ONOCR第一行不输出回车符ONLRET不输出回车符OFILL发送填充字符以延迟终端输出OFDEL以ASCII码的DEL作为填充字符,如果未设置该参数,填充字符为NULNLDLY换行输出延时,可以取NL0(不延迟)或NL1(延迟0.1s)CRDLY回车延迟,取值范围为:CR0、CR1、CR2和 CR3TABDLY水平制表符输出延迟,取值范围为:TAB0、TAB1、TAB2和TAB3BSDLY空格输出延迟,可以取BS0或BS1VTDLY垂直制表符输出延迟,可以取VT0或VT1FFDLY换页延迟,可以取FF0或FF1

c_cflag参数如下:

参数说明CBAUD波特率(4+1位)(非POSIX)CBAUDEX附加波特率(1位)(非POSIX)CSIZE字符长度,取值范围为CS5、CS6、CS7或CS8CSTOPB设置两个停止位CREAD使用接收器PARENB使用奇偶校验PARODD对输入使用奇偶校验,对输出使用偶校验HUPCL关闭设备时挂起CLOCAL忽略调制解调器线路状态CRTSCTS使用RTS/CTS流控制

c_lflag参数如下:

参数说明ISIG当输入INTR、QUIT、SUSP或DSUSP时,产生相应的信号ICANON使用标准输入模式XCASE在ICANON和XCASE同时设置的情况下,终端只使用大写。ECHO显示输入字符ECHOE如果ICANON同时设置,ERASE将删除输入的字符ECHOK如果ICANON同时设置,KILL将删除当前行ECHONL如果ICANON同时设置,即使ECHO没有设置依然显示换行符ECHOPRT如果ECHO和ICANON同时设置,将删除打印出的字符(非POSIX)TOSTOP向后台输出发送SIGTTOU信号

c_cc[NCCS]参数如下:

宏说明宏说明VINTRInterrupt字符VEOL附加的End-of-file字符VQUITQuit字符VTIME非规范模式读取时的超时时间VERASEErase字符VSTOPStop字符VKILLKill字符VSTARTStart字符VEOFEnd-of-file字符VSUSPSuspend字符VMIN非规范模式读取时的最小字符数  

常用初始化函数  

  • tcgetattr函数
  • cfgetispeed函数
  • cfgetospeed函数
  • cfsetispeed函数
  • cfsetospeed函数
  • tcflush函数
  • tcsetattr函数
读取当前参数函数:int tcgetattr(int fd,struct termios *termios_p)    fd:open操作后返回的文件句柄    *termios_p:为前面介绍的结构体    初始化开始前调用这个函数.获取当前波特率函数:int speed_t cfgetispeed(const struct termios *termios_p)int speed_t cfgetospeed(const struct termios *termios_p)    *termios_p:为前面介绍的结构体    成功返回0,失败返回-1波特率设置函数:int cfsetispeed(struct termios *termios_p,speed_t speed)int cfsetospeed(struct termios *termios_p,speed_t speed)    *termios_p:为前面介绍的结构体    speed:波特率,常用B2400,B4800,B9600,B115200,B460800    成功返回0,失败返回-1清空buffer数据函数:int tcflush(int fd,int queue_selector)    queue_selector:有三个常用宏定义                    TCIFLUSH:清空正读的数据,且不会读出                    TCOFLUSH:清空正写入的数据,且不会发送到终端                    TCIOFLUSH:清空所有正在发生的I/O数据.    成功返回0,失败返回-1设置串口参数函数:int tcsetattr(int fd,int optional_actions,cons struct termios *termios_p)    optional_actions:有三个常用宏定义                    TCSANOW:不等数据传输完毕,立即改变属性                    TCSADRAIN:等所有数据传输完毕,再改变属性                    TCSAFLUSH:清空输入输出缓冲区才改变属性    成功返回0,失败返回-1                
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

初始化设置代码如下:

/***fd:文件句柄*nSpeed:波特率*nBits:数据位*nEvent:奇偶校验*nStop:停止位/int set_opt(int fd,int nSpeed,int nBits,int nEvent ,int nStop){        struct termios newtio,oldtio;        if(tcgetattr(fd,&oldtio)!=0){            //错误            return -1;        }        bzero(&newtio,sizeof(newtio));        newtio.c_cflag |=  CLOCAL|CREAD;        newtio.c_cflag &= ~CSIZE;        switch(nBits){//设置数据位            case 7:                    newtio.c_cflag |= CS7;                    break;            case 8:                    newtio.c_cflag |= CS8;                          break;        }        switch(nEvent){//设置奇偶校验位            case 'O':                newtio.c_cflag |=PARENB;                newtio.c_cflag |=PARODD;                newtio.c_iflag |=(INPCK|ISTRIP);                break;            case 'E':                newtio.c_iflag |=(INPCK|ISTRIP);                newtio.c_cflag |=PARENB;                newtio.c_cflag &=~PARODD;                break;            case 'N':                newtio.c_cflag &=~PARENB;                break;        }        switch(nSpeed){            case 2400:                cfsetispeed(&newtio,B2400);                cfsetospeed(&newtio,B2400);                break;            case 4800:                cfsetispeed(&newtio,B4800);                cfsetospeed(&newtio,B4800);                break;            case 9600:                cfsetispeed(&newtio,B9600);                cfsetospeed(&newtio,B9600);                break;            case 115200:                cfsetispeed(&newtio,B115200);                cfsetospeed(&newtio,B115200);                break;            case 460800:                cfsetispeed(&newtio,B460800);                cfsetospeed(&newtio,B460800);                break;            default:                cfsetispeed(&newtio,B9600);                cfsetospeed(&newtio,B9600);                break;        }        if(nStop==1){//停止位设置            newtio.c_cflag &= ~CSTOPB;        }else if(nStop==2){            newtio.c_cflag |= CSTOPB;        }        newtio.c_cc[VTIME] = 0;        newtio.c_cc[VMIN] = 0;        tcflush(fd,TCIFLUSH);        if((tcsetttr(fd,TCSANOW,&newtio))!=0){            //com set error            return -1;        }        return 0;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82

串口之发送与接收

#include <stdio.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <termios.h>#include <errno.h>int set_opt(int,int,int,char,int);void main(){    int fd;    char *com= "/dev/ttyS0";    char *buffer = "hello world!\n";    if((fd = open(com, O_RDWR|O_NOCTTY|O_NDELAY))<0){        printf("open %s is failed",com);    }    else{        printf("open %s is success\n",com);        set_opt(fd, 115200, 8, 'N', 1);         wr_static = write(fd,buffer, strlen(buffer));        //读取差不多一样的这里就不介绍了            if(wr_static<0)                printf("write failed\n");            else                printf("wr_static is %d\n",wr_static);            close(fd);       }}int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop){    struct termios newtio,oldtio;    if  ( tcgetattr( fd,&oldtio)  !=  0) {         return -1;//读取参数错误    }    bzero( &newtio, sizeof( newtio ) );    newtio.c_cflag  |=  CLOCAL | CREAD;    newtio.c_cflag &= ~CSIZE;    switch( nBits )    {    case 7:        newtio.c_cflag |= CS7;        break;    case 8:        newtio.c_cflag |= CS8;        break;    }    switch( nEvent )    {    case 'O':        newtio.c_cflag |= PARENB;        newtio.c_cflag |= PARODD;        newtio.c_iflag |= (INPCK | ISTRIP);        break;    case 'E':         newtio.c_iflag |= (INPCK | ISTRIP);        newtio.c_cflag |= PARENB;        newtio.c_cflag &= ~PARODD;        break;    case 'N':          newtio.c_cflag &= ~PARENB;        break;    }    switch( nSpeed )    {    case 2400:        cfsetispeed(&newtio, B2400);        cfsetospeed(&newtio, B2400);        break;    case 4800:        cfsetispeed(&newtio, B4800);        cfsetospeed(&newtio, B4800);        break;    case 9600:        cfsetispeed(&newtio, B9600);        cfsetospeed(&newtio, B9600);        break;    case 115200:        cfsetispeed(&newtio, B115200);        cfsetospeed(&newtio, B115200);        break;    case 460800:        cfsetispeed(&newtio, B460800);        cfsetospeed(&newtio, B460800);        break;    default:        cfsetispeed(&newtio, B9600);        cfsetospeed(&newtio, B9600);        break;    }    if( nStop == 1 )        newtio.c_cflag &=  ~CSTOPB;    else if ( nStop == 2 )    newtio.c_cflag |=  CSTOPB;    newtio.c_cc[VTIME]  = 0;    newtio.c_cc[VMIN] = 0;    tcflush(fd,TCIFLUSH);    if((tcsetattr(fd,TCSANOW,&newtio))!=0)    {        perror("com set error");        return -1;    }    return 0;}
原创粉丝点击