-
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:23usb转rs485驱动 ,485 驱动 Windows Linux Mac WinCE 驱动 都有。 -
RS485驱动开发
2018-11-20 10:24:16RS485串口驱动开发,基于tms320c6748工程实例。有需要的下载 -
关于Linux下AT91SAM9261的RS485驱动
2020-08-19 03:52:10文章简单介绍了linux下AT91SAM9261的RS485驱动 -
usb转rs485驱动
2014-05-03 17:53:13usb转rs485驱动 -
linux RS485驱动
2017-06-28 20:28:44linux RS485驱动,模块化驱动,支持加载与卸载 -
USB转RS485驱动程序
2018-08-10 15:09:24USB转RS485的驱动程序,里面有详细步骤,经过本人实验,是可用的 -
linux下rs485驱动
2011-11-21 11:20:35linux下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:02USB-RS485驱动 -
友善6410开发板RS232改RS485驱动
2015-08-20 22:24:06友善6410开发板RS232改RS485驱动,可以经过适当改动应用到其他开发板 -
usb转rs485驱动程序
2021-07-26 03:00:32usb转rs485驱动程序是一款专业的USB编程电缆驱动,通过电脑的USB接口模拟成传统的串行口,实现编程电缆和plc等设备的连接通信。如果您的电脑缺少这款驱动,下载安装一下就可以正常使用了,具体的安装教程可以参考...usb转rs485驱动程序是一款专业的USB编程电缆驱动,通过电脑的USB接口模拟成传统的串行口,实现编程电缆和plc等设备的连接通信。如果您的电脑缺少这款驱动,下载安装一下就可以正常使用了,具体的安装教程可以参考下文,需要的朋友赶快下载吧!
软件功能
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设备,单击鼠标右键并运行更新驱动程序。
3、 Windows将检测到安装信息,显示“DGYCGK USB Composite Device ”设备,并出现如下没有通过Windows徽标测试的信息框,单击“仍然继续”。
4、 继续安装,让Windows拷贝驱动程序文件到你的硬盘。
5、 当Windows显示完成找到新硬件向导,单击“完成”结束安装。
6、 安装完成后,请确认在Windows的“开始\设置\控制面板\系统\硬件\设备管理器”菜单的“端口(COM和LPT)”展开条目中出现“DGYCGK USB to UART Bridge Controller(COMx)”,这个COMx就是USB编程电缆使用的COM口号。以后每次使用只要插入编程电缆就会出现该COM口,你只需在编程软件或通信软件等应用软件中选中该COM口即可。
-
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
2019-11-01 23:05:24KINCO 伺服驱动器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位操作系统。... -
rs485驱动设计 - 基于ARM9与LINUX的RS485总线的通信接口设计
2021-05-12 06:07:052.2RS485驱动设计设计中使用ARM9处理器S3C2440内部集成的UART外设和RSM485模块构建而成,其驱动程序与RS232驱动程序相比多了一个通信方向控制引脚的控制,所以在Linux操作系统中,完全可以借助内核的串口驱动添加... -
基于ARM与WINCE的RS485驱动程序设计.pdf
2021-09-21 20:21:07基于ARM与WINCE的RS485驱动程序设计.pdf -
\RS485 Drivers\RS485驱动安装说明.doc )
2012-03-02 21:22:33\RS485 Drivers\RS485驱动安装说明.doc ) -
一种好用的RS485驱动电路
2019-05-27 18:06:00常规的RS485驱动电路,除了需要接TX、RX两个引脚之外,通常还需要接一个或两个使能引脚,最近却发现另一种驱动电路,可以不需要 接使能引脚,能做到硬件上自动使能,自动切换收发状态,这样即节省了硬件资源,软件... -
RS485转usb驱动For x64 win10.zip
2019-09-02 12:32:0764位win10系统上可以使用的RS485转usb驱动,压缩包内附使用教程。先安装驱动程序,然后更新驱动程序,选择浏览计算机以查找驱动程序,手动安装驱动程序软件,从计算机的设备程序驱动列表中选取,显示兼容硬件,选择... -
USB转 RS232 或 RS485 驱动
2013-05-13 10:28:21USB转 RS232 或 RS485 驱动,适用于 WindowsXP、Vista、Windows7 等各版本Windows系统.rar -
IMX6 RS485 驱动移植
2019-06-17 20:52:541、在内核源码根目录... 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驱动
2018-01-17 11:59:01UT-885、890、2003A、880、8812等linux usb转rs485驱动 -
64位win10RS485转usb驱动,实测可用,带教程
2019-03-01 19:25:57用于64位的win10上的RS485转usb驱动, 楼主实测可用,带详细教程 -
RS485串口驱动源代码
2022-03-29 08:53:53串口驱动是最简单的一种驱动了,在Linux下一切设备都认为是文件,打开设备就像打开文件一样简单,直接上代码 2、RS485.c //---------------------------------------------------------------------------------...