免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 7575 | 回复: 6
打印 上一主题 下一主题

调试一个arm串口通信程序只能发送不能接收,read函数不执行 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-08-14 13:59 |只看该作者 |倒序浏览
:em11: 调试一个arm串口通信程序只能发送不能接收,read函数不执行
我调试一个arm串口通信程序只能发送不能接收,我用的是s3c2440的cpu,用串口调试助手在pc机上调试的
当程序运行到循环里的read函数时就卡住了,不知道是什么原因啊?
我调过另外一个串口通信程序,代码基本一样,也是这个问题,但是偶尔能接收到,没找出什么原因
哪位大侠遇到过这种情况,不知道是什么原因啊,请不吝赐教

程序如下,请高人指点
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>

#define BAUDRATE B115200
#define MODEMDEVICE "/dev/s3c2410_serial0"
#define _POSIX_SOURCE 1 /* POSIX compliant source */
#define FALSE 0
#define TRUE 1

volatile int STOP=FALSE;

main()
{
int fd, res;
struct termios oldtio,newtio;
char buf[255];


printf("Start:\r\n";


fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY );
if (fd <0) {perror(MODEMDEVICE); exit(-1); }

tcgetattr(fd,&oldtio); /* save current port settings */

bzero(&newtio, sizeof(newtio));
newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD | HUPCL;
newtio.c_iflag = IGNPAR;
newtio.c_oflag = 0;
newtio.c_lflag = ICANON ;
//newtio.c_cc[VTIME] = 0; /* inter-character timer unused */
///newtio.c_cc[VMIN] = 1; /* blocking read until 5 chars received */

tcflush(fd, TCIFLUSH);
tcsetattr(fd,TCSANOW,&newtio);


printf("old.cflag=%o\t\t\tnew.cflag=%o\n\r",oldtio.c_cflag,newtio.c_cflag);
printf("old.iflag=%o\t\t\tnew.iflag=%o\n\r",oldtio.c_iflag,newtio.c_iflag);
printf("old.oflag=%o\t\t\tnew.oflag=%o\n\r",oldtio.c_oflag,newtio.c_oflag);
printf("old.lflag=%o\t\t\tnew.lflag=%o\n\r",oldtio.c_lflag,newtio.c_lflag);


while(STOP==FALSE)
{
printf("Receiving...\n\r";
fflush(stdout);
printf("fflush ok\n\r";    //这条语句能够运行,能看到这个输出
res=read(fd,buf,255);    //程序应该执行到这里就不执行了,是不是read函数的参数设置不对?
printf("read ok\n\r";     //这条语句没有运行,没看到输出
buf[res]=0;
printf("Received %d chars: %s\n\r",res-1,buf);
if(buf[0]=='@')
{
STOP=TRUE;
printf("\n\r";
}

}

tcsetattr(fd,TCSANOW,&oldtio);
return 0;

}

论坛徽章:
0
2 [报告]
发表于 2009-08-14 16:52 |只看该作者
linux下发送数据,arm板可以收到,但是数据不稳定
前面是在xp下用串口调试程序发送的数据,arm板上运行到read函数后不能执行
求解

论坛徽章:
0
3 [报告]
发表于 2009-08-14 17:24 |只看该作者
需要仔细研究下中断属性的设置。。。

论坛徽章:
0
4 [报告]
发表于 2009-08-14 20:26 |只看该作者
友善之臂提供的源代码试一下:
# include <stdio.h>
# include <stdlib.h>
# include <termio.h>
# include <unistd.h>
# include <fcntl.h>
# include <getopt.h>
# include <time.h>
# include <errno.h>
# include <string.h>
static void Error(const char *Msg)
{
fprintf (stderr, "%s\n", Msg);
fprintf (stderr, "strerror() is %s\n", strerror(errno));
exit(1);
}
static void Warning(const char *Msg)
{
fprintf (stderr, "Warning: %s\n", Msg);
}
static int SerialSpeed(const char *SpeedString)
{
int SpeedNumber = atoi(SpeedString);
# define TestSpeed(Speed) if (SpeedNumber == Speed) return B##Speed
TestSpeed(1200);
TestSpeed(2400);
TestSpeed(4800);
TestSpeed(9600);
TestSpeed(19200);
TestSpeed(38400);
TestSpeed(57600);
TestSpeed(115200);
TestSpeed(230400);
Error("Bad speed";
return -1;
}
static void PrintUsage(void)
{
fprintf(stderr, "comtest - interactive program of comm port\n";
fprintf(stderr, "press [ESC] 3 times to quit\n\n";
fprintf(stderr, "Usage: comtest [-d device] [-t tty] [-s speed] [-7] [-c] [-x] [-o] [-h]\n";
fprintf(stderr, " -7 7 bit\n";
fprintf(stderr, " -x hex mode\n";
fprintf(stderr, " -o output to stdout too\n";
fprintf(stderr, " -c stdout output use color\n";
fprintf(stderr, " -h print this help\n";
exit(-1);
}
static inline void WaitFdWriteable(int Fd)
{
fd_set WriteSetFD;
FD_ZERO(&WriteSetFD);
FD_SET(Fd, &WriteSetFD);
if (select(Fd + 1, NULL, &WriteSetFD, NULL, NULL) < 0) {
Error(strerror(errno));
}
}
int main(int argc, char **argv)
{
int CommFd, TtyFd;
struct termios TtyAttr;
struct termios BackupTtyAttr;
int DeviceSpeed = B115200;
int TtySpeed = B115200;
int ByteBits = CS8;
const char *DeviceName = "/dev/ttyS0";
const char *TtyName = "/dev/tty";
int OutputHex = 0;
int OutputToStdout = 0;
int UseColor = 0;
opterr = 0;
for (; {
int c = getopt(argc, argv, "d:s:t:7xoch");
if (c == -1)
break;
switch(c) {
case 'd':
DeviceName = optarg;
break;
case 't':
TtyName = optarg;
break;
case 's':
if (optarg[0] == 'd') {
DeviceSpeed = SerialSpeed(optarg + 1);
} else if (optarg[0] == 't') {
TtySpeed = SerialSpeed(optarg + 1);
} else
TtySpeed = DeviceSpeed = SerialSpeed(optarg);
break;
case 'o':
OutputToStdout = 1;
break;
case '7':
ByteBits = CS7;
break;
case 'x':
OutputHex = 1;
break;
case 'c':
UseColor = 1;
break;
case '?':
case 'h':
default:
PrintUsage();
}
}
if (optind != argc)
PrintUsage();
CommFd = open(DeviceName, O_RDWR, 0);
if (CommFd < 0)
Error("Unable to open device");
if (fcntl(CommFd, F_SETFL, O_NONBLOCK) < 0)
Error("Unable set to NONBLOCK mode");
memset(&TtyAttr, 0, sizeof(struct termios));
TtyAttr.c_iflag = IGNPAR;
TtyAttr.c_cflag = DeviceSpeed | HUPCL | ByteBits | CREAD | CLOCAL;
TtyAttr.c_cc[VMIN] = 1;
if (tcsetattr(CommFd, TCSANOW, &TtyAttr) < 0)
Warning("Unable to set comm port");
TtyFd = open(TtyName, O_RDWR | O_NDELAY, 0);
if (TtyFd < 0)
Error("Unable to open tty");
TtyAttr.c_cflag = TtySpeed | HUPCL | ByteBits | CREAD | CLOCAL;
if (tcgetattr(TtyFd, &BackupTtyAttr) < 0)
Error("Unable to get tty");
if (tcsetattr(TtyFd, TCSANOW, &TtyAttr) < 0)
Error("Unable to set tty");
for (;;) {
unsigned char Char = 0;
fd_set ReadSetFD;
void OutputStdChar(FILE *File) {
char Buffer[10];
int Len = sprintf(Buffer, OutputHex ? "%.2X " : "%c", Char);
fwrite(Buffer, 1, Len, File);
}
FD_ZERO(&ReadSetFD);
FD_SET(CommFd, &ReadSetFD);
FD_SET( TtyFd, &ReadSetFD);
# define max(x,y) ( ((x) >= (y)) ? (x) : (y) )
if (select(max(CommFd, TtyFd) + 1, &ReadSetFD, NULL, NULL, NULL) < 0) {
Error(strerror(errno));
}
# undef max
if (FD_ISSET(CommFd, &ReadSetFD)) {
while (read(CommFd, &Char, 1) == 1) {
WaitFdWriteable(TtyFd);
if (write(TtyFd, &Char, 1) < 0) {
Error(strerror(errno));
}
if (OutputToStdout) {
if (UseColor)
fwrite("\x1b[01;34m", 1, 8, stdout);
OutputStdChar(stdout);
if (UseColor)
fwrite("\x1b[00m", 1, 8, stdout);
fflush(stdout);
}
}
}
if (FD_ISSET(TtyFd, &ReadSetFD)) {
while (read(TtyFd, &Char, 1) == 1) {
static int EscKeyCount = 0;
WaitFdWriteable(CommFd);
if (write(CommFd, &Char, 1) < 0) {
Error(strerror(errno));
}
if (OutputToStdout) {
if (UseColor)
fwrite("\x1b[01;31m", 1, 8, stderr);
OutputStdChar(stderr);
if (UseColor)
fwrite("\x1b[00m", 1, 8, stderr);
fflush(stderr);
}
if (Char == '\x1b') {
EscKeyCount ++;
if (EscKeyCount >= 3)
goto ExitLabel;
} else
EscKeyCount = 0;
}
}
}
ExitLabel:
if (tcsetattr(TtyFd, TCSANOW, &BackupTtyAttr) < 0)
Error("Unable to set tty");
return 0;
}

论坛徽章:
0
5 [报告]
发表于 2009-08-15 08:53 |只看该作者
好的,继续实验

论坛徽章:
0
6 [报告]
发表于 2009-08-19 09:58 |只看该作者

linux下基本解决了

linux下基本解决了,主要原因是pc机发送的数据末尾要加一个'\n',好比在turbo  c下从终端输入数据都要按回车才能完成输入一样
可能别的系统是要加'\r',我这边不行,只能用'\n'
下一步试试在xp下是什么原因
初学者,大家见笑了

论坛徽章:
0
7 [报告]
发表于 2012-04-12 17:57 |只看该作者
我碰到跟你一样的问题,现在我发送单字节可以,但是多字节的话就出错,原因未知
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP