LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1097|回复: 7

【串口问题】我的程序能够对串口进行读写了么?

[复制链接]
发表于 2004-3-4 18:00:38 | 显示全部楼层 |阅读模式
我想要的功能是这样的:本机的com1口与一片开发板上的串口2进行通讯。
连线方式就是直接用RS232电缆连,只需要用到收、发功能,其他的握手信号什么的都不需要.程序如下:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
///#include <sys/signal.h>
#include <string>

#define TRUE 1
#define FALSE 0
#define MODEDEVICE "/dev/ttyS1"

volatile int STOP=FALSE;

int open_Com(char devicename[])
{ int fd;
  char *deV;
  strcpy(deV,devicename);
  fd1=open(deV , O_RDWR | O_NOCTTY | O_NDELAY);
  if(-1==fd)
  {printf("Can't open s%\n",deV);
   return(FALSE);
  }
  return(TRUE);
}

int set_ioSpeed(int fd ,int baud_speed)
{ 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, };
  int   i;
  int   status;
  struct termios   Opt;
  tcgetattr(fd, &Opt);
  for ( i= 0;  i < sizeof(speed_arr) / sizeof(int);  i++)
   {
           if  (speed == name_arr)
           {
           tcflush(fd, TCIOFLUSH);
            cfsetispeed(&Opt, speed_arr);
            cfsetospeed(&Opt, speed_arr);
            status = tcsetattr(fd, TCSANOW, &Opt);
            if  (status != 0)
            {
             perror("tcsetattr fd\n");
             return(FALSE);
            }
             return(TRUE);
             }
   tcflush(fd,TCIOFLUSH);
}

int set_Com(int fd , int databits , int stopbits , int paritybits)
{int status;
struct termios oldtios , newtios;
//fd=open_Com(MODEDEVICE);
if(fd==0)
{perror("Can't open Com2");
  return(FALSE);
}
cgetattr(fd,&oldtios);
bzero(newtios);
newtios.c_cflag &=~CSIZE;
newtios.c_cflag =(CLOCAL | CREAD);
switch(databits)
{case 7:
        newtios.c_cflag |=CS7;
        break;
  case 8:
        newtios.c_cflag |=CS8;
        break;
  default:
        printf("Unrecognizable databits!\n");
        return(FALSE);
}
swtich(stopbits)
{case 1:
       newtios.c_cflag &=~CTOPB;
       break;
  case 2:
       newtios.c_cflag |=CTOPB;
       break;
  default:
       printf("unsupportable stopbits\n ")
       return(FALSE);
}
switch(paritybits)
{case 'n':
  case 'N':
       newtios.c_cflag &=~PARENB;
       newtios.c_iflag |=IGNPAR;
       break;
  case 'o':
  case 'O':
       newtios.c_cflag |=PARENB;
       newtios.c_cflag |=PARODD;
       newtios.c_iflag |=INPCK;
       break;
  case 'e':
  case 'E':
       newtios.c_cflag |=PARENB;
       newtios.c_cflag &=~PARODD;
       newtios.c_iflag |=INPCK;
       break;
  case 's':
  case 'S':
       newtios.c_cflag &=~PARENB;
       newtios.c_iflag |=INPCK;
       break;
  default:
       printf("Unsupportable paritybits!\n");
       return(FALSE);
}
newtios.c_lflag =0;   ////set non-echo
newtios.c_oflag=0;
newtios.c_cc[VMIN]=1;
newtio.c_cc[VTIME]=0;
tcflush(fd, TCIFLUSH);
tcsetattr(fd,TCSANOW,&newtio);
tcsetattr(1,TCSANOW,&newtio);
return;
}

int read_Com(char *devicename)
{ int buf[512];
  int com_read;
  com_read=read(MODEDEVICE , buf , 512);
  if(-1==com_read)
  {printf("Can't read!\n");
   return(FALSE);
  }
  fcntl(0,F_SETFL,0);///问题:现在可以直接对串口进行读操作了么?
  return(TRUE);
}

