原创 基于51单片机的串行通信(一)

2010-5-24 10:14 4651 9 9 分类: MCU/ 嵌入式

基于51单片机的串行通信(一)<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


51单片机的串行接口有四种工作方式。方式0是将SBUF作为8位同步移位寄存器使用(固定波特率);方式110位异步通信方式(可变波特率);方式211位异步通信方式(固定波特率);方式311位异步通信方式(可变波特率)。方式0的应用可以参见本人以前所写的博文“基于51单片机的串并变换”。本文将介绍方式1的应用。


 


1  硬件设计


AB两台51单片机机通过串行接口相连,B机的七段数码管显示其接收到(A机发出)的数字;而A机的七段数码管则显示其接收到(B机发出)的数字。电路原理图如下所示。  


<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />


点击看大图 


在桌面上双击图标787d03df-0e7b-4d82-b59f-76ef75c90ebe.jpg,打开ISIS 7 Professional窗口(本人使用的是v7.4 SP3中文版)。在器件选择按钮c49e7d27-a247-4ab0-9a0b-e65146e7ce5e.jpg中单击“P”按钮,或执行菜单命令“库”→“拾取元件/符号”,添加如下表所示的元件。



51单片机AT89C51    二片


晶体CRYSTAL 11.0592MHz   二只


瓷片电容CAP 22pF    四只


电解电容CAP-ELEC 10uF   二只


电阻RES 10K         二只


双列电阻网络 Rx8 300R(Ω)   二只


七段数码管7SEG-MPX1-CA   二只


 


在工具栏中单击虚拟仪器按纽471c9f4b-0610-40ae-aacb-1248e867c4d0.jpg,再在对象选择器中选择虚拟终端——VIRTUAL TERMINAL,放置两个虚拟终端。


若用Proteus软件进行仿真,则上图中的晶振和复位电路以及U1U231脚,都可以不画,它们都是默认的。


ISIS原理图编辑窗口中放置元件,再单击工具箱中元件终端图标b7ae5c8d-5eec-4292-b98f-610bd34e9e46.jpg,在对象选择器中单击POWERGROUND放置电源和地。放置好元件后,布好线。左键双击各元件,设置相应元件参数,完成电路图的设计。最后将其保存的文件名为“串1.DSN”。


 


2         软件设计


AB两机进行异步串行通信,当B机接收到A机发出的数据后,一方面通过其数码管显示,另外加上偏移量后发出。当A机收到B机发出的数据后,一方面通过其数码管显示,另外经延时后再发出下一个数据。AB两机的流程图如下所示。



bde87cc8-2559-4850-8179-b9290417af2a.jpg 


AB两台51单片机的异步串行接收采用查询方式,它们详细的C51程序如下所示。


//A机程序


#include<reg51.h>       //包含单片机寄存器的头文件


unsigned char code ddata[]={


    0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,


    0x88,0x83,0xc6,0xa1,0x86,0x8e


    }; //0,1,2,3,4....E,F的段码


 


/************************


函数功能:发送一个字节数据


*************************/


void Send(unsigned char dat)


{


    SBUF=dat;


   While(TI==0)


      ;           //等待


    TI=0;


}


 


/***********************


函数功能:接收一个字节数据


************************/


 unsigned char Receive(void)


{


    unsigned char dat;


    while(RI==0) 


         ;      //等待,直至接收完毕(RI=1


    RI=0;      //为了接收下一帧数据,需将RI0


    dat=SBUF;  //将接收缓冲器中的数据存于dat


    return dat;


}  


 


/**********************


函数功能:延时约150ms


***********************/


 void delay(void)  


{


   unsigned char m,n;


    for(m=0;m<200;m++)


    for(n=0;n<250;n++)     


           ;


 }


 


/*****************


函数功能:主函数


******************/


void main(void)


{


   unsigned char i;


   TMOD=0x20;  //TMOD=0010 0000B,定时器T1工作于方式2


   SCON=0x50;  //SCON=0101 0000B,串口工作方式1,允许接收


   PCON=0x00; 


   TH1=0xfd;   //定时器TH1赋初值,波特率9600


   TL1=0xfd;   //定时器TL1赋初值


   TR1=1;      //启动定时器T1  


    while(1)


   {


        for(i=0;i<8;i++) 


        {


           Send(i);        //发送数据i


           P0=ddata[Receive()]; //将接收到的数据送P0口显示


           delay();   //600ms后发送下一个数据         


           delay();


           delay();


           delay();


        }     


   }


}


 


