linux下的串口通讯程序出现了一个奇妙的bug?

我是山雨 发布于 2016/02/24 18:57
阅读 309
收藏 0
    大神们,问一个串口通信的问题
    问题是这样的,我测试的是这个程序的发送部分,将全局变量 static const char *pstr[]的赋值改为 {0, "AT"}; 将宏定义#define STR_NUM 9改为2。这时候执行程序,会出现这种情况:在g++编译程序后,首次运行程序可以成功发送出去,但是下一次运行发送会失败,如此循环下去。而且程序执行没错误,也执行发送函数 “send_data(fd, pstr[i], strlen(pstr[i]));”的语句了,但是就是没有成功发出去。这是咋回事。
    
这是源代码
#include <stdio.h> 
#include <unistd.h>
#include <syspes.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <string.h>

#define TRUE 0
#define FALSE -1
#define DEFAULT_DEV "/dev/ttyUSB0"
#define DEFAULT_BAUND B9600
#define DEFAULT_DATABIT CS8
#define DEFAULT_PAR ~PARENB
#define DEFAULT_INP ~INPCK
#define DEFAULT_STOPBIT ~CSTOPB
#define DEFAULT_INTERVAL 11

#define STR_NUM 2

//#define DEBUG
//#define FROM_ARGV

//测试模式下读取程序读取串口内容
#ifdef DEBUG 
#define READ_BUFFER_SIZE 32
#endif

//如果没有定义宏FROM_ARGV则定义pstr为指针数组,其各个元素所指向的内容为需要发送的数据
#ifndef FROM_ARGV
static const char *pstr[] = {0, "AT"};
#else //否则pstr被重新重命名为argv,程序将发送main函数接受的字符串参数
#define pstr argv
#endif


int open_dev(const char *dev_name);
int set_port(const int fd);
int send_data(const int fd, const char *buffer, const int buffer_len);
#ifdef DEBUG
int read_data(const int fd, char *read_buffer);
#endif



int main(int argc, char *argv[])
{
int fd;
int i;
char *dev_name = DEFAULT_DEV; //串口名称

#ifdef DEBUG
char read_buffer[READ_BUFFER_SIZE];
int read_buffer_size;
#endif

//打开串口
if((fd = open_dev(dev_name)) == FALSE)
{
perror("open error!");
return -1;
}

//设置串口
if(set_port(fd) == FALSE)
{
perror("set error!");
return -1;
}

//发送数据
do{
for(i = 1; i < STR_NUM; i++)
{
send_data(fd, pstr[i], strlen(pstr[i]));
}

#ifdef DEBUG
read_buffer_size = read_data(fd, read_buffer);
printf("read: %s\nsize: %d\n", read_buffer, read_buffer_size);
#endif

}while(0);

close(fd);

return 0;
}

//打开串口
int open_dev(const char *dev_name)
{
return open(dev_name, O_RDWR); //( !)另一个例程这里是O_RDWR|O_NOCTTY
}

int set_port(const int fd)
{
//设置速率
struct termios opt;
if(tcgetattr(fd, &opt) != 0)
{
return FALSE;
}
cfsetispeed(&opt, DEFAULT_BAUND);
cfsetospeed(&opt,DEFAULT_BAUND);
tcsetattr(fd,TCSANOW,&opt); // 激活新配置

//设置字符大小
opt.c_cflag &= ~CSIZE;

//设置数据位
opt.c_cflag |= DEFAULT_DATABIT;

//设置校验位
opt.c_cflag &= DEFAULT_PAR; //应该是无校验位
opt.c_iflag &= DEFAULT_INP;

//设置停止位
opt.c_cflag &= DEFAULT_STOPBIT; // 1个停止位

// 处理未接收的字符
tcflush(fd, TCIFLUSH);
// 设置等待时间和最小接收字符
opt.c_cc[VTIME] = DEFAULT_INTERVAL; /* 设置超时1.1 seconds*/ 
opt.c_cc[VMIN] = 0; /* Update the options and do it NOW*/

// 激活新配置
if(tcsetattr(fd, TCSANOW, &opt) != 0)
{
return FALSE;
}

return TRUE;
}

//发送数据 
int send_data(const int fd, const char *buffer, const int buffer_len)
{
return write(fd, buffer, buffer_len);
}

#ifdef DEBUG
//读取数据
int read_data(const int fd, char *read_buffer)
{
return read(fd, read_buffer, READ_BUFFER_SIZE);
}
#endif


问题补充:

1.   我接下来把static const char *pstr[]的赋值改为 {0, "AT", "bt"}; 将宏定义#define STR_NUM 2改为3。 然后发现,在之前那个一次发送成功一次发送失败的循环中,重新编译,修改后的程序。
如果上次编译时成功发送的那次(也就是这一次如果执行原来的运行文件会发送失败),接收到的结果是 bt(以后每次执行都是这个结果),如果上次编译时发送失败的那次,接收到的结果是 AT bt(以后一直如是结果)。

2.   用printf函数检查send_data的返回值,发现每次都是2,无论是上述的那种情况。

加载中
返回顶部
顶部