CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
山寨机中的战斗机! 程序优化工程师到底对IT界有没有贡献
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  Linux/Unix社区 >  内核及驱动程序研究区

200分送了!!!急,小弟急求各位大侠

楼主h_bin16888(木之杉)2004-12-01 19:46:31 在 Linux/Unix社区 / 内核及驱动程序研究区 提问

具体的是这样,主程序是一个死循环(在计算数据),这个时候,需要响应串口传过来的数据进行计算  
  1。需中断响应,这个程序怎么写?  
  2。我用了termios这个结构,很奇怪的是,可以接收(用信号,听说这个类似DOS的INT),但是不能够发送,不知道哪里出错了,向串口发送数据是(write(fd,buff,100))这个函数吗?有其他的函数吗?我在DOS下面用的outportb这个,直接对地址发送(outportb(0x3f8,buff,1))Linux下面的outb这个函数是否一样?  
  3,因为在中断里面需要判断当前串口是发送还是接收,需要直接读取UART寄存器的值,我在DOS下面用如下代码『  
  adr1   =   0x3f8  
  cb=inportb(adr1+2);      
            if(cb==6)  
            {  
            inportb(adr1+5);  
            continue;  
            }  
            if(cb==4)//这个时候中断接收数据  
            {  
            readserial()  
            continue;  
            }  
            if(cb==2)//这个时候中断发送数据  
            {  
            writeserial();  
            continue;  
            }  
            }   while((cb   &   1)==0);     //2  
            outportb(0x20,0x20);          
  』  
  上面这段程序在linux下面如何实现?用outb这个函数可以直接读取吗?关键问题就是如何判断串口寄存器的状态  
   
  下面这个是我写的Linux下面的第一个程序,请大家看看,错在哪里呀?只能够接收,不能够发送!!!  
  程序:  
  #include   <sys/ioctl.h>  
  #include   <sys/stat.h>  
  #include   <sys/types.h>  
  #include   <unistd.h>  
  #include   <asm/io.h>  
  #include   <errno.h>  
  #include   <sys/mman.h>  
  #include   <signal.h>  
  #include   <fcntl.h>  
  #include   <termios.h>  
   
                 
  #define   BAUDRATE   B38400              
  #define   MODEMDEVICE   "/dev/ttyS1"              
   
  void   readserial();  
  void   writeserial();  
  void   signal_handler_IO   (int   status);          
   
  main()       {                  
    int   fd,c,   res;        
    struct   termios   oldtio,newtio;      
    struct   sigaction   saio;                    
   
    char   buf[255];                  
   
          fd   =   open(MODEMDEVICE,   O_RDWR   |   O_NOCTTY   |   O_NONBLOCK);          
          if   (fd   <0)   {perror(MODEMDEVICE);   exit(-1);   }                  
     
          saio.sa_handler   =   signal_handler_IO;            
          saio.sa_mask   =   0;      
          saio.sa_flags   =   0;            
          saio.sa_restorer   =   NULL;          
          sigaction(SIGIO,&saio,NULL);        
          fcntl(fd,   F_SETOWN,   getpid());          
          fcntl(fd,   F_SETFL,   FASYNC);                  
          tcgetattr(fd,&oldtio);    
           
   
          newtio.c_cflag   =   BAUDRATE   |   CRTSCTS   |   CS8   |   CLOCAL   |   CREAD;              
          newtio.c_iflag   =   IGNPAR   |   ICRNL;            
          newtio.c_oflag   =   0;             //这个发送我不知道怎么设置,老是发送不对  
          newtio.c_lflag   =   ICANON;      
          newtio.c_cc[VMIN]=1;          
          newtio.c_cc[VTIME]=0;          
          tcflush(fd,   TCIFLUSH);            
          tcsetattr(fd,TCSANOW,&newtio);            
     
  while   (1)   {                
            //   计算  
          需要串口实时传送过来的数据,必须中断发送和接收  
      }                
    tcsetattr(fd,TCSANOW,&oldtio);      
  }                          
   
  void   readserial();  
  {  
        read(fd,readbuf,1)   //  
          /*   这个readbuf的值需要返回mian的while中进行计算    
  }//read   程序已经调通  
   
  void   writeserial()  
  {  
            write(fd,writebuf,1)    
          //这个writebuf是while计算以后的值,发送出去  
  }//不知道这错在哪里?????老实发送不了??  
   
   
  void   signal_handler_IO   (int   status)        
  {  
  /*        
  这里就需要刚才上面那个程序说的如何判断   UART寄存器的状态值了  
  if(串口有数据传入)  
            readserial();  
  if(有数据输出)  
            writeserial();  
  }//这个问题现在是一点都没有搞明白  
   
  小弟,在次谢过完整看了问题的各位大哥,如果你能帮忙,请回帖,如果不能,大家一起交流!  
     
  问题点数:100、回复次数:14Top

1 楼h_bin16888(木之杉)回复于 2004-12-01 21:02:02 得分 0

各位看完以后,都麻烦顶一下,谢谢Top

2 楼FreeSeagull(蓝天,白云,松花江)回复于 2004-12-02 20:49:36 得分 100

看端口应该是COM1,关于Linux下的Serial   port编程,你可以看看这个资料:  
  《Serial   Programming   Guide   for   POSIX   Operating   Systems》  
   
  5th   Edition  
  Michael   R.   Sweet  
   
  http://digilander.libero.it/robang/rubrica/serial.htm  
   
  我们公司就生产串口卡,而我本人负责Linux驱动程序开发。我们的例程就是参考那篇文章写的。Top

3 楼FreeSeagull(蓝天,白云,松花江)回复于 2004-12-02 20:53:22 得分 0

以下是我们的一块板卡的manual中的摘录,该文档目前尚未提交,如有错误欢迎指正:  
  4.2. Necessary   Header   Files  
  Now,   start   a   new   project   and   include   necessary   header   files  
  #include           <stdio.h>             /*standard   IO   definition*/  
  #include           <stdlib.h>           /*standard   functions   definition*/  
  #include           <unistd.h>           /*Unix   standard   function   definition*/  
  #include           <sys/types.h>     /*types   definition*/  
  #include           <sys/stat.h>       /*status   definition*/  
  #include           <fcntl.h>             /*file   control   definition*/  
  #include           <termios.h>         /*PPSIX   terminal   control   definition*/  
  #include           <errno.h>                   /*error   number   definition*/  
   
  4.3. Open  
  Next,   let’s   open   a   port   for   read   and   write.  
  int   fd;  
  /*   open   COM1   for   read/write   */  
  fd   =   open(   "/dev/ttyS1",   O_RDWR   |   O_NOCTTY   |   O_NDELAY);  
  if   (-1   ==   fd){    
  /*   fail   to   open   the   port*/    
  perror("   Fail   to   open   COM1!");  
   
  You'll   notice   that   when   we   opened   the   device   file   we   used   two   other   flags   along   with   the   read   +   write   mode:  
  fd   =   open("/dev/ttyS0",   O_RDWR   |   O_NOCTTY   |   O_NDELAY);  
  The   O_NOCTTY   flag   tells   UNIX   that   this   program   doesn't   want   to   be   the   "controlling   terminal"   for   that   port.  
  If   you   don't   specify   this   then   any   input   (such   as   keyboard   abort   signals   and   so   forth)   will   affect   your   process.  
  Programs   like   getty   (1M/8)   use   this   feature   when   starting   the   login   process,   but   normally   a   user   program   does   not   want   this   behavior.  
  The   O_NDELAY   flag   tells   UNIX   that   this   program   doesn't   care   what   state   the   DCD   signal   line   is   in   &#8722;   whether   the   other   end   of   the   port   is   up   and   running.   If   you   do   not   specify   this   flag,   your   process   will   be   put   to   sleep   until   the   DCD   signal   line   is   the   space   voltage.  
   
  4.4. Configure  
  To   configure   a   serial   port,   you   should   use   an   important   structure:  
  struct   termio  
  { unsigned   short     c_iflag; /*   Input   mode   flag*/  
  unsigned   short     c_oflag; /*   Output   mode   flag*/  
  unsigned   short     c_cflag; /*   Control   flag*/  
  unsigned   short     c_lflag; /*   local   mode   flag*/  
  unsigned   char     c_line; /*   line   discipline   */  
  unsigned   char     c_cc[NCC];                     /*   control   characters   */  
  };  
   
  Some   commonly   used   members’   configuration:  
  struct     termios   Opt;  
  tcgetattr(fd,   &Opt);  
  cfsetispeed(&Opt,B19200);           /*Baud   rate   =   19200Bps*/  
  cfsetospeed(&Opt,B19200);  
  tcsetattr(fd,TCANOW,&Opt);  
   
  The   following   example   demonstrates   setting   baud   rate   of   COM1:  
  /**  
  *   brief Setup   baud   rate   of   specified   port  
  *   param     fd             Handle   of   an   opened   port  
  *   param     speed     Desired   baud   rate  
  *   return     void  
  */  
  int   speed_arr[]   =   {   B38400,   B19200,   B9600,   B4800,   B2400,   B1200,   B300,   B38400,B19200,   B9600,   B4800,   B2400,   B1200,   B300,   };  
  int   name_arr[]   =   {38400,     19200,     9600,     4800,     2400,     1200,     300,   38400,      
  19200,     9600,   4800,   2400,   1200,     300,   };  
  void   set_speed(int   fd,   int   speed){  
  int       i;    
  int       status;    
  struct   termios       Opt;  
  tcgetattr(fd,   &Opt);    
  for   (   i=   0;     i   <   sizeof(speed_arr)   /   sizeof(int);     i++)   {    
  if     (speed   ==   name_arr[i])   {            
  tcflush(fd,   TCIOFLUSH);            
  cfsetispeed(&Opt,   speed_arr[i]);      
  cfsetospeed(&Opt,   speed_arr[i]);        
  status   =   tcsetattr(fd1,   TCSANOW,   &Opt);      
  if     (status   !=   0)   {                  
  perror("tcsetattr   fd1");      
  return;            
  }          
  tcflush(fd,   TCIOFLUSH);        
  }      
  }  
  }  
   
  Currently,   Advantech   PCM-3614   card   support   following   parity   check   types:  
  No   parity 8位 Option.c_cflag   &=   ~PARENB;  
  Option.c_cflag   &=   ~CSTOPB;  
  Option.c_cflag   &=   ~CSIZE;  
  Option.c_cflag   |=   ~CS8;    
  Odd   Parity 7位 Option.c_cflag   |=   ~PARENB;  
  Option.c_cflag   &=   ~PARODD;  
  Option.c_cflag   &=   ~CSTOPB;  
  Option.c_cflag   &=   ~CSIZE;  
  Option.c_cflag   |=   ~CS7;    
  Even   parity 7位 Option.c_cflag   &=   ~PARENB;  
  Option.c_cflag   |=   ~PARODD;  
  Option.c_cflag   &=   ~CSTOPB;  
  Option.c_cflag   &=   ~CSIZE;  
  Option.c_cflag   |=   ~CS7;    
  Space   Parity 7位 Option.c_cflag   &=   ~PARENB;  
  Option.c_cflag   &=   ~CSTOPB;  
  Option.c_cflag   &=   &~CSIZE;  
  Option.c_cflag   |=   CS8;    
   
  Now,   setup   data   bits,   stop   bits   and   parity   check   type:  
  /**  
  *   brief         Setup   data   bits,   stop   bits   and   parity   type  
  *   param     fd         Handle   of   an   opened   port  
  *   param     databits   Data   bits  
  *   param     stopbits   Stop   bits  
  *   param     parity     Parity   check   N,E,O,,S  
  */  
  int   set_Parity(int   fd,   int   databits,   int   stopbits,   int   parity)  
  {    
  struct   termios   options;    
  if     (   tcgetattr(fd,   &options)     !=     0)   {    
  perror("Setup   Serial   1");            
  return(FALSE);      
  }  
  Top

4 楼FreeSeagull(蓝天,白云,松花江)回复于 2004-12-02 20:53:28 得分 0

options.c_cflag   &=   ~CSIZE;    
  switch   (databits)   /*set   data   bits*/  
  {        
  case   7:  
  options.c_cflag   |=   CS7;    
  break;  
  case   8:            
  options.c_cflag   |=   CS8;  
  break;        
  default:          
  fprintf(stderr,"Unsupported   data   size\n");   return   (FALSE);      
  }  
  switch   (parity)    
  {        
  case   'n':  
  case   'N':          
  options.c_cflag   &=   ~PARENB;       /*   Clear   parity   enable   */  
  options.c_iflag   &=   ~INPCK;           /*   Enable   parity   checking   */    
  break;      
  case   'o':        
  case   'O':            
  options.c_cflag   |=   (PARODD   |   PARENB);   /*   Odd   parity   check*/      
  options.c_iflag   |=   INPCK;                           /*   Disable   parity   checking   */    
  break;      
  case   'e':      
  case   'E':        
  options.c_cflag   |=   PARENB;           /*   Enable   parity   */          
  options.c_cflag   &=   ~PARODD;       /*   Change   to   Even   parity   check*/            
  options.c_iflag   |=   INPCK;               /*   Disable   parity   checking   */  
  break;  
  case   'S':    
  case   's':     /*as   no   parity*/        
          options.c_cflag   &=   ~PARENB;  
  options.c_cflag   &=   ~CSTOPB;break;      
  default:        
  fprintf(stderr,"Unsupported   parity\n");          
  return   (FALSE);      
  }      
  /*   set   stop   bits   */      
  switch   (stopbits)  
  {        
  case   1:          
  options.c_cflag   &=   ~CSTOPB;      
  break;      
  case   2:          
  options.c_cflag   |=   CSTOPB;      
        break;  
  default:          
    fprintf(stderr,"Unsupported   stop   bits\n");      
    return   (FALSE);    
  }    
  /*   Set   input   parity   option   */    
  if   (parity   !=   'n')        
  options.c_iflag   |=   INPCK;    
  tcflush(fd,TCIFLUSH);  
  options.c_cc[VTIME]   =   150;   /*   time   out:   15   seconds*/        
  options.c_cc[VMIN]   =   0;   /*   Update   the   options   and   do   it   NOW   */  
  if   (tcsetattr(fd,TCSANOW,&options)   !=   0)        
  {    
  perror("Setup   Serial   3");        
  return   (FALSE);      
  }    
  return   (TRUE);      
  }  
   
  Note:   If   you   want   to   develop   application   used   for   transferring   data   rather   than   acting   as   data   terminals,   you   should   choose   Raw   Mode   for   input   and   output   as   shown   below:  
  options.c_lflag     &=   ~(ICANON   |   ECHO   |   ECHOE   |   ISIG);     /*Input*/  
  options.c_oflag     &=   ~OPOST;       /*Output*/  
   
  4.5. Read   and   Write  
  Reading   and   writing   a   port   is   as   simple   as   reading   and   writing   an   ordinary   file.  
  Write   data:  
  char     buffer[1024];  
  int   Length;  
  int   nBytes   =   write(fd,   buffer,   Length)  
  The   write   function   returns   the   number   of   bytes   sent   or   &#8722;1   if   an   error   occurred.   Usually   the   only   error   you'll   run   into   is   EIO   when   a   MODEM   or   data   link   drops   the   Data   Carrier   Detect   (DCD)   line.   This   condition   will   persist   until   you   close   the   port.  
  Read   data:  
  char     buff[1024];  
  int         Length;  
  int   nBytes   =   read(fd,   buff,   Length);  
   
  Reading   data   from   a   port   is   a   little   trickier.   When   you   operate   the   port   in   raw   data   mode,   each   read   system   call   will   return   the   number   of   characters   that   are   actually   available   in   the   serial   input   buffers.   If   no   characters   are   available,   the   call   will   block   (wait)   until   characters   come   in,   an   interval   timer   expires,   or   an   error   occurs.  
  The   read   function   can   be   made   to   return   immediately   by   doing   the   following:  
  fcntl(fd,   F_SETFL,   FNDELAY);  
  The   FNDELAY   option   causes   the   read   function   to   return   0   if   no   characters   are   available   on   the   port.   To   restore  
  normal   (blocking)   behavior,   call   fcntl()   without   the   FNDELAY   option:  
  fcntl(fd,   F_SETFL,   0);  
  This   is   also   used   after   opening   a   serial   port   with   the   O_NDELAY   option.  
   
  4.6. Close  
  After   finished   using   a   port,   you   should   close   it   to   allow   other   application   to   access   this   port   like   this.  
  close(fd);  
  Where   fd   is   the   handle   of   the   opened   port.  
   
  4.7. Example  
  This   example   demonstrates   how   to   open,   configure,   read   and   close   a   port.  
  /*********************************************************************  
  *   Demo   project    
  *   Show   how   to   open/configure/read/write/close   a   serial   port  
  **********************************************************************/  
  #define   FALSE     -1  
  #define   TRUE       0  
  /*********************************************************************/  
  int   OpenDev(char   *Dev)  
  {  
  int fd   =   open(   Dev,   O_RDWR   |   O_NOCTTY   |   O_NDELAY)  
  if   (-1   ==   fd)  
  {    
  perror("Can't   Open   Serial   Port");  
  return   -1;  
  }  
  else  
  return   fd;  
  }  
  int   main(int   argc,   char   **argv){  
  int   fd;  
  int   nread;  
  char   buff[512];  
  char   *dev     =   "/dev/ttyS1";     //Serial   port   2  
  fd   =   OpenDev(dev);  
  set_speed(fd,19200);  
  if   (set_Parity(fd,8,1,'N')   ==   FALSE)     {  
  printf("Set   Parity   Error\n");  
  exit   (0);  
  }  
  while   (1)   //loop   to   read   data  
  {        
  while((nread   =   read(fd,   buff,   512))>0)  
  {    
  printf("\nLen   %d\n",nread);    
  buff[nread+1]   =   '\0';        
  printf(   "\n%s",   buff);        
  }  
  }  
  close(fd);      
  exit   (0);  
  }    
  Top

5 楼h_bin16888(木之杉)回复于 2004-12-03 19:57:03 得分 0

谢谢,楼上这位兄弟,你说的那篇文章我看过,里面没有讲到我所需要的响应中断,比如如何直接判断当前是发送,还是接收,还有一个问题就是,我的read为什么一会好,一会不行,而write根本就不行,最开始的时候,也可以的,我很郁闷呀,求助,你是搞这个网卡驱动的吗?留下qq好不?我的qq:63305340,想请教你Top

6 楼yanwenyuan0102(小郎)回复于 2004-12-09 14:04:54 得分 0

顶啦Top

7 楼h_bin16888(木之杉)回复于 2004-12-19 02:25:37 得分 0

没有人知道吗?顶一下Top

8 楼h_bin16888(木之杉)回复于 2005-02-17 13:32:46 得分 0

高手解答一下。顶一下  
  Top

9 楼h_bin16888(木之杉)回复于 2005-02-19 19:32:02 得分 0

定Top

10 楼tengulre(debian core developer)回复于 2005-02-20 14:06:36 得分 0

dingTop

11 楼tengulre(debian core developer)回复于 2005-02-20 15:31:37 得分 0

zai   dingTop

12 楼h_bin16888(木之杉)回复于 2005-02-20 19:52:40 得分 0

定Top

13 楼h_bin16888(木之杉)回复于 2005-02-23 18:55:53 得分 0

顶呀Top

14 楼h_bin16888(木之杉)回复于 2005-02-26 11:07:25 得分 0

顶Top

相关问题

  • 急,有分送
  • 急!!急.....,送分,送分!!请各位大虾帮帮忙
  • 急,,请各位兄弟解决,80分送
  • 急~~~!!!(高分送上)
  • 急,100分送了
  • 急!急!急!高分送出!
  • 急!急!急!50分送上。
  • 关闭窗体的问题.各位进来看看.80分送上,急!!!!!
  • 超级急,各位大侠,快点来帮我啊,送分送分!
  • 在线急等,高分送!

关键词

  • 函数
  • 中断
  • 数据
  • program
  • 串口
  • noctty
  • definition
  • 接收
  • ndelay
  • fd

得分解答快速导航

  • 帖主:h_bin16888
  • FreeSeagull

相关链接

  • CSDN Blog
  • 技术文档
  • 代码下载
  • 第二书店
  • 读书频道

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo