yangnifeng 发表于 2011-12-28 10:02

基于Arm开发的linux嵌入式系统,RS485串口读写通讯中,板子对该串口可写不可读

基于Arm开发的linux嵌入式系统,RS485串口读写通讯中:

板子对该串口配置为:波特率9600;数据位:8;停止位:1;奇偶校验:无;PC端使用RS232转485串口,配置相同;

板子上的测试程序将其配置好后做写操作时,PC端的测试程序可以正确收到;

PC端程序间隔5秒对串口写数据,板子上的程序读操作读不到任何东西,一直阻塞与Read;若是选择不阻塞式Read(),其将不停返回-1;

PC端能读到板子上写入串口的数据;
PC端往串口写数据,用示波器在RS485引脚上可见负载电压,即有数据到板子;
但是板子上的程序一直读不到,就像其串口文件上没有数据可读一样!

ARM串口引脚是有数据的,板子的RS485串口驱动应该是没问题的吧;
板子的测试应用程序往RS485串口写东西,PC端是可以读到的!
那是否就是我板子的应用程序关于串口配置得


请各路大神解吾之惑,不胜感激!!!在线速等!!!(附件为板子和PC的调试程序)


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/ipc.h>
#include <termios.h>




int birdrate_arr[] = {B115200, B38400, B19200, B9600, B4800, B2400, B1200, B300, B38400, B19200, B9600, B4800, B2400, B1200, B300};
int name_arr[] = {115200, 38400, 19200, 9600, 4800, 2400 , 1200, 300, 38400, 19200, 9600, 4800, 2400, 1200, 300};

int IPNC_app_test_SetSpeed(int fd, int speed)
{
         int status, i;
         struct termios Opt;
         tcgetattr(fd, &Opt);
         
         for(i=0; i<sizeof(name_arr)/sizeof(int); i++)
    {
      if (speed==name_arr)
      {
                        speed = birdrate_arr;
                                                break;
               }
         }   

         tcflush(fd, TCIOFLUSH);
         cfsetispeed(&Opt, speed);
         cfsetospeed(&Opt, speed);
         status = tcsetattr(fd, TCSANOW, &Opt);
    if(status != 0)
         {
       return -1;
    }
    return 1;
}

int IPNC_app_test_SetParity(int fd, int databits, int stopbits, int parity)
{
          struct termios options;
          if(tcgetattr(fd, &options)!=0)
          {
            return -1;
          }
          options.c_cflag &= ~CSIZE;
          switch(databits)/* 设置数据位数 */
          {
          case 7:
            options.c_cflag |= CS7;
            break;
          case 8:
            options.c_cflag |= CS8;
            break ;
          default:
            return -1;
          }
         
    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);   /*设置为奇效验 */
      options.c_iflag |= INPCK;               /*Disnable parity checking*/
      break ;
    case 'e':
    case 'E':
               options.c_cflag |= PARENB;       /*Enable parity*/
      options.c_cflag &= ~PARODD;      /*转换为偶效验 */
      options.c_iflag |= INPCK;      /*Disnable parity checking*/
      break ;
    case 'S':
    case 's':   /* as no parity */
               options.c_cflag &= ~PARENB;
               options.c_cflag &= ~CSTOPB;
      break ;
    default:
      return -1;
         }
   /*设置停止位 */
          switch(stopbits)
          {
          case 1:
                     options.c_cflag &= ~CSTOPB;
                     break ;
          case 2:
                     options.c_cflag |= CSTOPB;
            break ;
          default:
            return -1;
          }
   /*Set input parity option*/
//    if(parity != 'n' )
//       options.c_iflag |= INPCK;

    options.c_cc = 150;//15 seconds
    options.c_cc = 0;
   
         tcflush(fd,TCIFLUSH);/*Update the options and do it NOW*/
         if(tcsetattr(fd,TCSANOW, &options)!=0)
    {
      return -1;
         }
    return 1;
}