//B机程序


#include<reg51.h>       //包含单片机寄存器的头文件


unsigned char code ddata[]={


    0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,


    0x88,0x83,0xc6,0xa1,0x86,0x8e


    }; //0,1,2,3,4....E,F的段码


 


/***************************


函数功能:发送一个字节数据


****************************/


void Send(unsigned char dat)


{


    SBUF=dat;


   while(TI==0)


      ;              //等待


    TI=0;


}


 


/***************************


函数功能:接收一个字节数据


****************************/


 unsigned char Receive(void)


{


    unsigned char dat;


    while(RI==0) 


         ;      //等待,直至接收完毕(RI=1


    RI=0;      //为了接收下一帧数据,需将RI0


    dat=SBUF;  //将接收缓冲器中的数据存于dat


    return dat;


}


 


/*****************


函数功能:主函数


******************/


void main(void)


{


   unsigned char dat;


   TMOD=0x20;  //定时器T1工作于方式2


   SCON=0x50;  //SCON=0101 0000B,串口工作方式1,允许接收(REN=1


   PCON=0x00;   


   TH1=0xfd;  //定时器TH1赋初值,波特率9600


   TL1=0xfd;  //定时器TL1赋初值     


   TR1=1;    //启动定时器T1  


   while(1)


   {


       dat=Receive();


       P0=ddata[dat]; //将接收到的数据送P0口显示


       Send(dat+8);      //偏移量为+8        


   }


}


 


打开Keil程序(本人使用的是Keil8.05中文版),执行菜单命令“工程”→“新建工程”创建“串1”项目,并选择单片机型号为AT89C51。执行菜单命令“文件”→“新建”创建文件,输入A机的C语言源程序,保存为“A.C”。在Project Workspace窗口中右击源代码组1,选择“添加文件到组‘源代码组 l’”将源程序“A.C”添加到项目中。


Keil中执行执行菜单命令“工程”→“创建目标”(或点击“创建目标”快捷按钮),编译源程序。如果编译成功,则在“Output Window”的“创建”窗口中显示没有错误,并创建了“A.HEX”文件(注意此时可执行文件的输出路径和文件名)。


然后在Project Workspace窗口中右击源代码组1,选择“删除组‘源代码组 l’和它的文件”删除源程序“A.C”。再次执行菜单命令“文件”→“新建”创建文件,输入B机的C语言源程序,保存为“B.C”。在Project Workspace窗口中右击源代码组1,选择“添加文件到组‘源代码组 l’”将源程序“B.C”添加到项目中。


再次在Keil中执行执行菜单命令“工程”→“创建目标”(或点击“创建目标”快捷按钮),编译源程序。如果编译成功,则在“Output Window”的“创建”窗口中显示没有错误,并创建了“B.HEX”文件(注意此时可执行文件的输出路径和文件名)。


 


3  仿真与调试


关于ProteusKeil的联合仿真调试,可参见我以前所写的博文或其它参考资料。需注意ProteusISISAB机的CPU属性中Program FileKeilμVision3中的路径和文件名要一致。


启动ProteusISIS,并将其放在屏幕的右上角(可将原理图放大到合适大小);再启动KeilμVision3,并将其放在屏幕的左下角。


    Keil中执行菜单命令“调试”→“启动/停止调试”,或直接单击图标b02af464-efa6-44c8-bbc5-24e0a70ca872.jpg进入Keil调试环境。同时,在Proteus ISIS的窗口中可看出Proteus也进入了程序调试状态。


   Keil代码编辑窗口中设置相应断点,断点的设置方法:在需要设置断点语句前双击鼠标左键,可设置断点;再次双击,可取消该断点。


Keil中按F5键(或点击“运行”快捷按钮)运行程序。AB机的七段数码管将分别显示不断变化的数值,同时监视AB机的虚拟终端也将显示本机发出的数据,如下图所示。


点击看大图


<?xml:namespace prefix = w ns = "urn:schemas-microsoft-com:office:word" />


 


或可以点击单步、运行到光标处、全速运行等快捷按钮,以及同时观察工程窗口寄存器页面、存储器窗口等,来进行仿真调试。


AB机的程序调试中,可以按照以下顺序进行:A机的发送程序、B机的接收程序、B机的发送程序、A机的接收程序。然后再进行AB机的联合调试。


 


    本人邮箱:txxyc104@163.com,欢迎来信讨论.


 


 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
9
关闭 站长推荐上一条 /3 下一条