这是rs485通信协议等资料,本人在此共享出来,谢谢
一、RS485基本知识
RS-485接口芯片已广泛应用于工业控制、仪器、仪表、多媒体网络、机电一体化产品等诸多领域。可用于RS-485接口的芯片种类也越来越多。如何在种类繁多的接口芯片中找到最合适的芯片,是摆在每一个使用者面前的一个问题。RS-485接口在不同的使用场合,对芯片的要求和使用方法也有所不同。使用者在芯片的选型和电路的设计上应考虑哪些因素,由于某些芯片的固有特性,通信中有些故障甚至还需要在软件上作相应调整,如此等等。希望本文对解决RS-485接口的某些常见问题有所帮助。
1 RS-485接口标准
传输方式:差分
传输介质:双绞线
标准节点数:32
最远通信距离:1200m 共模电压最大、最小值:+12V;-7V
差分输入范围:-7V~+12V
接收器输入灵敏度:±200mV
接收器输入阻抗:≥12kΩ
2 节点数及半双工和全双工通信
rs485仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
-
- /****************************************/
- /* Copyright (c) 2017, 通信工程学院 */
- /* All rights reserved. */
- /****************************************/
- #include "RS485.h"
- //主函数
- void main(void)
- {
- uchar type;
- Init();//初始化
-
- while (1)
- {
- if (RecvData(&type)==0) // 接收帧错误或者地址不符合,丢弃
- continue;
-
- switch (type)
- {
- case ACTIVE: // 主机询问从机是否在位
- SendData(READY,0,StatusBuf); // 发送READY指令
- break;
- case GETDATA: // 主机读设备请求
- ClrStatusBuf();
- GetStat(); // 数据采集函数
- SendData(SENDDATA,strlen(StatusBuf),StatusBuf);
- break;
- default:
- break; // 指令类型错误,丢弃当前帧
- }
- }
- }
- //初始化
- void Init(void)
- {
- P1 = 0xFF;
- DevNo = (P1&0x00111111); // 读取本机设备号
- TMOD = 0x20;//定时器T1,工作方式2,自动重装
- SCON = 0x50;//串口通信工作方式1,允许接收
- TH1 = 0xFD;//波特率9600
- TL1 = 0xFD;
- TR1 = 1;
- PCON = 0x00;// SMOD=0,波特率不加倍
- EA = 0;
-
- }
- //接收数据帧函数,实际上接收的是主机的指令
- //*type指令类型
- bit RecvData(uchar *type)
- {
- uchar tmp,rCount,i;
- uchar r_buf[RECFRMMAXLEN]; // 保存接收到的帧
- uchar FlagRecvOver; // 一帧接收结束标志
- uchar FlagStartRec; // 一帧开始接收标志
- uchar CheckSum; // 校验和
- uchar DataLen; // 数据字节长度变量
-
- //禁止发送,允许接收
- DE = 0;
- RE = 0;
- //接收一帧数据
- rCount = 0;
- FlagStartRec = 0;
- FlagRecvOver = 0;
-
- while (!FlagRecvOver)
- {
- RI = 0;
- while (!RI);
- tmp = SBUF;
- RI=0;
- …………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
- ,其数值为0x24
- if ((!FlagStartRec) && (tmp == 0x24))
- {
- FlagStartRec = 1;
- }
- if (FlagStartRec)
- {
- r_buf[rCount] = tmp;
- rCount ++;
-
- //判断是否收到字符'*',其数值为0x2A,根据接收的指令设置相应标志位
- if (tmp == 0x2A)
- FlagRecvOver = 1;
- }
- if (rCount == RECFRMMAXLEN) // 帧超长错误,返回0
- return 0;
- }
-
- //计算校验和字节
- CheckSum = 0;
- DataLen = r_buf[3];
-
- for (i=0;i<3+DataLen;i++)
- {
- CheckSum = CheckSum + r_buf[i+1];
- }
-
- //判断帧是否错误
- if (rCount<6) // 帧过短错误,返回0,最短的指令帧为6个字节
- return 0;
-
- if (r_buf[1]!=DevNo) // 地址不符合,错误,返回0
- return 0;
-
- if (r_buf[rCount-2]!=CheckSum) // 校验错误,返回0
- return 0;
- *type = r_buf[2]; // 获取指令类型
- return 1; // 成功,返回1
- }
- //发送数据帧函数
- //type数据类型,len数据长度,*buf数据
- void SendData(uchar type,uchar len,uchar *buf)
- {
- uchar i,tmp;
- uchar CheckSum = 0;
-
- //允许发送,禁止接收
- DE = 1;
- RE = 1;
-
- //发送帧起始字节
- tmp = 0x24;
- Send(tmp);
-
- Send(DevNo);// 发送地址字节,也即设备号
- CheckSum = CheckSum + DevNo;
-
- Send(type); // 发送类型字节
- CheckSum = CheckSum + type;
- Send(len); // 发送数据长度字节
- CheckSum = CheckSum + len;
-
- //发送数据
- for (i=0;i<len;i++)
- {
- Send(*buf);
- CheckSum = CheckSum + *buf;
- buf++;
- }
-
- Send(CheckSum);// 发送校验和字节
- //发送帧结束字节
- tmp = 0x2A;
- Send(tmp);
- }
- //采集数据函数经过简化处理,取固定的10个字节数据
- void GetStat(void)
- {
- StatusBuf[0]=DATA0;
- StatusBuf[1]=DATA1;
- StatusBuf[2]=DATA2;
- StatusBuf[3]=DATA3;
- StatusBuf[4]=DATA4;
- StatusBuf[5]=DATA5;
- StatusBuf[6]=DATA6;
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
RS485通信协议及程序.zip
(1.41 MB, 下载次数: 307)
|