int write_Com(char *devicename)
{ int buf[512];
  int com_write;
  com_write=write(MODEDEVICE , buf ,512);
  if(-1==com_write)
  {printf("Can't write!\n");
   return(FALSE)
  }
  return(TRUE);
}

main(int argc , char *argv)
{int fd;
int buffer[512];
fd=open_com(MODEDEVICE);
set_ioSpeed(MODEDEVICE);
set_Com(fd , 8 , 1 , 'n');
read_Com(MODEDEVICE);
break;
}
 楼主| 发表于 2004-3-4 18:03:01 | 显示全部楼层
我是新手啊,其中有错误,还请批评指正,请高手不吝赐教。谢谢
发表于 2004-3-6 17:03:20 | 显示全部楼层
char *deV;
strcpy(deV,devicename);
dev指向那里啊?
发表于 2004-3-6 18:32:30 | 显示全部楼层
很高兴能看到这方面程序
请问
volatile  是什么意思?


  1. nt open_Com(char devicename[])
  2. { int fd;
  3. char *deV;
  4. strcpy(deV,devicename);
  5. fd1=open(deV , O_RDWR | O_NOCTTY | O_NDELAY);
  6. if(-1==fd)
  7. {printf("Can't open s%\n",deV);
  8. return(FALSE);
  9. }
  10. return(TRUE);
  11. }
复制代码

这里的fd1没有定义?
 楼主| 发表于 2004-3-8 18:08:51 | 显示全部楼层
volalite 表示这个flag可以在程序中改动的,并且将改动的值update。
 楼主| 发表于 2004-3-8 18:28:26 | 显示全部楼层
不好意思,由于当时匆忙,没有好好校验一下代码。现在看来发现了很多语法错误。:-(
现在将校正过的发表如下:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
///#include <sys/signal.h>
#include <string.h>

#define TRUE 1
#define FALSE 0
#define MODEDEVICE "/dev/ttyS0"

volatile int STOP=FALSE;

int open_Com(char devicename[])
{ int fd;
  char *deV;
  strcpy(deV,devicename);
  fd=open(deV , O_RDWR | O_NOCTTY | O_NDELAY);
  if(-1==fd)
  {printf("Can't open s%\n",deV);
   return(-1);
  }
  return 0;
}

int set_ioSpeed(int fd ,int baud_speed)
{ 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, };
  int   i;
  int   status;
  struct termios   Opt;
  tcgetattr(fd, &Opt);
  for ( i= 0;  i < sizeof(speed_arr) / sizeof(int);  i++)
   {
           if  (baud_speed == name_arr)
           {
            tcflush(fd, TCIOFLUSH);
             cfsetispeed(&Opt, speed_arr);
             cfsetospeed(&Opt, speed_arr);
             status = tcsetattr(fd, TCSANOW, &Opt);
             if  (status != 0)
            {
             perror("tcsetattr fd\n");
             return(FALSE);
            }
              return(TRUE);
             }
   tcflush(fd,TCIOFLUSH);
   }
}

int set_Com(int fd , int databits , int stopbits , int paritybits)
{int status;
struct termios oldtios , newtios;
//fd=open_Com(MODEDEVICE);
if(fd==-1)
{perror("Can't open Com2");
  return(FALSE);
}
tcgetattr(fd,&oldtios);
bzero(&newtios,sizeof(newtios));
newtios.c_cflag &=~CSIZE;
newtios.c_cflag =(CLOCAL | CREAD);
switch(databits)
{case 7:
        newtios.c_cflag |=CS7;
        break;
  case 8:
        newtios.c_cflag |=CS8;
        break;
  default:
        printf("Unrecognizable databits!\n");
        return(FALSE);
}
switch(stopbits)
{case 1:
       newtios.c_cflag &=~CSTOPB;
       break;
  case 2:
       newtios.c_cflag |=CSTOPB;
       break;
  default:
       printf("unsupportable stopbits\n ");
       return(FALSE);
}
switch(paritybits)
{case 'n':
  case 'N':
       newtios.c_cflag &=~PARENB;
       newtios.c_iflag |=IGNPAR;
       break;
  case 'o':
  case 'O':
       newtios.c_cflag |=PARENB;
       newtios.c_cflag |=PARODD;
       newtios.c_iflag |=INPCK;
       break;
  case 'e':
  case 'E':
       newtios.c_cflag |=PARENB;
       newtios.c_cflag &=~PARODD;
       newtios.c_iflag |=INPCK;
       break;
  case 's':
  case 'S':
       newtios.c_cflag &=~PARENB;
       newtios.c_cflag &=~CSTOPB;
       break;
  default:
       printf("Unsupportable paritybits!\n");
       return(FALSE);
}
newtios.c_lflag =0;   ////set non-echo
newtios.c_oflag=0;
newtios.c_cc[VMIN]=1;
newtios.c_cc[VTIME]=0;
tcflush(fd, TCIFLUSH);
tcsetattr(fd,TCSANOW,&newtios);
tcsetattr(1,TCSANOW,&newtios);
return;
}

