单片机多机通信实现 毕业论文.doc_第1页
单片机多机通信实现 毕业论文.doc_第2页
单片机多机通信实现 毕业论文.doc_第3页
单片机多机通信实现 毕业论文.doc_第4页
单片机多机通信实现 毕业论文.doc_第5页
免费预览已结束,剩余18页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

单片机多机通信实现1、 设计要求 三片单片机利用串行口进行串行通信:串行通信的波特率为9600bit/s。串行口工作方式为方式1的单工串行通信。2、 设计方案一个主机和两个从机,主机通过按键选择要通信的从机,按键确认后通过矩阵键盘输入要传输的信息,从机接收主机发送的信息并发回长度校验码给主机,主机确认校验信息是否正确,若正确,主机液晶显示“send:信息”和从机数,从机液晶显示所接收的信息;若错误则主机从发信息,重复前面的步骤。3、 硬件电路设计 3.1 单片机最小系统的设计本系统共用三块单片机,每块单片机均选用at89s52,最小系统也都一样。由于三块单片机的主要任务是通信,为了得到准确的波特率,采用振荡频率为11.0592mhz的晶振,再接两个30pf的瓷片电容即可构成单片机的时钟电路。单片机最小系统电路如下:图31 单片机最小系统电路复位电路也可以换成看门狗电路实现,可使单片机可靠的复位。为了简化电路设计,本系统采用简单方法,可使单片机上电复位,此外可以通过按键手动复位。单片机上电即可复位,r1与c3的充电时间大于两倍的机器周期,使rst引脚有足够长的时间保存高电平,使单片机可靠的复位。正常工作时,按下按键sw1就可以使单片机复位。3.2 矩阵键盘电路设计图32 矩阵键盘电路p1口接44的矩阵键盘,共16个按键,分别为0c及“开始通信”,“选择从机”和“输入信息”键。p1.0p1.3接矩阵键盘的行,p1.4p1.7接矩阵键盘的列。3.3 液晶显示电路设计液晶显示电路如下图:图33 液晶lcd1602显示电路p0口上拉10k8的排阻,自己画的排阻符号如下: 图34 排阻符号排阻具有九个引脚,一个公共端,另外八个脚分别接到需要接上拉电阻的单片机的p0口。排阻相当于8个大小均为10k的电阻,在电路中主要其电平转化作用,通过的电流很小,每只电阻的功耗也很小。如接5v电源,每只电阻的电流约为0.5ma,很小,但是由于p0口是接液晶,不用接排阻也能实现,本着节约的原则在本设计中没有接排阻。主机整体原理图如下: 图35 主机原理图两从机的原理图与主机的原理图仅仅的区别就是没有外接矩阵键盘,其他的都一样。4电源电路设计本系统主要供电为5v直流电,为了获得5v的直流电压和足够大的电流,并能提供两种接口,交流与直流输入都能通用,将电源电路设计成如下形式。图36 电源电路原理图交流输入用15v的变压器,将变压器通过接口插到板子上。直流输入与交流输入类似,都要经过整流桥,确保电解电容c4不会反接,稳压电路公用,用mc7805实现5v直流稳压,最大可输出1a的电流,足以为整个系统供电。c5与c6用于防止稳压块产生自激振荡。c4用于滤波,使输入纹波很小,输出端接电容c7,用于防止输出电压突变。5 多机通信协议的算法设计 5.1 主从机程序设计主机模式流程如下:图37 主机模式通信流程图从机模式通信流程如下:图38 从机模式通信流程图5.2 键盘程序设计1号单片机的按键采用矩阵形式,44的行列矩阵,共16个按键,可以完成多种控制功能。1号单片机的键盘程序包括:按键扫描、获取键值与按键处理几部分。按键处理又包括实现各种功能的函数。由键盘程序负责调度。键盘控制流程如下:图39 按键控制流程图按键扫描采用行扫描法,先输出全零行,再读看是否有按键按下,如有按键,则先消抖动,然后再次确认是否有按键,如果确有按键,再逐行置低电平扫描按下的键的行列位置,最后将按键对应位置的8位二进制码(即低四位表示行号,高四位表示列号)返回;若无按键,则返回0。获取键值函数为switch结构的散转程序,根据按键的行与列得到按键的键值,这里预先定义按键的键值为字符0c、e,cs。以字符形式表示键值利于液晶直接显示。按键处理为多分支结构,每个分支完成一种功能。具体流程如下:图41 按键处理流程图通信方向设置流程如下:图42 通信方向设置流程图从机选择流程如下:图43 从机选择流程图5.3 系统初始化程序设计系统初始化程序包括定时器初始化、串口初始化、发送数据初始化和全局变量初始化。初始化步骤如下: 图44 系统初始化步骤对于1号单片机,还有液晶屏初始化这一步。1号单片机的主程序执行顺序:图45 1号单片机主程序定时器初始化使定时器一工作在方式二,波特率设置为9600b/s,并开中断。串口初始化使串口工作在方式三,9位数据位。发送与接收数据区的开始地址被已经被指定,用指针常量表示。发送数据初始化在发送数据区存放待发送的数据串,以空字符作为结束符。全局变量初始化只需根据需要设置即可。液晶显示程序只许根据需要调用液晶模块内的函数即可,显示以字符形式输出。输出字符的ascii码,液晶显示对应的字符。用指向code区的指针访问待显示的字符数据串来显示。6 结论 本设计解决了多单片机的串行通信问题,通信速度较快并具有一定的检错能力。但检错机制不够精确,难以保证很高的正确率,还需进一步完善。扩展功能:平权式多机通信协议,这样就可解决通信过程中,争用主机权问题,采用优先编码器为核心的主机权分配电路,可以使电路工作可靠稳定。参考文献 1 吕汉兴,祁志勇.mcs51系列单片机多机通信的实现j.仪表技术,1999.32 郭天祥,51单片机c语言教程入门,提高,开发,拓展全攻略,2011.53 叶佩.mcs_51单片机的多机通信方式研究j.计算技术与信息发展,2009.12. 4 杨玉军.单片机多机通信系统可靠性的研究j.河南科学,2002.6.5 林雪每,彭佳红,姚志成.单片机多机通信协议的设计j.单片机开发与应用,2006.2.6 戴仙金.51单片机及其c语言程序开发实例m.北京:清华大学出版社.2008. 7、完成效果a、系统开始工作时的界面:b、选择从机1:传送信息ca6215,结果显示如下:c、选择从机2:传送信息cba62,结果显示如下:d、系统整体图:程序:主机 51单片机多机通信实现#include#include#define uint unsigned int #define uchar unsigned char#define _succ_ 0x0f/数据传送成功#define _err_ 0xf0/数据传送失败unsigned char table16= ;unsigned char table4=welcome!;unsigned char table1=slave is 2;unsigned char table2=slave is 1;unsigned char table316=send:;unsigned char buff20; /数据缓冲区unsigned char temp=0xff;sbit rs=p26; /1602的数据/指令选择控制线 sbit rw=p25; /1602的读写控制线 sbit en=p27; /1602的使能控制线 /void jian()sbit key1=p32;sbit key2=p33;uchar start,add;void delay_1ms(unsigned int t);void jian() ; /unsigned char addr;/延时1ms函数void delay_1ms(unsigned int t) unsigned int x,y; for(x=t;x0;x-) for(y=110;y0;y-);void delay11()/延时程序 uint i,j; for(i=0;i=2;i+) for(j=0;j0;x-) for(y=110;y0;y-); void lcd_wcom(uchar com) /1602写命令函数 rs=0; /选择指令寄存器 rw=0; /选择写 p0=com; /把命令字送入p2 delay(5); /延时一小会儿,让1602准备接收数据 en=1; /使能线电平变化,命令送入1602的8位数据口 en=0; void lcd_wdat(uchar dat) /1602写数据函数 rs=1; /选择数据寄存器 rw=0; /选择写 p0=dat; /把要显示的数据送入p2 delay(5); /延时一小会儿,让1602准备接收数据 en=1; /使能线电平变化,数据送入1602的8位数据口 en=0; void lcd_init() /1602初始化函数 lcd_wcom(0x38); /8位数据,双列,5*7字形 lcd_wcom(0x0c); /开启显示屏,关光标,光标不闪烁 lcd_wcom(0x06); /显示地址递增,即写一个数据后,显示位置右移一位 lcd_wcom(0x01); /清屏 /缓冲区初始化void buff_init() unsigned char i; /将table里的数据放到缓冲区里 for(i=0;i9;i+) buffi= tablei; delay_1ms(100); /串口初始化函数void serial_init() tmod=0x20; /定时器1工作于方式2 th1=0xfd; tl1=0xfd; /波特率为9600 pcon=0; scon=0xd0; /串口工作于方式3 tr1=1; /开启定时器 ti=0; ri=0;/发送数据函数void send_data(unsigned char *buff) unsigned char i; unsigned char lenth; unsigned char check; lenth=strlen(buff); /计算数据长度 check=lenth; ti=0; /发送数据长度 tb8=0; /发送数据帧 sbuf=lenth; /发送长度 while(!ti); ti=0; for(i=0;ilenth;i+) /发送数据 check=checkbuffi; tb8=0; sbuf=buffi; while(!ti); ti=0; tb8=0; /发送校验字节 sbuf=check; while(!ti); ti=0; /向指定从机地址发送数据void addr_data(unsigned addr) while(temp!=addr) /主机等待从机返回其地址作为应答信号 ti=0; /发送从机地址 tb8=1; /发送地址帧 sbuf=addr; while(!ti); ti=0; ri=0; while(!ri); temp=sbuf; ri=0; temp=_err_; /主机等待从机数据接收成功信号 while(temp!=_succ_) send_data(buff); ri=0; while(!ri); temp=sbuf; ri=0; void main() uchar m; lcd_init(); lcd_wcom(0x80); /显示地址设为80h(即00h,)上排第一位 for(m=0;msizeof(table4)-1;m+) /将table中的数据依次写入1602显示 lcd_wdat(table4m); delay(4); delay_1ms(3000); serial_init(); while(1) jian(); lcd_wcom(0x80); /显示地址设为80h(即00h,)上排第一位 for(m=0;msizeof(table)-1;m+) /将table中的数据依次写入1602显示 lcd_wdat(tablem); delay(4); if(add!=0) lcd_wcom(0x80+40); /显示地址设为80h(即00h,)上排第一位 for(m=0;msizeof(table1)-1;m+) /将table中的数据依次写入1602显示 lcd_wdat(table1m); delay(4); else lcd_wcom(0x80+40); /显示地址设为80h(即00h,)上排第一位 for(m=0;msizeof(table2)-1;m+) /将table中的数据依次写入1602显示 lcd_wdat(table2m); delay(4); if(start!=0) for(m=0;msizeof(table)-1;m+)table3m+5=tablem; buff_init();lcd_wcom(0x80); for(m=0;msizeof(table3)-1;m+) /将table中的数据依次写入1602显示 lcd_wdat(table3m); delay(4); if(add!=0) addr_data(0x01); elseaddr_data(0x02); void jian() /键盘的扫描 static uchar temp,flag,num,wei; p1=0xef; /选中其中的第一列 temp=p1; temp&=0x0f; if(temp!=0x0f) delay11();/延时10ms,消抖 temp=p1; temp&=0x0f; if(temp!=0x0f) switch(temp) case 0x0e: num=0;wei+; break;/0 case 0x0d: num=1; wei+; break;/1 case 0x0b: num=2;wei+; break;/2 case 0x07: num=3;wei+; break;/3 while(temp!=0x0f) /松手检测 temp=p1; temp&=0x0f; p1=0xdf; /选中第二列 temp=p1; temp&=0x0f; if(temp!=0x0f) delay11(); /延时10ms temp=p1; temp&=0x0f; if(temp!=0x0f) switch(temp) case 0x0e: num=4;wei+; break;/4 case 0x0d: num=5;wei+; break;/5 case 0x0b: num=6;wei+; break;/6 case 0x07: num=7;wei+; break;/7 while(temp!=0x0f) /松手检测 temp=p1; temp&=0x0f; p1=0xbf; temp=p1; temp&=0x0f; if(temp!=0x0f) delay11(); /延时10ms temp=p1; temp&=0x0f; if(temp!=0x0f) switch(temp) case 0x0e: num=8;wei+; break;/8 case 0x0d: num=9;wei+; break;/9 case 0x0b: num=a;wei+; break; case 0x07: num=b;wei+; break; /while(temp!=0x0f) 松手检测 /break; / while(temp!=0x0f) /松手检测 temp=p1; temp&=0x0f; p1=0x7f; temp=p1; temp&=0x0f; if(temp!=0x0f) delay11(); /延时10ms temp=p1; temp&=0x0f; if(temp!=0x0f) switch(temp) case 0x0e: num=c;wei+; break; case 0x0d: start=start; break; case 0x0b: add=add; break; case 0x07:num=c;wei=0;flag=flag; break; while(temp!=0x0f) /松手检测 temp=p1; temp&=0x0f; if(flag!=0)tablewei=num; 从机:从机1程序(从机2的程序只要把从机地址改了就可以其他的都和从机1相同)#include#include#define uint unsigned int #define uchar unsigned char#define addr 0x02/从机1的地址#define _succ_ 0x0f/数据传送成功#define _err_ 0xf0/数据传送失败unsigned char aa=0xff;/主机与从机之间通信标志unsigned char buff20;/数据缓冲区sbit rs=p20; /1602的数据/指令选择控制线 sbit rw=p21; /1602的读写控制线 sbit en=p22; /1602的使能控制线 sbit led1 = p36; /绿色指示灯sbit led2 = p37; /红色指示灯uchar code table=information:; /要显示的内容1放入数组table /uchar code table1=123456789; /要显示的内容2放入数组table1void delay(uint n) /延时函数 uint x,y; for(x=n;x0;x-) for(y=110;y0;y-); void lcd_wcom(uchar com) /1602写命令函数 rs=0; /选择指令寄存器 rw=0; /选择写 p0=com; /把命令字送入p2 delay(5); /延时一小会儿,让1602准备接收数据 en=1; /使能线电平变化,命令送入1602的8位数据口 en=0; void lcd_wdat(uchar dat) /1602写数据函数 rs=1; /选择数据寄存器 rw=0; /选择写 p0=dat; /把要显示的数据送入p2 delay(5); /延时一小会儿,让1602准备接收数据 en=1; /使能线电平变化,数据送入1602的8位数据口 en=0; void lcd_init() /1602初始化函数 lcd_wcom(0x38); /8位数据,双列,5*7字形 lcd_wcom(0x0c); /开启显示屏,关光标,光标不闪烁 lcd_wcom(0x06); /显示地址递增,即写一个数据后,显示位置右移一位 lcd_wcom(0x01); /清屏 /串口初始化函数void serial_init() tmod=0x20; /定时器1工作于方式2 th1=0xfd; tl1=0xfd; /波特率为9600 pcon=0; scon=0xd0; /串口工作于方式3 tr1=1; /开启定时器 ti=0; ri=0;/接收数据函数unsigned char rece_data(unsigned char *buff) unsigned char i,temp; unsigned char lenth; unsigned char check; ri=0; /接收数据长度 while(!ri); if(rb8=1) /若接收到地址帧,则返回0xfe return 0xfe; lenth=sbuf; ri=0; check=lenth; for(i=0;ilenth;i+) /接收数据 while(!ri); if(rb8=1) /若接收到地址帧,则返回0xfe return 0xfe; buffi=sbuf; check=check(buffi); ri=0; while(!ri); /接收校验字节 if(rb8=1) /若接收到地址帧,则返回0xfe return 0xfe; temp=sbuf; ri=0; check=tempcheck; /将从主机接收到的校验码与自己计算的校验码比对 if(check!=0) /校验码不一致,表明数据接收错误,向主机发送错误信号,函数返回0xff ti=0; tb8=0; sbuf=_err_; while(!ti); ti=0;

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论