红联Linux门户
Linux帮助

linux的串口编程问题???

发布时间:2008-12-23 00:48:40来源:红联作者:657371
我近几日在学串口的编程,按照书上的教程编写了代码,在试验过程中,通过write函数向串口发送数据没问题(我机器上有两个COM口,系统是XP,用VirtualBox装了fedora 10,用交叉线,通过XP的终端服务接收fedora所发送的数据),但是,当我用read函数接收数据时,就只接收到乱码,而且没有等待,只要一执行编译的文档,就直接运行完成,返回的是一串乱码。在这里我实在不明白是什么回事,我把代码贴出,麻烦帮我看看我是那里错了,谢谢。

#include
#include
#include
#include
#include
#include
#include
#include
#include


int fd;


struct termio
{
unsigned short c_iflag;
unsigned short c_oflag;
unsigned short c_cflag;
unsigned short c_lflag;
unsigned char c_line;
unsigned char c_cc[NCCS];

};


int open_port(int comport)
{
if(comport==1)
{
fd=open("/dev/ttyS0",O_RDWR|O_NOCTTY|O_NDELAY);
if(fd==-1)
{
perror("Can't Open Serial Port");
return(-1);
}
}
else if(comport==2)
{
fd=open("/dev/ttyS1",O_RDWR|O_NOCTTY|O_NDELAY);
if(fd==-1)
{
perror("Can't Open Serial Port");
return(-1);
}
}
else if(comport==3)
{
fd=open("/dev/ttyS2",O_RDWR|O_NOCTTY|O_NDELAY);
if(fd==-1)
{
perror("Can't Open Serial Port");
return(-1);
}
}



if(fcntl(fd,F_SETFL,0)<0)
printf("FCNTL FAILED!\n");
else
printf("fcntl=%d\n",fcntl(fd,F_SETFL,0));

if(isatty(STDIN_FILENO)==0)
printf("standard input is not a terminal device\n");
else
printf("isatty success!\n");

printf("fd-open=%d\n",fd);
return fd;

}



int set_opt(int fd,int nSpeed,int nBits,char nEvent,int nStop)//
{
struct termios newtio,oldtio;
if(tcgetattr(fd,&oldtio)!=0)
{
perror("SetupSerial 1");
return -1;
}
bzero(&newtio,sizeof(newtio));
//
newtio.c_cflag |=CLOCAL | CREAD;
newtio.c_cflag &=~CSIZE;
//
switch(nBits)
{
case 7:
newtio.c_cflag |=CS7;
break;
case 8:
newtio.c_cflag |=CS8;
break;
}
//
switch(nEvent)
{
case 'O':
newtio.c_cflag |=PARENB;
newtio.c_cflag |=PARODD;
newtio.c_iflag |=(INPCK |ISTRIP);
break;
case 'E':
newtio.c_iflag |=(INPCK | ISTRIP);
newtio.c_cflag |=PARENB;
newtio.c_cflag&=~PARODD;
break;
case 'N':
newtio.c_cflag &=~PARENB;
break;
}
//
switch(nSpeed)
{
case 2400:
cfsetispeed(&newtio,B2400);
cfsetospeed(&newtio,B2400);
break;
case 4800:
cfsetispeed(&newtio,B4800);
cfsetospeed(&newtio,B4800);
break;
case 9600:
cfsetispeed(&newtio,B9600);
cfsetospeed(&newtio,B9600);
break;
case 115200:
cfsetispeed(&newtio,B115200);
cfsetospeed(&newtio,B115200);
break;
case 460800:
cfsetispeed(&newtio,B460800);
cfsetospeed(&newtio,B460800);
break;
default:
cfsetispeed(&newtio,B9600);
cfsetospeed(&newtio,B9600);
break;
}
//
if(nStop==1)
newtio.c_cflag &=~CSTOPB;
else if(nStop==2)
newtio.c_cflag |=CSTOPB;
//
newtio.c_cc[VTIME]=0;
newtio.c_cc[VMIN]=0;
//
tcflush(fd,TCIFLUSH);
//
if((tcsetattr(fd,TCSANOW,&newtio))!=0)
{
perror("com set error");
return -1;
}
printf("set done!\n");
return 0;
}



int main()
{
int i,j;
char na[30];
fd=open_port(1);
printf("fd=%d\n",fd);
j=set_opt(fd,115200,8,'N',1);
printf("j=%d\n",j);
i=read(fd,na,31);
printf("i=%d,na=%s\n",i,na);
close(fd);
return;
}

[ 本帖最后由 657371 于 2008-12-23 00:50 编辑 ]
文章评论

共有 4 条评论

  1. kaishui 于 2009-04-15 14:08:53发表:

    如果不是开发终端之类的,只是串口传输数据,而不需要串口来处理,那么使用原始模式(Raw Mode)方式来通讯,设置方式如下:

    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /*Input*/
    options.c_oflag &= ~OPOST; /*Output*/

  2. honglin615 于 2009-04-10 12:38:13发表:

    {:2_97:}

  3. antheazhang 于 2008-12-26 13:09:20发表:

    1、na没有初始化
    2、Linux下的com1接收的数据是从哪来的?
    如果是利用交叉线从com2来的,那么main函数中需要等待com1接收缓冲区有数据到达才能读到数据。
    也就是说得利用中断或者查询的方式使程序在执行后等待数据到来。

    Linux初学者,说错了大家别笑。我只知道单片机里是用中断或查询进行串口通讯的,VC里面通过事件通知缓冲区有数据到达。

    [ 本帖最后由 antheazhang 于 2008-12-26 13:19 编辑 ]

  4. smailhere 于 2008-12-24 18:04:06发表:

    知道了!













    ------------------------------------------------------------------------------------------------------------
    签名:木门 http://www.shqibao.com