设置串口属性通常有以下几个步骤:
1. 包含头文件:
#include <stdio.h> /*标准输入输出定义*/
#include <stdlib.h> /*标准函数库定义*/
#include <unistd.h> /*Unix 标准函数定义*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h> /*文件控制定义*/
#include <termios.h> /*POSIX 终端控制定义*/
#include <errno.h> /*错误号定义*/
#include <string.h> /*字符串功能函数*/
2. termios结构体
struct termios {
tcflag_t c_iflag; /* 输入参数 */
tcflag_t c_oflag; /* 输出参数 */
tcflag_t c_cflag; /* 控制参数*/
tcflag_t c_ispeed; /* 输入波特率 */
tcflag_t c_ospeed; /* 输出波特率 */
cc_t c_line; /* 线控制 */
cc_t c_cc[NCCS]; /* 控制字符*/
};
3. 设置波特率
struct termios opt;
tcgetattr(fd, &Opt);//设置前先获取属性
tcflush(fd, TCIOFLUSH);
cfsetispeed(&stOpt, DEVICE);//cfgetispeed 获取波特率
cfsetospeed(&stOpt, DEVICE);//cfgetospeed
tcsetattr(fd,TCSANOW,&options);//设置属性
4. 配置串口属性(包括:数据位、校验位、停止位等)
struct termios options;
tcgetattr(iCom, & options);//设置前先获取
tcflush(fd,TCIFLUSH);//清空缓存数据
tcsetattr(fd,TCSANOW,&options);//设置属性
校验位:
奇校验:options.c_cflag |= (PARODD | PARENB);//
options.c_iflag |= INPCK;//
偶校验:options.c_cflag |= PARENB;
options.c_cflag &= ~PARODD;
options.c_iflag |= INPCK;
无校验:options.c_cflag &= ~PARENB;
options.c_iflag &= ~INPCK;
停止位:
1位:options.c_cflag &= ~CSTOPB;//
2位:options.c_cflag |= CSTOPB;
数据位:
7位:options.c_cflag &= ~CSIZE; //
options.c_cflag |= CS7;
8位:options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
超时:
tcflush(iCom, TCIFLUSH);//清空缓存
stOpt.c_cc[VTIME] = 120; //超时12秒
stOpt.c_cc[VMIN] = 0; //
5. 常用属性
PARODD 输入输出是奇校验
PARENB允许输出产生奇偶信息以及输入的奇偶校验。
INPCK启用输入奇偶检测
CSIZE字符长度掩码。取值为 CS5, CS6, CS7, 或 CS8。
CSTOPB设置两个停止位,而不是一个。
例:
Linux下打开串口(9600,n,8,1):
//变量声明
td_s32 g_fdCom[4] = {-1, -1, -1, -1}; //串口句柄
struct termios stOpt;
//打开设备
g_fdCom[2] = open("/dev/ttyAMA1", O_RDWR); //| O_NOCTTY | O_NDELAY| O_SYNC
tcgetattr(g_fdCom[2], &stOpt);
tcflush(g_fdCom[2], TCIFLUSH);
//设置波特率
//cfmakeraw(&stOpt);//存储属性吗?,这句话导致超时设置失效
cfsetispeed(&stOpt, B9600);//cfgetispeed 获取波特率
cfsetospeed(&stOpt, B9600);//cfgetospeed
//串口控制属性配置
/*有这个配置,其他配置省略*/
//tcsetattr(iCom, TCSANOW, &stOpt);
//stOpt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); //Input
//stOpt.c_oflag &= ~OPOST; //Output
//数据位
stOpt.c_cflag &= ~CSIZE;
stOpt.c_cflag |= CS8;
//校验位,奇校验
stOpt.c_cflag &= ~PARENB; //无校验
stOpt.c_iflag &= ~INPCK; //不启用奇偶校验检测,若采用无校验,则不启用
//stOpt.c_iflag |= INPCK;
//停止位
stOpt.c_cflag &= ~CSTOPB; //1位停止位
stOpt.c_oflag &= ~OPOST;
//超时
tcflush(g_fdCom[2], TCIFLUSH);
stOpt.c_cc[VTIME] = 150; //超时15秒
stOpt.c_cc[VMIN] = 0; //
//cfmakeraw(&stOpt);//存储属性吗?,这句话导致超时设置失效
if (tcsetattr(g_fdCom[2],TCSANOW,&stOpt) != 0)
{
printf("set parity error\n");
return -1;
}
Windows下打开串口(9600,n,8,1):
//变量声明:
HANDLE hCom; //串口句柄
DCB dcpProperty;
//打开设备
hCom = CreateFile(__T("COM1"), //COM1口
GENERIC_READ|GENERIC_WRITE, //允许读写
0, //独占方式,串口不能共享,故为零
NULL,
OPEN_EXISTING, //打开而不是创建
0,//同步方式、、FILE_FLAG_OVERLAPPED表示是异步
NULL);
if(hCom==(HANDLE)-1)
{
MessageBox(__T("打开COM失败!"));
}
else
{
MessageBox(__T("串口已打开"));
}
//设定超时
//读超时
COMMTIMEOUTS TimeOuts;
BOOL bSuccess;
TimeOuts.ReadIntervalTimeoutlinux换行按哪个键=0;
TimeOuts.ReadTotalTimeoutMultiplier=100;
TimeOuts.ReadTotalTimeoutConstant=5000;//5秒
//在读一次输入缓冲区的内容后读操作就立即返回,
//而不管是否读入了要求的字符。
//写超时
TimeOuts.WriteTotalTimeoutMultiplier=5000;
TimeOuts.WriteTotalTimeoutConstant=5000;
bSuccess = SetCommTimeouts(hCom,&TimeOuts); //设置超时
if (!bSuccess)
{
MessageBox(__T("设置超时失败"));
}
//配置串口属性
GetCommState(hCom, &dcpProperty); //未获取则不能设置
//设置波特率
dcpProperty.BaudRate = CBR_9600; //波特率
//dcpProperty.fParity = -1; //允许奇偶校验
//dcpProperty.Parity = NOPARITY; //奇校验
dcpProperty.StopBits = ONESTOPBIT ; //1位停止位
dcpProperty.ByteSize = 8; //通讯字节数
SetCommState(hCom, &dcpProperty);
//清空读写缓存
PurgeComm(g_hCom,PURGE_TXCLEAR|PURGE_RXCLEAR);
//读写操作。。
附录:
DESCRIPTION 描述
termios 函数族提供了一个常规的终端接口,用于控制非同步通信端口。
这里描述的大部分属性有一个 termios_p 类型的参数,它是指向一个 termios 结构的指针。这个结构包含了至少下列成员:
tcflag_t c_iflag; /* 输入模式 */
tcflag_t c_oflag; /* 输出模式 */
tcflag_t c_cflag; /* 控制模式 */
tcflag_t c_lflag; /* 本地模式 */
cc_t c_cc[NCCS]; /* 控制字符 */
c_iflag 标志常量:
IGNBRK
忽略输入中的 BREAK 状态。
BRKINT
如果设置了 IGNBRK,将忽略 BREAK。如果没有设置,但是设置了 BRKINT,那么 BREAK 将使得输入和输出队列被刷新,如果终端是一个前台进程组的控制终端,这个进程组中所有进程将收到 SIGINT 信号。如果既未设置 IGNBRK 也未设置 BRKINT,BREAK 将视为与 NUL 字符同义,除非设置了 PARMRK,这种情况下它被视为序列 \377 \0 \0。
IGNPAR
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论