int IPNC_app_test_openRS485(int devnumb, int birdrate)
{
      int i;
      char dev;
               
      if(devnumb==0)
      {         
                sprintf(dev, "/dev/tts/0"; //dev/ttyS0对应串口com0
      }
      else if(devnumb==1)
      {
                sprintf(dev, "/dev/tts/1"; //dev/ttyS1对应串口com1         
      }
      else
      {
                return DEV_NUMBER_WRONG;//wrong device numb
      }
   
      for(i=0; i<sizeof(name_arr)/sizeof(int); i++)
      {
                if (birdrate==name_arr)
                {
                        i = -1;
                        break;
                }
         }
                     
      if(i!=-1)
      {
                return DEV_BIRDRATE_WRONG;//wrong device numb      
      }
   
      int fd = open(dev, O_RDWR);          // | O_NOCTTY | O_NDELAY   
      if(fd==-1)
      {
                  printf("Error open\n";
                return DEV_OPENDEV_FAIL;
      }
      else
      {
                if( IPNC_app_test_SetSpeed(fd, birdrate)==-1) // 设置波特率
                {
                        return DEV_SETBIRDRATE_FAIL;
                }
      }
      if( IPNC_app_test_SetParity(fd, 8, 1, 'N')==-1)
      {
                return DEV_SETBIRDRATE_FAIL;
      }
      return fd;
}

int IPNC_app_test_closeRS485(int fd)
{
      close(fd);
      return 1;
}



int main()
{      
      int lcount = 0, timer = 0;
      char cmd = {0};
      struct termios old_Opt;
      
      int fd485 = IPNC_app_test_openRS485(0, 9600);          // | O_NOCTTY | O_NDELAY
      if(fd485 < 0)
      {
                printf("Error open\n";
                return -1;
      }
      else
      {
                printf("Open RS485 device success!\n";
                   tcgetattr(fd485, &old_Opt);
      }

      while(1)
      {
                printf("\n\nWriting rs485 [%d] time... ... ", ++timer);
                write(fd485, "test write with RS485 device!", 12;
                printf("done!\n";
                if(timer > 2)
                        break;
                else
                        sleep(10);
      }

      sleep(5);
      timer = 0;
      
      while(1)
      {
                tcflush(fd485, TCIOFLUSH);
                memset(cmd, 0, sizeof(cmd));
                printf("\n\nBefore Read from RS485 [%d] time ... ... ", ++timer);
                fflush(stdout);
                lcount = read(fd485, cmd, sizeof(cmd));
                printf("done!\nRead RS485 success: cmd = [%s].\n", cmd);
                if(timer > 2)
                        break;
                else
                        sleep(10);
      }

      sleep(5);

      tcflush(fd485, TCIOFLUSH);
         tcsetattr(fd485, TCSANOW, &old_Opt);
      
      IPNC_app_test_closeRS485(fd485);
    return 0;
}

Life_is_so 发表于 2011-12-29 21:20

设置成非规范模式试试

hzy2hzy 发表于 2011-12-30 16:50

回复 1# yangnifeng

读写时序问题吧,板子上先读后写看看?

下面的if语句,怎么用int 和int*比较?不是很懂,可以解释一下?   



for(i=0; i<sizeof(name_arr)/sizeof(int); i++)
      {
                if (birdrate==name_arr)
                {
                        i = -1;
                        break;
                }
         }


yangnifeng 发表于 2012-01-04 10:04

回复 3# hzy2hzy


    黏贴出来的没有整形数组下标实际上,有关整形数组birdrate_arr和name_arr的循环使用中都应该有,不知为何黏贴出来就没有了!

yangnifeng 发表于 2012-01-04 10:21

回复 3# hzy2hzy


    另外:我试过板子上不断的只读;PC不断的只写,问题依然存在!

googny 发表于 2012-06-05 22:58

我想问问在设置串口波特率的时候.
int birdrate_arr[] = {B115200, B38400, B19200, B9600, B4800, B2400, B1200, B300, B38400, B19200, B9600, B4800, B2400, B1200, B300};
这句话 为什么声明成int类型的? speed_t 类型的不好吗?
还有为什么里面的元素有重复的? 是怕漏掉扫描不上吗? 还是有什么原因?
页: [1]
查看完整版本: 基于Arm开发的linux嵌入式系统,RS485串口读写通讯中,板子对该串口可写不可读