linux下串口常规设置参考(C实现)

结构体成员

设置串口中最基本的包括波特率设置,校验位和停止位设置。在linux环境下,串口的设置主要是设置struct termios结构体的各成员值,如下所示:

 struct termio
  {   
     unsigned short c_iflag; /* 输入模式标志 */
     unsigned short c_oflag; /* 输出模式标志 */
     unsigned short c_cflag; /* 控制模式标志*/
     unsigned short c_lflag; /*本地模式标志 */
     unsigned char c_line; /* line discipline */
     unsigned char c_cc[NCC]; /* control characters */
  };

在这个结构中最为重要的是c_cflag,通过对它的赋值,用户可以设置波特率、字符大小、 数据位、停止位、奇偶校验位和硬件流控等。另外c_iflagc_cc 也是比较常用的标志。在 此主要对这3 个成员进行详细说明。

c_cflag

宏名含义
CBAUD波特率的位掩码
B00波特率(放弃DTR)
B18002400波特率
B48004800波特率
B96009600波特率
B1920019200波特率
B3840038400波特率
B5760057600波特率
B115200115200波特率
EXTA外部时钟率
EXTB外部时钟率
CSIZE数据位的位掩码
CS55个数据位
CS66个数据位
CS77个数据位
CS88个数据位
CSTOPB2个停止位(不设则是1个停止位)
CREAD接收使能
PARENB校验位使能
PARODD使用奇校验而不使用偶校验
HUPCL最后关闭时挂线(放弃DTR)
CLOCAL本地连接(不改变端口所有者)
LOBLK块作业控制输出
CNET_CTSRTS硬件流控制使能

c_iflag

宏名c_iflag支持的常量名称
INPCK奇偶校验使能
IGNPAR忽略奇偶校验错误
PARMRK奇偶校验错误掩码
ISTRIP除去奇偶校验位
IXON启动出口硬件流控
IXOFF启动入口软件流控
IXANY允许字符重新启动流控
IGNBRK忽略中断情况
BRKINT当发生中断时发送SIGINT信号
INLCR将NL映射到CR
IGNCR忽略CR
ICRNL将CR映射到NL
IUCLC将高位情况映射到低位情况
IMAXBEL当输入太长时回复ECHO

c_cc支持的常量名称 

宏名支持的常量名称
VINTR中断控制,对应键为CTRL+C
VQUIT退出操作,对应键为CRTL+Z
VERASE删除操作,对应键为Backspace(BS)
VKILL删除行,对应键为CTRL+U
VEOF位于文件结尾,对应键为CTRL+D
VEOL位于行尾,对应键为Carriage
VEOL2位于第二行尾,对应键为Line
VMIN指定了最少读取的字符数
VTIME指定了读取每个字符的等待时间

串口控制函数

函数名功能
Tcgetattr取属性(termios结构)
Tcsetattr设置属性(termios结构)
cfgetispeed得到输入速度
cfgetospeed得到输出速度
cfsetispeed设置输入速度
cfsetospeed设置输出速度
Tcdrain等待所有输出都被传输
tcflow挂起传输或接收
tcflush刷清未决输入和/或输出
Tcsendbreak送BREAK字符
tcgetpgrp得到前台进程组ID
tcsetpgrp设置前台进程组ID

常用串口属性的设置方法

设置流控制

 termios_new.c_cflag &= ~CRTSCTS; //不使用流控制
 ​
 termios_new.c_cflag |= CRTSCTS; //使用硬件流控制
 ​
 termios_new.c_iflag |= IXON|IXOFF|IXANY; //使用软件流控制

屏蔽字符大小位

 termios_new.c_cflag &= ~CSIZE;

设置数据位大小

 termios_new.c_cflag |= CS8; //使用8位数据位
 ​
 termios_new.c_cflag |= CS7; //使用7位数据位
 ​
 termios_new.c_cflag |= CS6; //使用6位数据位
 ​
 termios_new.c_cflag |= CS5; //使用5位数据位

设置奇偶校验方式

 termios_new.c_cflag &= ~PARENB; //无奇偶校验
 ​
 termios_new.c_cflag |= PARENB; //奇校验
 ​
 termios_new.c_cflag &= ~PARODD;
 ​
 termios_new.c_cflag |= PARENB; //偶校验
 ​
 termios_new.c_cflag &= ~PARODD;

停止位

 termios_new.c_cflag |= CSTOPB; //2位停止位
 ​
 termios_new.c_cflag &= ~CSTOPB; //1位停止位

输出模式

 termios_new.c_cflag &= ~OPOST; //原始数据(RAW)输出

控制字符

 termios_new.c_cc[VMIN] = 1; //读取字符的最小数量
 ​
 termios_new.c_cc[VTIME] = 1; //读取第一个字符的等待时间

实例

 
#include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <termios.h>
 #include <sys/types.h>
 #include <errno.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 ​
 typedef unsigned char uint8_t;
 typedef unsigned int uint32_t;
 struct env_info {
     uint8_t head[3];  //标识位st
     uint8_t type;     //数据类型
     uint8_t snum;     //房间编号
     uint8_t temp[2];  //温度
     uint8_t hum[2];   //湿度
     uint8_t x;        //三轴信息
     uint8_t y; 
     uint8_t z;
     uint32_t ill;     //光照
     uint32_t bet;     //电池电量
     uint32_t adc;     //电位器信息
 };
 int init_usb()                                 
 {                                              
     struct termios options;                    
 ​
     //打开串口设备                             
     int fd_uart = open("/dev/ttyUSB0", O_RDWR);  
 ​
     printf("fd_uart = %d\n",fd_uart);
     if(fd_uart < 0){                           
         perror("open err");                    
         return -1;                             
     }                                          
 ​
     //设置串口属性                             
     tcgetattr(fd_uart, &options);           //取属性(termios结构)
     //控制模式标志      
     options.c_cflag |= ( CLOCAL | CREAD );  //(本地连接(不改变端口所有者)|接收使能)
     options.c_cflag &= ~CSIZE;              //屏蔽字符大小位 
     options.c_cflag &= ~CRTSCTS;            //不使用流控制 
     options.c_cflag |= CS8;                 //8个数据位 
     options.c_cflag &= ~CSTOPB;             //~1位停止位
     options.c_iflag |= IGNPAR;              //忽略奇偶校验错误   
     options.c_iflag &= ~(ICRNL | IXON);     //~(将CR映射到NL|启动出口硬件流控) 
     options.c_oflag = 0;                    //输出模式标志  
     options.c_lflag = 0;                    //本地模式标志  
 ​
     cfsetispeed(&options, B115200);         //设置输入速度,115200波特率       
     cfsetospeed(&options, B115200);         //设置输出速度,115200波特率      
     tcsetattr(fd_uart, TCSANOW, &options);  //设置属性(termios结构)   
 ​
     return fd_uart;                                  
 }
 int main(int argc, char *argv[])
 {
     int fd_uart;
     while(1)
     {
         fd_uart = init_usb();
         if(fd_uart > 0){
             break;
         }
     }
     struct env_info options;
     struct env_info *pmsg = &options;
     char action = 0x83;
     while(1)
     {
         read(fd_uart,pmsg,sizeof(struct env_info));
         printf("温度:%d\n",pmsg->temp[0]);
         printf("湿度:%d\n",pmsg->hum[0]);
         printf("x:%d\n",pmsg->x);
         printf("y:%d\n",pmsg->y);
         printf("z:%d\n",pmsg->z);
         printf("光照强度:%u\n",pmsg->ill);
         printf("电池电量:%u\n",pmsg->bet);
         printf("电位器:%u\n",pmsg->adc);
         write(fd_uart,&action,sizeof(action));
         sleep(1);
     }
     return 0;
 }

参考地址

参考地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值