int read_Com(char *devicename)
{ char buf[512];
  int com_read;
  int fd;
  fd=open_Com(MODEDEVICE);
  if(fd==0)   ////changed "1"->"0"
  {
    com_read=read(fd , buf , 512);
    if(-1==com_read)
    {
     printf("Can't read!\n");
     return(FALSE);
    }

/// fcntl(0,F_SETFL,0);///&Icirc;&Ecirc;&Igrave;&acirc;&pound;&ordm;&Iuml;&Ouml;&Ocirc;&Uacute;&iquest;&Eacute;&Ograve;&Ocirc;&Ouml;±&frac12;&Oacute;&para;&Ocirc;&acute;&reg;&iquest;&Uacute;&frac12;&oslash;&ETH;&ETH;&para;&Aacute;&sup2;&Ugrave;×÷&Aacute;&Euml;&Atilde;&acute;&pound;&iquest;
    return(TRUE);
   }
  printf("Can't open com!\n");
  return(FALSE);
}

int write_Com(char *devicename)
{ char buf[512];
  int com_write;
  int fd;
  fd=open_Com(MODEDEVICE);
  if(fd==0)  /////changed "1"->"0"
  {
    com_write=write(fd , buf ,512);
    if(-1==com_write)
    {printf("Can't write!\n");
    return(FALSE);
    }
  return(TRUE);
  }
  printf("Can't write com!\n");
  return(FALSE);
}

int main(int argc , char *argv)
{int fd;
int res0, res1,res2;
////char buffer[512];
fd=open_Com(MODEDEVICE);
if(0==fd)
  {
   res0=set_ioSpeed(fd , 19200);
   if(TRUE==res0)
    {
      res1==set_Com(fd , 8 , 1 , 'n');
      if(TRUE==res1)
       {
        res2==read_Com(MODEDEVICE);
        if(res2==TRUE)
          {
             ////close(fd);
            return(TRUE);
          }
        }
    }
  }
return(FALSE);
}
 楼主| 发表于 2004-3-8 18:35:51 | 显示全部楼层
关于deV指针,初始化的问题,我想问:该怎样初始化呢?
先给它随便赋一个值么?
上面这个程序,我的设想是一台PC和一块开发板通过串口收发两根线直接连接,进行通信。不知道还要注意什么,,需要用到调用进程的函数么??
请大虾们不吝赐教,谢谢
发表于 2004-3-8 20:44:06 | 显示全部楼层
我才做了串口的程序,呵呵,还可以从你的程序里,看到参考的代码的影子哦~

我在程序里很少用指针(因为不太会用,容易出错),
我用数组, read, write 的时候也是用数组

个人感觉你的dev 用处不大,直接
fd=open(devicename , O_RDWR | O_NOCTTY | O_NDELAY); 不好吗?

串口设置其实很死的,就那么几步,但是要想以后的读写正常,对各种设置一定要弄清楚了

尤其你看 serial how to 的时候,有 canonical and non-canonical 两种,区别要注意了

我也是新手,只是在linux上做了个串口程序。
以后想大家多学习。

btw: 用论坛的 code 功能,贴代码比较清楚,容易看
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表