基于RS485的简单现场总线通信系统设计
指导书
1. 课程设计目的
1) 进一步融合大学期间所学的理论知识和实践技能;
2) 提高学生问题分析能力和实际操作能力;
3) 通过完成一个较完整的简单课题,使学生对实际的系统设计与实现有一个初步的认识。
2. 技术指标
A, 单发单收,在发送状态,能够连续发送从0到99的数字;
B, 单发单收,在接收状态,能够接收数据,并在数码管上正确地显示出来;
C, 单发多收,在AB完成的基础上,接上多个接收设备,能够正确发送和接收;
D, 设定一个为主站,其余为从站,每次数据传输都由主站发起,即主站请求从站1发送数据,主站接收到,并显示在数码管上,主站再请求从站2发数据,从站2要能发送数据,并且主站要能收到并显示出来。每个站点要在软件中设定站址。
3. 系统设计方案
3.1整体方案设计
基于RS-485的现场总线通信系统克服了RS232通信距离短的缺陷,已广泛应用于工业控制、仪器、仪表、多媒体网络、机电一体化产品等诸多领域。
为了更好地理解使用RS485总线的方法,我们先简单回顾一下RS232的原理和操作方法。在串行通讯时,要求通讯双方都采用一个标准接口,使不同的设备可以方便地连接起来进行通讯。RS-232-C接口(又称EIA RS-232-C 是目前最常用的一种串行通讯接口。(“RS-232-C中的“-C只不过表示RS-232 的版本,所以与“RS-232简称是一样的)它是在1970年由美国电子工业协会(EIA 联合贝尔系统、调制解调器厂家及计算机终端生产厂家共同制定的用于串行通讯的标准。它的全名是数据终端设备(DTE)和数据通讯设备(DCE)之间串行二进制数据交换接口技术标准。规定采用一个25个脚的DB-25连接器,对连接器的每个引脚的信号内容加以规定,还对各种信号的电平加以规定。后来IBM的PC机将RS-232 简化成了DB-9连接器,从而成为事实标准。而工业控制的RS-232口一般只使用RXD(收)、TXD(发)、GND(地)
三条线。注意DB-9连接器有公头母头之分,一般PC机配有公头。下图是一个C51单片机小系统的原理图(和实验中心的小系统不一样,这里只是起到示意作用)。
几个问题:
1:只用MAX485 逆转电平芯片不用
2:12M晶振需要调整波特率和TH1初值,不能直接用天祥锅锅的模板
3:由于485半双工通讯,所以每个时刻只能有一个终端发送数据,因此MAX485E的输入输出使能端需要实时控制。 代码中为M485, 连接MAX485E的PIN2,PIN3.
源码:
#include<reg52.h> #define Host 0xff #define Guest1 0x01 #define Guest2 0x02 #define Guest3 0x03 #define Guest4 0x04 #define Guest5 0x05 #define Guest6 0x06 #define Guest7 0x07 #define nul 222 sbit M485 = P3^5; unsigned char Master = 1; unsigned char address = Host; unsigned char RxBuff = 0xff; unsigned char digit[17] = { 0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x98, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71, 0xff }; void delayms(int x) { int i, j; for(i = x; i; --i) for(j= 110; j; --j); return ; } void initSCI(void) { SM0 = 0; /*Step 1 : 确定串口通信方式*/ SM1 = 1; TMOD = 0x20; /*step 2: 根据串口通信方式 确定是否设置波特率*/ TH1 = 0xf3; TL1 = 0xf3; TR1 = 1; /*step 3 :启动*/ REN = 1; EA = 1; /*step 4: 是否启用中断函数*/ ES = 1; } void putChar (unsigned char chr)//发送一个字符 { SBUF = chr; } int disp(unsigned char X) { unsigned char i = 0; if( X == nul ) { P0 = 0xff; P1 = 0xfc; } else { P0 = 0xff; P1 = 0xff - (1 << 1); if( (X/10)%10 ) P0 = digit[(X/10)%10]; else P0 = 0xff; P0 = 0xff; P1 = 0xfe; P0 = digit[X%10]; } return 1; } int dispDely(unsigned char X) { int i, j; for(j = 200; j; --j) for(i = 200; i; --i) disp( X ); P0 = 0xff; return 1; } unsigned char checkMode() { if( P2 & 1 ) return 1; if( P2 & 2 ) return 2; if( P2 & 4 ) return 3; if( P2 & 8 ) return 4; return 0; } int Mode1() { unsigned char i = 0; M485 = 1; for(i = 0; i < 100; ++i) { putChar(i); delayms(1000); } return 1; } int Mode2() { M485 = 0; while(1) { if(RxBuff != 0xff) disp(RxBuff); } return 1; } int Mode3() { if( address == Host ) Mode1(); else Mode2(); return 1; } unsigned char get = 0; int Mode4() { unsigned char i = 0; unsigned char foobar = RxBuff; if( address == Host ) { M485 = 1; delayms(5000); for(i = Guest1; i < Guest4; ++i) { M485 = 1; delayms(1000); putChar(i); delayms(10); M485 = 0; delayms(4000); if(RxBuff != foobar) { dispDely(foobar = RxBuff); } } } else { M485 = 0; delayms(5); if( RxBuff == address) { if( !get ) { get = 1; M485 = 1; delayms(100); putChar(address + 50); delayms(10); M485 = 0; } } if( get )disp( address + 50 ); else disp( nul ); } return 1; } int work(unsigned mode) { switch( mode ) { case 1: Mode1(); break; case 2: Mode2(); break; case 3: Mode3(); break; case 4: Mode4(); break; } return 0; } int main() { initSCI(); while(1) { work( checkMode() ); } return 0; } void ser() interrupt 4 { if( RI ) { RI = 0; RxBuff = SBUF; } if( TI ) { TI = 0; } return ; }