串口问题setup serialport bad file descriptor

是大柚子呀 2020-12-24 02:28:04
[显示setup serialport 1:bad file descriptor哪里错了啊][
#include "serialPort.h"
#include <string.h>
#include <sys/ioctl.h>
using namespace std;
serialPort::serialPort()
{
fd = -1;
}
bool serialPort::OpenPort(const char* dev)
{

char* _dev = new char[32];
strcpy(_dev, dev);
fd = open(_dev, O_RDWR| O_NOCTTY | O_NDELAY ); //| O_NOCTTY | O_NDELAY
if (-1 == fd)
{
perror("Can't Open Serial Port");
return false;
}

int DTR_flag;
DTR_flag = TIOCM_DTR;
ioctl(fd, TIOCMBIS, &DTR_flag);//Set RTS pin
return true;

}
int serialPort::setup(int speed, int flow_ctrl, int databits, int stopbits, int parity)
{

int i;
int status;
struct termios options;
/*tcgetattr(fd,&options)得到与fd指向对象的相关参数,并将它们保存于options,该函数还可以测试配置是否正确,该串口是否可用等。若调用成功,函数返回值为0,若调用失败,函数返回值为1.
*/
if (tcgetattr(fd, &options) != 0)
{
perror("SetupSerial 1");
return(false);
}
int speed_arr[14] = { B38400, B19200, B9600, B4800, B2400, B1200, B300,
B38400, B19200, B9600, B4800, B2400, B1200, B300, };
int name_arr[14] = { 38400, 19200, 9600, 4800, 2400, 1200, 300, 38400,
19200, 9600, 4800, 2400, 1200, 300, };
//设置串口输入波特率和输出波特率
for (i = 0; i < sizeof(speed_arr) / sizeof(int); i++)
{
if (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:
fprintf(stderr, "Unsupported data size\n");
return (false);
}
//设置校验位
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;// INPCK:打开输入奇偶校验
break;
case 's':
case 'S': //设置为空格
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
break;
default:
fprintf(stderr, "Unsupported parity\n");
return (false);
}
// 设置停止位
switch (stopbits)
{
case 1:
options.c_cflag &= ~CSTOPB; break;
case 2:
options.c_cflag |= CSTOPB; break;
default:
fprintf(stderr, "Unsupported stop bits\n");
return (false);
}

//修改输出模式,原始数据输出
options.c_oflag &= ~OPOST;// OPOST:执行输出处理;

options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);// 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)//tcsetattr函数用于设置终端的相关参数
{
perror("com set error!\n");
return (false);
}
return (true);
}

int serialPort::readBuffer(unsigned char *buffer, int size)
{
return read(fd, buffer, size);
}
int serialPort::writeBuffer(unsigned char *buffer, int size)
{
return write(fd, buffer, size);
}
uint8_t serialPort::getchar()
{
uint8_t t;
read(fd, &t, 1);
return t;
}
void serialPort::ClosePort()
{
close(fd);
}

]
...全文
2497 点赞 收藏 1
写回复
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
Happy_Enger 2020-12-25
打印一下你的FD,看看是不是有问题
回复
相关推荐
发帖
CPU和硬件区
创建于2012-11-23

1009

社区成员

Linux /Unix kernel支持不同的硬件体系,X86, ARM, MIPS, 等等
申请成为版主
帖子事件
创建了帖子
2020-12-24 02:28
社区公告
暂无公告