《单片机应用与仿真训练》设计报告单片机多机通信姓名:学号:专业班级:指导老师:所在学院:2011年7月5 日摘要本设计是基于AT89S52单片机温度检测传输的三机通信系统,有三个单片机组成,其中一个作为主机(上位机),控制并负责接收来自从机1号和从机2号采集的数据信息,并显示在数码管上。
由主机发送控制信息(通过按键控制),确定是接收来自想要得到各从机数据。
从机1号和2号是数据采集模块,用来采集室内或室外温度信息,并通过通信协议传送给主机。
为保证三机通信可靠性,通信口要有识别功能,51单片机串行口控制寄存器SCON中SM2位正是满足这一要求而设置的。
当串行口以工作方式三工作时,接收和发送的信息都是11位数据,既包含SBUF寄存器传送的8位数据,还包括SCON中可编程第9位数据即TB8或RB8,主机可通过设定TB8是0或1,来区别发送的是地址还是数据。
从机都先将SCON中的SM2设置为1,待主机发送地址信息,与本身的地址对照,如果是,则令从机SM2为0,准备接收主机信息并发送温度信息,如果不是,则继续等待。
主机通过中断口接收数据,处理后显示在数码管上。
此次设计由于只有一个18b20温度传感器,这里用三个任意的数据代替从机2采集温度数据,由于传输距离较短,这里不用MAX232,直接将主机的发送端接从机接收端,主机接收端连接从机发射端,仿真结果正常显示,实验结果正常。
目录1概述 (1)1.1设计概述 (1)1.2多机通信基本原理 (1)1.3 通信协议 (2)2系统总体方案及硬件设计 (3)2.1总体设计方案 (3)2.2硬件电路设计 (3)3软件设计 (7)3.1控制流程图 (7)3.2串行口采集步骤 (7)3.3软件流程图 (8)PROTEUS仿真 (9)课程设计体会 (11)参考文献: (12)附件1:主机A源程序代码 (13)附件2:原理图 (24)1概述1.1设计概述目前在通信领域里,单片机一对一通信已经不能满足人们设计的需要,多机通信已经成为主要通信方式。
单片机多机通信是指两台以上的单片机组成的网络结构,可以通过串行通信方式共同实现对某一过程的控制。
目前单片机多机通信形式较多,常见的有星形、环形,串行总线型通信和主从式多机型四种。
本设计采用的是主从式多机型,它是一种分散性网络结构,具有接口简单、使用灵活等优点。
下图为主从式多机通信示意图:多机通信示意图1.2多机通信基本原理51用于多机通信时必须工作在方式2或方式3。
以方式3为例,每发送一帧数据为11位:1位起始位(0),8位数据位和1位停止位(1),附加的第9位数据在非多机系统中为奇偶校验位,在发送端有SCON的TB8产生,在接收端传送到开关电源模块SCON的RB8。
它还可设定为“0”或“1”作为在MTD2002多机通信中区分数据帧(0标志)还是地址帧(1标志)的标志。
在MCS-51多机系统中有以下协议:所有的各从机均处于听命状态,即SM2=1,以便接收主机发来的地址,当接收到一帧信息的RB8为“1”时,表示主机发送来的是地址信息,所有的从机均发生接收中断,否则中断屏蔽。
当一从机进入相应的中断服务程序,把接收到的地址和本机的地址比较,如果相符合就令其SM2=0,并向主机发回本机地址以作应答,该从机就与主机联通,准备接收主机发来的命令或数据信息,而其他的未被寻址从机保持SM2=1并退出各自的中断服务程序。
这样,只有SM2=0的从机才能接收到主机发送来的数据信息,顺利实现地址帧和数据帧的分离。
被寻址从机在通信完成后重新使SM2=1,并退出中断服务程序,等待下次通信。
1.3 通信协议要实现单片机和PC机的正常通信,必须正确设定它们两者之间的通信方式,保证双方都用相同的波特率、起始位、停止位、奇偶校验位,并且要建立双方通信的应答信号。
单片机既可工作在同步移位寄存器方式下也可工作在UART(通用异步收发器)下。
串行口的通信方式是由特殊功能寄存器SCON来控制的。
其各控制定义如下:SM0,SM1:工作模式设定位;SM2:允许使用方法2、3多机通信控制位;RB8:接收数据第9位;TB8:发送数据第9位;TI:发送中断标志;RI:接收中断标志。
本文中工作方式为3,即9位UART定时器T1作为波特率发生器。
1)串行通信波特率为9600bps;2)帧格式为8位数据位,一位起始位,一位可编程的第9位(即发送和接收的地址/数据位的标志位),一位停止位;3)主机和从机遵循主从原则,主机用呼叫方式选择从机,数据在主机和从机之间双向传递,各从机之间的相互通信需通过主机作为中介;4)主从机之间还应传送一些供它们识别的命令和状态字,如以‘c’表示主机发送从机接收命令,以‘d’表示从机发送主机接收命令等。
2系统总体方案及硬件设计2.1总体设计方案多机通信模块共有四个基本模块组成,一是主单片机,主要功能是控制发送命令和接受从机发送的数据;二是从单片机1,负责采集温度数据,并发送到主机;三是从机2,功能作用同上,但也可以是其他数据,比如空气空气湿度、水分、相关气体含量等;四是显示模块,本设计采用数码管显示,数码管便宜简单、编程容易、易控制,同时硬件电路比较好设计等。
下图为总体设计框图:总体设计方案框图2.2硬件电路设计单片机最小系统有时钟电路、复位电路、电源电路组成,如下图(1)时钟电路:单片机工作时,是一条一条地从ROM中取指令,然后一步一步地执行。
单片机访问一次存储器的时间,称之为一个机器周期,这是一个时间基准。
—个机器周期包括12个时钟周期。
如果一个单片机选择了12MHz晶振,它的时钟周期是1/12us,它的一个机器周期是12×(1/12)us,也就是1us。
没有晶振,就没有时钟周期,没有时钟周期,就无法执行程序代码,单片机就无法工作。
旁边的两个电容叫负载电容。
一般单片机的晶振工作于并联谐振状态,它是根据晶振厂家提供的晶振要求负载电容选值的。
晶振的频率就是在它提供的负载电容下测得的,能最大限度的保证频率值的误差。
两个电容的取值都是相同的,或者说相差不大,如果相差太大,容易造成谐振的不平衡,容易造成停振或者干脆不起振。
(2)复位电路:上电复位电路上图是用作上电复位用的,VCC一上电,由于电容两端电压不能突变,所以RST上为高电平,然后电容放电,RST就为低电平了,放电时间为1/(R10*C),这个时间应该大于三个晶振周期。
而那个开关的作用就是手动复位用的了。
(3)电源电路:电源电路见最小系统中的电源即是,较简单。
(4)显示电路:显示电路由四位共阴数码管组成,其中位选由单片机P2口提供,段选由P0(P0口已上拉电阻)口提供,其中位选处加限流电阻。
(5)温度采集电路:18B20传感器是独特的一线接口,只需要一条口线通信,简化了分布式温度传感应用无需外部元件可用数据总线供电,电压范围为3.0 V至5.5 V 无需备用电源测量温度范围为-55 °C至+125 ℃。
根据DS18B20的通讯协议,主机(单片机)控制DS18B20完成温度转换必须经过三个步骤:每一次读写之前都要对DS18B20进行复位操作,复位成功后发送一条ROM指令,最后发送RAM指令,这样才能对DS18B20进行预定的操作。
复位要求主CPU将数据线下拉500微秒,然后释放,当DS18B20收到信号后等待16~60微秒左右,后发出60~240微秒的存在低脉冲,主CPU收到此信号表示复位成功。
(6)传输电路:上图为MAX232电平转换芯片电路,其主要特点是:1、符合所有的RS-232C技术标准。
2、只需要单一+5V电源供电。
3、片载电荷泵具有升压、电压极性反转能力,能够产生+10V和-10V电压V+、V-。
4、功耗低,典型供电电流5mA 。
5、内部集成2个RS-232C驱动器。
6、高集成度,片外最低只需4个电容即可工作。
由于本次通信是单片机之间的通信,距离较近,此次设计过程中没用,直接将主机的发射口接从机接收口,主机接收口连接从机发射口。
3软件设计3.1控制流程图多机温度检测系统设计流程图主机发送控制命令,确定由哪一个从机传送采集的温度数据,然后经过处理,显示在数码管上。
3.2串行口采集步骤主机发送信息,可以传送到各个从机或指定从机,各从机发送的信息只能被主机接收。
多机通信(关键是地址帧的识别)主机发送:地址帧、数据帧的鉴别是通过第9位数据确定:TB8=1,地址帧,TB8=0,数据帧;从机接收:各从机串行口工作在方式2、方式3下;多机通信标志SM2(SCON.5)=1;检查接收到的第9位RB8(SCON.2),当 RB8=1:地址帧,将地址装入SBUF ,置位RI ,发出接收中断请求;判断主机发送地址温度采集从机1处理传送主机显示温度温度采集从机2处理是否与本机相符,若相符,则将从机SM2清0(变成直通方式),准备接收其后传送来的数据。
RB8=0:数据帧,对SM2=1,RB8=0的从机,接收数据丢弃,而对SM2=0的从机:直通方式,不论RB8是0还是1,都将接受到的数据送SBUF,并发出中断请求。
多机通信的过程总结如下:(1)全部从机串行口工作方式初始化为2或3,置位SM2,允许中断;(2)主机置位TB8,发送要寻址的从机地址;(3)所有的从机均接收主机发送的地址,进入中断进行地址比较;(4)确认寻址从机,自身SM2清0,向主机返回地址供主机核对;(5)主机核对无误,向被寻址从机发送发送命令,通知从机进行一对一数据通信。
3.3软件流程图PROTEUS仿真从机1显示如下:按下开关后,主机发送从机A地址,从机A收到地址和自己相比较,如果正确,则回应主机,然后发送温度数据,如果不正确,则继续等待。
从机B温度显示如下:按下开关后,主机发送从机B地址,从机B收到地址和自己相比较,如果正确,则回应主机,然后发送温度数据,如果不正确,则继续等待。
课程设计体会通过本次课程设计,进一步熟悉了单片机编程原理和数字控制电路技术的相关知识,使自己所学的理论知识得到巩固,并充分认识到了自己所学的专业知识的实用性和重要性,同时对Proteuls操作更加熟练。
过程中遇到了一些困难,如:多机通信协议部分地址和数据的如何安排发送等,显示电路中的驱动是否需要驱动等问题。
经过查找相关资料和科技文献,和电子发烧友的同学们交流,一步步解决所遇到的困难。
但是在解决这些问题的过程无疑是对自己自身专业素质的一种提高,同时也加深自己对专业技术的认识。
这次课程设计,使我看到自身的不足和缺点,也使我学到了如何克服电子电路设计时的困难,希望今后类似这样的课程设计会更多,让我多一些机会锻炼自己的创新能力!参考文献:[1] 康华光.电子技术基础(模拟部分)(第五版).北京:高等教育出版社,2006.[2] 康华光.电子技术基础(数字部分)(第五版).北京:高等教育出版社,2006.[3]单片机原理及应用技术(第一版).中国矿业大学出版社,2008附件1:主机A源程序代码#include <reg51.h>#define uchar unsigned char#define uint unsigned intuchar ch[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; uchar ch1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; uchar Mode;uchar m1,m2,m3,m4;sbit P10 = P1^0;sbit P13 = P1^3;sbit P17 = P1^7;sbit P20 = P2^0;sbit P21 = P2^1;sbit P23 = P2^3;sbit P22 = P2^2;sbit P24 = P2^4;sbit P25 = P2^5;sbit key=P1^4;sbit key0=P1^2;void UART_init(){TMOD = 0x20;TH1 = 0xfd;TL1 = 0xfd;TR1 = 1;SCON = 0xd0;ES = 1;EX0 = 1;IT0 = 1; //INT0下跳触发EA = 1;TI = 0;}void DelayMs(int ms){uchar i;while(ms--)for(i=0; i<120; i++);}void putc_to_SerialPort(uchar c){SBUF = c;while(TI == 0);TI = 0;}void MasterControl(unsigned char Addr)//, unsigned char Comd) {TB8 = 1;putc_to_SerialPort(Addr);DelayMs(50);TB8 = 0;}void delay(int us){ int s;for ( s=0; s<us; s++);}void disp(){//int t1,t2, t0;P0 = 0xff;P0 = ch[m1];P23=0;delay(200);P23=1;P0 = 0xff;P0= ch1[m2];P22=0;delay(200);P22=1;P0 = 0xff;P0 = ch[m3];P24=0;delay(200);P24=1;P0 = 0xff;P0 = ch[0];P20=0;delay(200);P20=1;}com_int(void) interrupt 4{uchar i,k;ES=0;if(RI==1){RI = 0;if(SBUF=='b'){i=i+1;}elseif(SBUF=='d'){k=k+1;}else if(i==1){m1=0;m1=SBUF;i=i+1;}else if(i==2){m2=0;m2=SBUF;i=i+1;} else if(i==3){// i=0;m3=0;m3=SBUF;i=i+1;}else if(i==4){i=0;m4=0;m4=SBUF;}else if(k==1){m1=0;m1=SBUF;k=k+1;}else if(k==2){ m2=0;m2=SBUF;k=k+1;}else if(k==3){ // k=0;m3=0;m3=SBUF;k=k+1;}else if(k==4){ k=0;m4=0;m4=SBUF;}}ES=1;}void main(void){P1 = 0xff;UART_init();Mode = 0;while(1){if(key==0){DelayMs(35);if(key==0){key0==1;P10 = 1;MasterControl('b');//,'O');}}if(key0==0){DelayMs(35);if(key0==0){key==1;P13 = 1;MasterControl('c');}}disp();}}从机B程序代码:#include <reg51.h>#include"DS18B20.H"#include"intrins.h"#define uchar unsigned charuchar m1,m2,m3;uchar RecData;sbit P10 = P1^0;sbit P13 = P1^3;sbit P24 = P2^4;sbit P23 = P2^3;sbit P25 = P2^5;void UART_init(){TMOD = 0x21;TH1 = 0xfd;TL1 = 0xfd;TR1 = 1;SCON = 0xf0;ES = 1;PS = 1;EA = 1;}void DelayMs(int ms){uchar i;while(ms--)for(i=0; i<120; i++);}void delay1(uint ms){uchar y ;while(ms--){for(y = 0 ; y<250 ; y++){_nop_() ;_nop_() ;_nop_() ;_nop_() ;}}}void putc_to_SerialPort(uchar c) {SBUF = c;while(TI == 0);TI = 0;}void dispy(){// P0 = 0xff;P0 = ch[disp[0]];P23=0;delay(60);P23=1;// P0 = 0xff;P0= ch[disp[1]];P25=0;delay(60);P25=1;// P0 = 0xff;P0 = ch[disp[2]];P24=0;delay(60);P24=1;}com_int(void) interrupt 4{ES=0;if(RI){uchar i;RecData = SBUF;RI = 0;if(RB8 == 1){if(RecData == 'b'){SM2 = 0;putc_to_SerialPort('b');delay1(20);for(i=0;i<=3;i++){putc_to_SerialPort(disp[i]);delay1(300);}SM2=1;}else {SM2 = 1;}}}RI=0;TI=0;SM2=1;ES=1;}void main(void){P0 = 0xff;P1 = 0xff;UART_init();// dispy();while(1){dispy();ReadTemperature();}}其中18B20.H文件如下:#define uchar unsigned char#define uint unsigned intsbit DQ =P2^2; //定义通信端口uchar disp[3]; //待显示的数据,高2位整数部分,低2位小数部分//延时函数void delay(unsigned int i){while(i--);}//初始化函数Init_DS18B20(void){uchar x=0;DQ = 1; //DQ复位delay(8); //稍做延时DQ = 0; //单片机将DQ拉低delay(80); //精确延时大于480usDQ = 1; //拉高总线delay(14);x=DQ; //稍做延时后如果x=0则初始化成功x=1则初始化失败delay(20);}//读一个字节ReadOneChar(void){uchar i=0;uchar dat = 0;for (i=8;i>0;i--){DQ = 0; // 给脉冲信号dat>>=1;DQ = 1; // 给脉冲信号if(DQ)dat|=0x80;delay(4);}return(dat);}//写一个字节WriteOneChar(unsigned char dat){unsigned char i=0;for (i=8; i>0; i--){DQ = 0;DQ = dat&0x01;delay(5);DQ = 1;dat>>=1;}delay(4);}//读取温度void ReadTemperature(void){uchar a=0,temp;uchar b=0;Init_DS18B20();WriteOneChar(0xCC); // 跳过读序号列号的操作WriteOneChar(0x44); // 启动温度转换Init_DS18B20();WriteOneChar(0xCC); //跳过读序号列号的操作WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器)前两个就是温度a=ReadOneChar(); //读取温度值低位b=ReadOneChar(); //读取温度值高位temp=b;temp&=0xf0;if(temp==0) //正温{disp[3]=(b<<4)|(a>>4)/100;disp[2]=(((b<<4)|(a>>4))%100)/10;disp[1]=(((b<<4)|(a>>4))%100)%10;disp[0]=((a&0x0f)*625)/1000;}else //负温{if(a==0){a=~a+1;b=~b+1;}else{a=~a+1;b=~b;}disp[3]=22;disp[2]=((b<<4)|(a>>4))/10;disp[1]=((b<<4)|(a>>4))%10;disp[0]=((a&0x0f)*625)/1000;}}附件2:原理图。