zoukankan      html  css  js  c++  java
  • 4412 RS485

    一、485硬件原理

    • 差分对传输数据的原理
      • IO数据的传输→差分对
    • rs232传输的距离在15米以下,RS485传输距离是几十米到1000米以上
    • 为什么485可以传输这么远
      • 差分对的机制可以降低电磁场的干扰
      • 衰减
    • 485传输距离和传输线有关系
      •  注意:双绞线和屏蔽线

    二、485原理图

    嵌入式上一般使用串口转485

    分析芯片datasheet

    串口的信号转化为485则:

    • D→(A,B),DE高电平,RE高电平

    485信号转化为串口信号则:

    • (A,B),DE低电平,RD低电平

    三、驱动

    485驱动=串口驱动+GPIO的字符驱动

    BUF_XURTS1高电平发送,低电平接收

    串口驱动是drivers/char/max485_ctl.c   

    • 485驱动=串口驱动+GPIO的字符驱动
    • BUF_XURTS1高电平发送,低电平接收
    • (GPIO是GPA0_7,串口设备节点是ttySAC1)


    驱动中只需要操作GPIO

    • 设备节点/dev/max485_ctl


    应用中,控制GPIO和串口=类似led+串口的操作

    • ioctl是参数是1,则输出高电平,发送
    • ioctl是参数是0,则输出低电平,接收
    • 串口的节点/dev/ttySAC1


    运行程序

    • 发送./test_485 /dev/ttySAC1 1
    • 接收./test_485 /dev/ttySAC1 0

    测试程序发送的信息:iTOP-4412: max485 test app(times:%d)

     测试程序:

    //#include <stdio.h>
    #include <unistd.h>
    //#include "uart.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <termios.h>
    #include <string.h>
    
    #define MAX485_CONTROL
    
    //#include "uart.c"
    int set_opt(int fd,int nSpeed, int nBits, char nEvent, int 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;
            break;
        case 8:
            newtio.c_cflag |= CS8;
            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;
        }
    
        printf("Baund Rate: %d
    ", nSpeed);
    
        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;
        case 921600:
            printf("Rate:921600
    ");
            cfsetispeed(&newtio, B921600);
                    cfsetospeed(&newtio, B921600);
                    break;
        default:
            cfsetispeed(&newtio, B9600);
            cfsetospeed(&newtio, B9600);
            break;
        }
        if( nStop == 1 )
            newtio.c_cflag &=  ~CSTOPB;
        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!
    
    ");
        return 0;
    }
    
    int prepare_to_send(int fd)
    {
        int ret;
    
        ret = ioctl(fd, 1, 0);
        if(ret<0)
        {
            printf("max485 set ctl to high failed!
    ");
    
            return -1;
        }
        else
        {
            return 0;
        }
    }
    
    int prepare_to_recv(int fd)
    {
        int ret;
    
        ret = ioctl(fd, 0, 0);
        if(ret<0)
        {
            printf("max485 set ctl to low failed!
    ");
            
            return -1;
        }
        else
        {
            return 0;
        }
    }
    
    void main(int argc, char* argv[])
    {
        unsigned char ucTmp;
        int fd1,fd2,nset1,nset2,nread;
    
        char buf[100];
        //char buf1[1];
    
        //char *buff = "Hello
    
    ";
    
        int i = 0;
    
        char *max485_ctl = "/dev/max485_ctl_pin";
    
        if(3 != argc)
            {
            printf("Usage:    test_485 [uart port] [type]
    ");
            printf("        type: 0--recv, 1--send
    ");
                
            return;
        }
    
        fd1 = open(argv[1], O_RDWR);
        if (fd1 == -1)
        {
            printf("Open %s faild
    ", argv[1]);
            exit(1);
        }
    
        nset1 = set_opt(fd1, 9600, 8, 'N', 1);
        if (nset2 == -1)
        {
            printf("Set uart faild
    ");
            exit(1);
        }
    
    #ifdef MAX485_CONTROL
        if((fd2=open(max485_ctl, O_RDWR|O_NOCTTY|O_NDELAY))<0)
        {
            printf("Open %s faild
    ", max485_ctl);
            close(fd1);
            
            exit(1);
        }
    #endif
        
        if(0 == atoi(argv[2]))    //recv
        {
    #ifdef MAX485_CONTROL
            prepare_to_recv(fd2);
    #endif
            while(1)
            {    
                
                nread = read(fd1, buf, 100);
                if (nread > 0)
                {
                    for(i=0; i<nread; i++)
                    {
                        printf("%c", buf[i]);
                
                        if(buf[i] == 'q')
                            //break;
                            goto exit;
                    }
                }
                //if(nread)
                //{
                //    printf("
    ");
                //}
                sleep(1);
            }
        }
        else    //send 
        {
    #ifdef MAX485_CONTROL
            prepare_to_send(fd2);
    #endif
            while(1)
            {
                printf("Send data, time:%d
    ", i);
                sprintf(buf, "iTOP-4412: max485 test app(times:%d)
    ", i++);
                //nread = write(fd1, "iTOP-4412: max485 test app
    ", strlen("iTOP-4412: max485 test app
    "));
                nread = write(fd1, buf, strlen(buf));
                sleep(1);
    #if 0
                nread = read(fd1, buf, 100);
                            if (nread > 0)
                            {
                                    for(i=0; i<nread; i++)
                                    {
                                            printf("%c", buf[i]);
    
                                            if(buf[i] == 'q')
                                                    //break;
                                                    goto exit;
                                    }
                            }
                            if(nread)
                            {
                                    printf("
    ");
                            }
    #endif
            }
        }
    exit:
        close(fd1);
    
            return;
    }
    测试程序
  • 相关阅读:
    MD5 Message Digest Algorithm in Visual Basic 6
    遍历指定文件夹的指定格式的文件并且copy到指定的文件夹下面
    宝宝的成长脚印8/17
    儿歌童谣两首
    office2003之資料編輯列的角字顯示7/10
    宝宝的成长脚印8/27
    宝宝的成长脚印7/30
    宝宝的成长脚印7/3
    LED手电筒真不咋滴8/27
    液晶显示器右边出现黑条7/7
  • 原文地址:https://www.cnblogs.com/ch122633/p/9505219.html
Copyright © 2011-2022 走看看