一、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; }