免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 9706 | 回复: 5
打印 上一主题 下一主题

[操作系统] 基于Arm开发的linux嵌入式系统,RS485串口读写通讯中,板子对该串口可写不可读 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-12-28 10:02 |只看该作者 |倒序浏览
5可用积分
基于Arm开发的linux嵌入式系统,RS485串口读写通讯中:

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

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

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

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

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


请各路大神解吾之惑,不胜感激!!!在线速等!!!(附件为板子和PC的调试程序)
test_rs485.7z (2.39 KB, 下载次数: 118)

#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[VTIME] = 150;  //  15 seconds
    options.c_cc[VMIN] = 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[20];
               
        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[128] = {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;
}

论坛徽章:
0
2 [报告]
发表于 2011-12-29 21:20 |只看该作者
设置成非规范模式试试

论坛徽章:
0
3 [报告]
发表于 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;
                }
           }  


论坛徽章:
0
4 [报告]
发表于 2012-01-04 10:04 |只看该作者
回复 3# hzy2hzy


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

论坛徽章:
0
5 [报告]
发表于 2012-01-04 10:21 |只看该作者
回复 3# hzy2hzy


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

论坛徽章:
0
6 [报告]
发表于 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 类型的不好吗?
还有为什么里面的元素有重复的? 是怕漏掉扫描不上吗? 还是有什么原因?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP