当前时区为 UTC + 8 小时



发表新帖 回复这个主题  [ 4 篇帖子 ] 
作者 内容
1 楼 
 文章标题 : 串口通讯程序出现了一个奇妙的bug?
帖子发表于 : 2016-02-23 14:58 

注册: 2016-01-23 16:07
帖子: 23
系统: win8&ubuntu
送出感谢: 5
接收感谢: 0 次
大神们,问一个串口通信的问题
问题是这样的,我测试的是这个程序的发送部分,将全局变量 static const char *pstr[]的赋值改为 {0, "AT"}; 将宏定义#define STR_NUM 9改为2。这时候执行程序,会出现这种情况:在g++编译程序后,首次运行程序可以成功发送出去,但是下一次运行发送会失败,如此循环下去。而且程序执行没错误,也执行发送函数 “send_data(fd, pstr[i], strlen(pstr[i]));”的语句了,但是就是没有成功发出去。这是咋回事。
大神,看在昨天就是元宵节的份上,给点思路吧,谢谢 :Love

这是源代码
#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


最后由 山雨欲来风满楼 编辑于 2016-02-23 17:25,总共编辑了 2 次

页首
 用户资料  
 
2 楼 
 文章标题 : Re: 串口通讯程序出现了一个奇妙的bug?
帖子发表于 : 2016-02-23 17:21 

注册: 2016-01-23 16:07
帖子: 23
系统: win8&ubuntu
送出感谢: 5
接收感谢: 0 次
我接下来把static const char *pstr[]的赋值改为 {0, "AT", "bt"}; 将宏定义#define STR_NUM 2改为3。 然后发现,在之前那个一次发送成功一次发送失败的循环中,重新编译,修改后的程序。
如果上次编译时成功发送的那次(也就是这一次如果执行原来的运行文件会发送失败),接收到的结果是 bt(以后每次执行都是这个结果),如果上次编译时发送失败的那次,接收到的结果是 AT bt(以后一直如是结果)。


页首
 用户资料  
 
3 楼 
 文章标题 : Re: 串口通讯程序出现了一个奇妙的bug?
帖子发表于 : 2016-02-23 19:49 
头像

注册: 2008-09-18 13:11
帖子: 2781
送出感谢: 1
接收感谢: 453
你为什么不去检查write/send_data的返回值?


页首
 用户资料  
 
4 楼 
 文章标题 : Re: 串口通讯程序出现了一个奇妙的bug?
帖子发表于 : 2016-02-24 8:26 

注册: 2016-01-23 16:07
帖子: 23
系统: win8&ubuntu
送出感谢: 5
接收感谢: 0 次
astolia 写道:
你为什么不去检查write/send_data的返回值?

将主函数do-while语句中,的
for(i = 1; i < STR_NUM; i++)
{
send_data(fd, pstr[i], strlen(pstr[i]));
}
部分修改为
for(i = 1; i < STR_NUM; i++)
{
int x = send_data(fd, pstr[i], strlen(pstr[i]));
printf( " return write= %d\n", x);
}
发现,每次执行程序都会有相同的返回值 2; :Sad


页首
 用户资料  
 
显示帖子 :  排序  
发表新帖 回复这个主题  [ 4 篇帖子 ] 

当前时区为 UTC + 8 小时


在线用户

正在浏览此版面的用户:没有注册用户 和 1 位游客


不能 在这个版面发表主题
不能 在这个版面回复主题
不能 在这个版面编辑帖子
不能 在这个版面删除帖子
不能 在这个版面提交附件

前往 :  
本站点为公益性站点,用于推广开源自由软件,由 DiaHosting VPSBudgetVM VPS 提供服务。
我们认为:软件应可免费取得,软件工具在各种语言环境下皆可使用,且不会有任何功能上的差异;
人们应有定制和修改软件的自由,且方式不受限制,只要他们自认为合适。

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
简体中文语系由 王笑宇 翻译