主题 : ARM串口通信求助 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 108165
精华: 0
发帖: 5
金钱: 25 两
威望: 5 点
综合积分: 10 分
注册时间: 2014-09-17
最后登录: 2015-05-14
楼主  发表于: 2014-09-27 19:55

 ARM串口通信求助

ARM与pc机进行串口通信时出了一些问题,ARM上也是Linux系统,pc机上Linux系统是用虚拟机装的,ARM发,PC收
ARM上写串口程序程序:
#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include<errno.h>
#Include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<termios.h>
#include<stdlib.h>
int main(void)
{
      int fd;
      int nwrite,i;
     char buff[]="hello\n";
     //打开串口
     if((fd=open_pport(1))<0){
              perror("open_port error");
              return;
      }
      //设置串口
      if((i=set_opt(fd,115200,8,'N',1))<0){
              perror("set_opt error");
              return;
       }
       printf("fd=%d\n",fd);
      //向串口写入字符串
      nwrite=write(fd,buff,8);
      printf("nwrite=%d\n",nwrite);
      close(fd);
      return;
}


linux读串口程序:

#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include<errno.h>
#Include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<termios.h>
#include<stdlib.h>
int main(void)
{
      int fd;
      int nread,i;
     char buff[8];
     //打开串口
     if((fd=open_pport(1))<0){
              perror("open_port error");
              return;
      }
      //设置串口
      if((i=set_opt(fd,115200,8,'N',1))<0){
              perror("set_opt error");
              return;
       }
      //利用select函数来实现多个串口的读写
      FD_ZERO(&rd);
      FD_SET(fd,&rd);
      while(FD_ISSET(fd,&rd)){
      if(select(fd+1,&rd,NULL,NULL,NULL)<0)
                    perror("select");
      else{
                    while((nread=read(fd,buff,8))>0)
                    {
                              printf("nread=%d,%s\n",nread,buff);
                    }
      }
      close(fd);
      return;
}

  
  

其中open_port和set_port分别为:
set_port:
int set_opt(int fd,int nSpeed,int nBits,charnEvent,int nStop)
{
  //fd:指定的串口,nSpeed:波特率,nBits:字符大小,nEvent:奇偶校验,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;//7个数据位
              break;
       case 8:
              newtio.c_cflag|=CS8;//8个数据位
              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;//CSTOPB不设置为2,设置1
              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;
}
open_port:
int open_port(int fd,int comport)
{
              char *dev[]={“/dev/ttyS0”,”/dev/ttyS1”,”/dev/ttyS2”};
              long vdisable;
              if(comport==1)//串口1
              {            fd=open(“/dev/ttyS0”,O_RDWR|O_NOCTTY|O_NDELAY);
                            if(-1==fd){
                                   perror(“Can’topen serial port”);
                                   return -1;
                            }
              }
              if(comport==2)//串口2
              {            fd=open(“/dev/ttyS1”,O_RDWR|O_NOCTTY|O_NDELAY);
                            if(-1==fd){
                                   perror(“Can’topen serial port”);
                                   return -1;
                            }
              }
              if(comport==3)//串口3
              {            fd=open(“/dev/ttyS2”,O_RDWR|O_NOCTTY|O_NDELAY);
                            if(-1==fd){
                                   perror(“Can’topen serial port”);
                                   return -1;
                            }
              }
//恢复串口为阻塞状态
              if(fcntl(fd,F_SETFL,0)<0)
                            printf(“fcntlfailed!\n”);
              else
                            printf(“fcntl=%d\n”,fcntl(fd,F_SETFL,0));
//测试是否为终端设备
              if(isatty(STDIN_FILENO)==0)
                            printf(“standardinput is not a terminal device\n”);
              else
                            printf(“isatty success\n”);
              printf(“fd-open=%d\n”,fd);
              return fd;
}

问题是:Linux系统是用虚拟机装的,为ubuntu12.04,ARM板为micro2440,由ARM发送的“hello\n”用xp下串口助手可以接收到,但是Linux系统运行读串口程序时,提示set down(串口设置的最后一个printf语句)之后就没有下文了,也没有显示也没退出程序,请问这是什么原因造成的?应如何修改?
[ 此帖被wxl_zyz在2014-09-27 20:17重新编辑 ]