精华内容
下载资源
问答
  • RS485 驱动调试
    千次阅读
    2018-10-26 15:24:50

    基于i.MX6Q平台,调试RK485,出现下面两个问题:

        1)在115200波特率下,RK485必须先发送数据才能接收到数据,不先发送的话,不能接收数据;

        2)在9600波特率下,不能发送数据;

     

    分析问题:跟踪驱动代码,流控逻辑问题;

    更多相关内容
  • RS485驱动程序.rar

    2019-08-04 18:30:06
    基于STM32F103的RS485驱动程序,稳定使用的程序版本,!
  • usb转rs485驱动 485 驱动

    2020-08-28 17:06:23
    usb转rs485驱动 ,485 驱动 Windows Linux Mac WinCE 驱动 都有。
  • RS485驱动开发

    2018-11-20 10:24:16
    RS485串口驱动开发,基于tms320c6748工程实例。有需要的下载
  • 文章简单介绍了linux下AT91SAM9261的RS485驱动
  • usb转rs485驱动

    2014-05-03 17:53:13
    usb转rs485驱动
  • linux RS485驱动

    2017-06-28 20:28:44
    linux RS485驱动,模块化驱动,支持加载与卸载
  • USB转RS485驱动程序

    2018-08-10 15:09:24
    USB转RS485驱动程序,里面有详细步骤,经过本人实验,是可用的
  • linux下rs485驱动

    2011-11-21 11:20:35
    linux下rs485驱动,可支持115200波特率的数据的收发
  • RS485驱动

    千次阅读 2015-12-18 16:10:45
    一、原理 RS232用两根线实现全双工,两根线各做各的,互不影响,可以同时进行;... 1、驱动程序中已经含有对半双工情况下的接受切换,驱动程序会根据你读或写的动作,自动进行切换。这种情况下,RS485的编程就与RS2

    一、原理
    RS232用两根线实现全双工,两根线各做各的,互不影响,可以同时进行;RS485虽然可以用四根线实现全双工,但是实际应用中比较少见,更常见的是只用两根线实现半双工,这样一来,就涉及到“收状态”和“发状态”的切换,这一切换又涉及两种情况:
    1、驱动程序中已经含有对半双工情况下的接受切换,驱动程序会根据你读或写的动作,自动进行切换。这种情况下,RS485的编程就与RS232完全没有区别。
    2、驱动程序不带自动切换,此时,为了完成切换,必须使用额外的GPIO连接RS485收发模块的接受使能端,在接受、发送数据之前,首先对使能端置位,使之处于正确的“接收”或“发送”状态。

    二、支持平台
    此文是基于TI芯片AM1808平台的RS485驱动,由于他们的软串口不支持485串口数据传输,所以自己写了一个简单的485驱动,此驱动只用来简单的控制485的使能管脚,拉高或拉低电平,满足读写。

    1.rs485驱动

    #include <linux/fs.h>
    #include <linux/major.h>  
    #include <linux/blkdev.h>
    #include <linux/capability.h>
    #include <linux/smp_lock.h>
    #include <asm/io.h>
    #include <asm/uaccess.h>
    #include <linux/module.h>
    #include <linux/delay.h>
    #include <linux/kernel.h>
    #include <linux/sched.h>
    #include <linux/interrupt.h>     /* for in_interrupt */
    #include <linux/timer.h>
    #include <linux/init.h>
    #include <linux/version.h>
    #include <asm/irq.h>
    #include <linux/gpio.h>
    #include <linux/moduleparam.h>
    #include <linux/list.h>
    #include <linux/cdev.h>
    #include <linux/proc_fs.h>
    #include <linux/mm.h>
    #include <linux/seq_file.h>
    #include <linux/ioport.h>
    #include <linux/io.h>
    #include <linux/device.h>
    #include <linux/ioctl.h>
    
    #define RS485DE     GPIO_TO_PIN(2, 15)//lct add 2015/11/19
    #define nREV      0
    #define nSENT     1
    #define LAST_BYTES_FIFO_TO_SHIFTER 1
    //#define RS485SENTBEGIN  0  
    //#define RS485SENTOVER   1
    //ioctl函数传参的时候,命令字cmd最好不要自己定义宏,内核会过滤掉不合法的cmd,因为cmd分为4个部分,type,number,direction,size。自己定义的cmd没有这四个部分,内核直接过滤掉你的ioctl请求,所以ioctl根本不会到驱动,在应用层调用的时候就被返回错误了。
     #define DRIVERNAME  "rs485driver"
    
    static int rs485_open(struct inode*, struct file *);
    static int rs485_close(struct inode*, struct file *);
    static long rs485_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
    #ifdef DEBUG_WG
    #define PRIN_DEBUG printk
    #else
    #define PRIN_DEBUG
    #endif
    
    static         dev_t  dev;
    static struct  cdev   cdev;
    static struct  class  *rs485_class = NULL;
    
    static struct file_operations rs485_ctl_fops =
    {
         .owner = THIS_MODULE,
         .open  = rs485_open,
         .release = rs485_close,
         .unlocked_ioctl = rs485_ioctl,
    };
    
    //struct rs485de_ctl
    //{
    //     long BaudRate;     //19200
    //     int parity;               // 0
    //     int startBits;          // 1
    //     int dataBits;          // 8
    //     int stopBits;          // 1
    //     long count;          //  15字节
    //};
    
    //struct rs485de_ctl *dep;
    
    static int __init rs485_init(void)
    {
    
         int result;
    
         result = alloc_chrdev_region(&dev, 0, 1, DRIVERNAME);
         if(result < 0){
             printk("Error registering rs485 character device\n");
             return -ENODEV;
         }
         printk(KERN_INFO "rs485 major#: %d, minor#: %d\n", MAJOR(dev), MINOR(dev));
    
         cdev_init(&cdev, &rs485_ctl_fops);
         cdev.owner = THIS_MODULE;
         cdev.ops = &rs485_ctl_fops;
    
         result = cdev_add(&cdev, dev, 1);
         if(result){
             unregister_chrdev_region(dev, 1);
             printk("Error adding rs485.. error no:%d\n",result);
             return -EINVAL;
         }
         rs485_class = class_create(THIS_MODULE, DRIVERNAME);
         device_create(rs485_class, NULL, dev, NULL, DRIVERNAME);
    
         printk(DRIVERNAME " initialized\n");
    
         return 0;
    }
    
    static int rs485_open(struct inode*inode, struct file *filp)
    {         
         int status;
         printk("=======%s\n", __func__);
    
         status = gpio_request(RS485DE, "rs485 enable\n");
         printk("====status=%d\n", status);
         if (status < 0) {
              gpio_free(RS485DE);
              return status;
         }
    
         //set 485_DE/RE as output and set it to be low level as receive
         gpio_direction_output(RS485DE, 0);
         return 0;
    }
    
    static int rs485_close(struct inode*inode, struct file *filp)
    {
         printk("=======%s\n", __func__);
         gpio_free(RS485DE);
         return 0;
    }
    
    void set_rs485de_sent(void)
    {
         printk("=======%s\n", __func__);
         //set 485_DE/RE as output and set it to be high level as send
         gpio_direction_output(RS485DE, 0);
         gpio_set_value(RS485DE, 1);
    }
    
    void set_rs485de_receive(void)
    {
         //set 485_DE/RE as output and set it to be low level as receive
         gpio_direction_output(RS485DE, 0);
         gpio_set_value(RS485DE, 0);
    }
    
    //计算切换电平的延时时间,主要跟起始位,校验位,数据位,停止位
    //void read_delay_and_clr_de(void)
    //{
    //     unsigned int i;
    //     unsigned int delay_time_us;
    //     delay_time_us=(1000000/dep->BaudRate)+1;
    //     delay_time_us=delay_time_us*(dep->parity+dep->stopBits+dep->dataBits+dep->startBits)*LAST_BYTES_FIFO_TO_SHIFTER;
    //     printk("delay time is %dus\n",delay_time_us);    
    //
    //     for(i=0;i<delay_time_us;i++)
    //          udelay(1);
    //     set_rs485de_receive();    
    //}
    
    static long rs485_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
    {
         int ret = 0;
    
      switch(cmd)
      {
           case 0:
                 set_rs485de_sent();          
                 break;
           case 1:
                 set_rs485de_receive();    
                 break;
           default:
                 ret=-1;
    
                 break;
      }     
         return ret;
    }
    
    static void __exit rs485_exit(void)
    {
         //printk("=======%s\n", __func__);
         printk("rs485 chrdev exit!\n");
            cdev_del(&cdev);
            unregister_chrdev_region(dev, 1);
            device_destroy(rs485_class, dev);
            class_destroy(rs485_class);
    }
    
    MODULE_LICENSE("GPL");
    module_init(rs485_init);
    module_exit(rs485_exit);
    

    注意:在这个rs485驱动调试过程中,遇到的最大的问题就是电平切换后的延时时间的计算,
    delay_time_us=(1000000/dep->BaudRate)+1;
    delay_time_us=delay_time_us*(dep->parity+dep->stopBits+dep->dataBits+dep->startBits)*LAST_BYTES_FIFO_TO_SHIFTER;

    为了不增加驱动负担,可以把延时时间计算好之后,直接在用户空间调用,比如usleep(8500);

    2.测试程序

    #include <stdio.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <errno.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <termios.h>
    #include <stdlib.h>
    #include <signal.h>
    #include <sys/time.h>
    
    int openport(char *strDev)
    {
    
         int fd = open( strDev, O_RDWR|O_NONBLOCK);//O_NDELAY |O_NONBLOCK|O_NOCTTY
    
         if(fd==-1)
         {
             printf("Open Serial Port Device %s error no %d\n",
                    strDev , fd );
             return 0;
         }
         if(fcntl(fd, F_SETFL, 0)<0)
            printf("fcntl failed!\n");
        else
            printf("fcntl=%d\n",fcntl(fd, F_SETFL,0));
         //测试是否为终端设备
         if(isatty(STDIN_FILENO) == 0)
             printf("standard input is not a terminal device\n");
         else
             printf("isatty success!\n");
         printf("fd-open=%d\n",fd);
         return fd;
    }
    
    int setport(int fd, int baud, int databits, int stopbits, int parity)
    {
        int baudrate;
        struct termios newtio;
    
        switch(baud)
        {
        case 300:
            baudrate=B300;
            break;
        case 600:
            baudrate=B600;
            break;
        case 1200:
            baudrate=B1200;
            break;
        case 2400:
            baudrate=B2400;
            break;
        case 4800:
            baudrate=B4800;
            break;
        case 9600:
            baudrate=B9600;
            break;
        case 19200:
            baudrate=B19200;
            break;
        case 38400:
            baudrate=B38400;
        case 57600:
            baudrate=B57600;
            break;
        case 115200:
            baudrate=B115200;
            break;
        default :
                baudrate=B9600;
        break;
        }
    
        tcgetattr(fd,&newtio);
        bzero(&newtio,sizeof(newtio));
        newtio.c_cflag &= ~CSIZE;
    
        switch (databits) //设置数据位数
        {
        case 7:
            newtio.c_cflag |= CS7; //7位数据位
            break;
        case 8:
            newtio.c_cflag |= CS8; //8位数据位
            break;
        default:
            newtio.c_cflag |= CS8;
            break;
        }
    
        switch (parity) //设置校验
        {
        case 'n':
        case 'N':
            newtio.c_cflag &= ~PARENB;   /* Clear parity enable */
            newtio.c_iflag &= ~INPCK;     /* Enable parity checking */
            break;
        case 'o':
        case 'O':
            newtio.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/
            newtio.c_iflag |= INPCK;             /* Disnable parity checking */
            break;
        case 'e':
        case 'E':
            newtio.c_cflag |= PARENB;     /* Enable parity */
            newtio.c_cflag &= ~PARODD;   /* 转换为偶效验*/
            newtio.c_iflag |= INPCK;       /* Disnable parity checking */
            break;
        case 'S':
        case 's':  /*as no parity*/
            newtio.c_cflag &= ~PARENB;
            newtio.c_cflag &= ~CSTOPB;break;
        default:
            newtio.c_iflag &= ~INPCK;     /* Enable parity checking */
            break;
        }
    
        switch (stopbits)//设置停止位
        {
        case 1:
            newtio.c_cflag &= ~CSTOPB;  //1
            break;  //请到HTTp://www.timihome.net访问
        case 2:
            newtio.c_cflag |= CSTOPB;  //2
            break;
        default:
            newtio.c_cflag &= ~CSTOPB;
            break;
        }
    
        newtio.c_cc[VTIME] = 0;
        newtio.c_cc[VMIN] = 13;
        newtio.c_cflag   |=   (CLOCAL|CREAD);
        newtio.c_oflag|=OPOST;
        newtio.c_iflag   &=~CRTSCTS;
        newtio.c_iflag   &=~(IXON|IXOFF|IXANY);
        cfsetispeed(&newtio,baudrate);
        cfsetospeed(&newtio,baudrate);
        tcflush(fd, TCIFLUSH);
    
        if (tcsetattr(fd,TCSANOW,&newtio) != 0)
        {
            return -1;
        }
    
        return 0;
    }
    
    int readport(int fd, char *buf, int maxLen)//读数据,参数为串口,BUF,长度
    {
        char szBuf[15] = {0};
        int nLen = 0;
    
        nLen = read(fd, buf, maxLen);
    
        if(nLen > 0)
        printf("\n nLen = %d\n", nLen);
    
        else if(nLen < 0)
        {
            printf("Read uart data failed  \r\n");
            return -1;
        }
        return nLen;
    }
    
    int writeport(int fd, char *buf, int len)  //发送数据
    {
        int wrnum = 0;
    
        wrnum = write(fd, buf, len);
    
        if(wrnum == len)
        {
            printf("write uart data success  \r\n");
            return wrnum;
    
        }
        else
        {
            printf("write uart data failed  \r\n");
            return -1;
        }
    
    }
    
    // 关闭串口
    void closeport(int fd)
    {
        close(fd);
    }
    
    int main(int argc, unsigned long *argv[])
    {
         int ret, i;
         int fd_485, fd_uart;
         int write_buf_size, read_buf_size;
         char write_buf[15] = {0X69, 0XA1, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0XC8};
             char read_buf[15];
    
         fd_uart = openport("/dev/ttySU4");
         if(fd_uart==-1)
         {
              perror("The /dev/ttySU4 open error.");
              exit(1);
         }
    
         if((fd_485=open("/dev/rs485driver",O_RDONLY | O_NONBLOCK))<0)
         {
              perror("can not open device rs485driver\n");
              exit(1);
         }
         ret = setport(fd_uart, 19200, 8, 1, 'N');
         if(ret < 0)
         {
                  printf("Set Serial Port failed .\r\n");
                  return 0;
         }
    
         while(1)
         {              
              ret=ioctl(fd_485,0,NULL);//send
              write_buf_size=writeport(fd_uart,write_buf,15);
              if(write_buf_size<0)
                   return;
              usleep(8320);
              ioctl(fd_485,1,NULL);
              read_buf_size=read(fd_uart,read_buf,15);
    
              if(read_buf_size>0)
              {
                   printf("\n");
                   printf("read_buf_size len:%d",read_buf_size);
                   printf("      ");
                   for(i=0;i<read_buf_size;i++)
                        {
                        printf("0x%02x",read_buf[i]);
                        }
                   printf("\n");
              }else
                   printf("Timeout\n");
              printf("/dev/ttySU4 has received %d chars!\n",read_buf_size);    
              fflush(stdout);                             
         }
         closeport(fd_uart);
    
         return 0;
    }
    

    三。小结

    以上驱动程序和测试程序比较简单,只适合在AM1808平台使用,希望可以对同样在此平台开发的朋友们有点帮助吧。

    展开全文
  • USB-RS485驱动.rar

    2021-06-04 10:23:02
    USB-RS485驱动
  • 友善6410开发板RS232改RS485驱动,可以经过适当改动应用到其他开发板
  • usb转rs485驱动程序

    2021-07-26 03:00:32
    usb转rs485驱动程序是一款专业的USB编程电缆驱动,通过电脑的USB接口模拟成传统的串行口,实现编程电缆和plc等设备的连接通信。如果您的电脑缺少这款驱动,下载安装一下就可以正常使用了,具体的安装教程可以参考...

    usb转rs485驱动程序是一款专业的USB编程电缆驱动,通过电脑的USB接口模拟成传统的串行口,实现编程电缆和plc等设备的连接通信。如果您的电脑缺少这款驱动,下载安装一下就可以正常使用了,具体的安装教程可以参考下文,需要的朋友赶快下载吧!

    10612752eeaced30b04622e7e9f094f8.png

    软件功能

    1、支持的操作系统Windows2000/Windows XP

    2、完全兼容USB V1.1和USB CDC V1.1规范

    3、USB总线供电(非隔离电缆)、或USB总线供电与PLC的编程口同时供电(隔离型电缆)

    4、波特率:300bps~1Mbps自动适应

    5、每台PC只支持一根USB编程电缆

    使用说明

    将USB转换线插入电脑的USB接口中,系统会提示检测到新设备并出现新硬件添加向导,选择从列表或指定位置安装,手动安装,找到刚才驱动的解压目录,让WINDOWS自动搜索更新驱动即可。

    usb转rs485驱动安装教程

    驱动程序的安装非常简单,只需按提示进行即可,以Windows XP为例,按以下步骤进行:

    1、 打开将要连接USB编程电缆的电脑电源,并确认电脑的USB口已经启动并正常工作。

    2、 将USB编程电缆插入电脑的USB接口,Windows将检测到设备并运行添加新硬件向导帮助你设置新设备,插入驱动程序光盘并单击下一步继续。

    如果Windows没有提示找到新硬件,那么在设备管理器的硬件列表中,展开“通用串行总线控制器”,选择带问号的USB设备,单击鼠标右键并运行更新驱动程序。

    10612752eeaced30b04622e7e9f094f8.png

    3、 Windows将检测到安装信息,显示“DGYCGK USB Composite Device ”设备,并出现如下没有通过Windows徽标测试的信息框,单击“仍然继续”。

    cedc1df37d373e997202699b41976854.png

    4、 继续安装,让Windows拷贝驱动程序文件到你的硬盘。

    b2b9e4b4a53cbb409cf9d33c89347953.png

    5、 当Windows显示完成找到新硬件向导,单击“完成”结束安装。

    83712ab52683242f258310373b78b854.png

    6、 安装完成后,请确认在Windows的“开始\设置\控制面板\系统\硬件\设备管理器”菜单的“端口(COM和LPT)”展开条目中出现“DGYCGK USB to UART Bridge Controller(COMx)”,这个COMx就是USB编程电缆使用的COM口号。以后每次使用只要插入编程电缆就会出现该COM口,你只需在编程软件或通信软件等应用软件中选中该COM口即可。

    ece9e1ca2cf01ca19c94984b15d89dfb.png

    展开全文
  • 003-RS485驱动

    2021-02-01 13:55:10
    完整的485测试程序 包含电路图 程序注释详细
  • 串口+RS485驱动

    千次阅读 2019-08-10 08:08:25
    其实RS485不算什么协议,只是物理层做了差分传输,AB两线的电压差来表示0,1,0,1,可靠性和距离更加好,因此,一个串口外设只能作为半双工使用,而RS232是可以全双工的。 max485模块可以直接与stm的串口外设相连,...

    其实RS485不算什么协议,只是物理层做了差分传输,AB两线的电压差来表示0,1,0,1,可靠性和距离更加好,因此,一个串口外设只能作为半双工使用,而RS232是可以全双工的。
    max485模块可以直接与stm的串口外设相连,但需要一个发送和接收的一个引脚作为控制。(抛开三极管驱动等电路)

    stm32作为master段,一般默认状态是接受的,如果要发送,可以改变控制引脚,发送完立即改为接收即可。

    其他和RS232一模一样。

    展开全文
  • KINCO 伺服驱动器RS232/RS485驱动文件及使用说明rar,KINCO 伺服驱动器RS232/RS485驱动文件及使用说明
  • 捷顺USB-RS485驱动

    2021-04-20 10:48:01
    捷顺USB-RS485驱动是官方提供的一款USB驱动,本站收集提供高速下载,用于解决USB接口不能正常识别,无法正常使用的问题,本动适用于:Windows XP / Windows 7 / Windows 8 / Windows 10 32/64位操作系统。...
  • 2.2RS485驱动设计设计中使用ARM9处理器S3C2440内部集成的UART外设和RSM485模块构建而成,其驱动程序与RS232驱动程序相比多了一个通信方向控制引脚的控制,所以在Linux操作系统中,完全可以借助内核的串口驱动添加...
  • 基于ARM与WINCE的RS485驱动程序设计.pdf
  • \RS485 Drivers\RS485驱动安装说明.doc )
  • 常规的RS485驱动电路,除了需要接TX、RX两个引脚之外,通常还需要接一个或两个使能引脚,最近却发现另一种驱动电路,可以不需要 接使能引脚,能做到硬件上自动使能,自动切换收发状态,这样即节省了硬件资源,软件...
  • 64位win10系统上可以使用的RS485转usb驱动,压缩包内附使用教程。先安装驱动程序,然后更新驱动程序,选择浏览计算机以查找驱动程序,手动安装驱动程序软件,从计算机的设备程序驱动列表中选取,显示兼容硬件,选择...
  • USB转 RS232 或 RS485 驱动,适用于 WindowsXP、Vista、Windows7 等各版本Windows系统.rar
  • IMX6 RS485 驱动移植

    千次阅读 2019-06-17 20:52:54
    1、在内核源码根目录... 6g2c-rs485.patch 2、修改设备树中对应串口设备节点属性,以uart4、使能引脚gpio1_14为例: &uart4 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart4 &p...
  • 【驱动问题】Linux RS485驱动

    千次阅读 2018-01-29 21:49:08
    【驱动问题】Linux RS485驱动
  • UT-885、890、2003A、880、8812等linux usb转rs485驱动
  • 用于64位的win10上的RS485转usb驱动, 楼主实测可用,带详细教程
  • RS485串口驱动源代码

    2022-03-29 08:53:53
    串口驱动是最简单的一种驱动了,在Linux下一切设备都认为是文件,打开设备就像打开文件一样简单,直接上代码 2、RS485.c //---------------------------------------------------------------------------------...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,374
精华内容 2,149
关键字:

rs485驱动