找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 16024|回复: 1
打印 上一主题 下一主题
收起左侧

掌握单片机双机通信的基本使用和编程方法

[复制链接]
跳转到指定楼层
楼主
ID:360306 发表于 2018-6-27 15:38 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  
课程名称
  
单片机原理及应用
实验课时
4
实验项目
双机通信实验
实验时间
2018.6.13/2018.6.20
指导老师
胡国华
实验成绩

实验目的(本次上机实验所涉及并要求掌握的知识点)
掌握双机通信的基本使用方法,掌握双机通信程序的编程方法
实验环境
Protues仿真软件   KellC51 集成开发环境   微机1
实验内容
实验一:方式一的应用设计
  
一、实验内容
  
单片机甲、乙双机串行通信,双机RXDTXD相互交叉相连,甲机P1口接8个开关,乙机P1口接8个发光二极管。甲机设置为只能发送不能接收的单工方式。要求甲机读入P1口的8个开关的状态后,通过串行口发送到乙机,乙机将接收到的甲机的8个开关的状态数据送入P1口,由P1口的8个发光二极管来显示8个开关的状态。双方晶振均采用11.0592MHz。    
  
二、实验原理及步骤
  
三、电路设计及调试
  
1)实验电路
  
file:///C:/Users/zyt/AppData/Local/Temp/msohtmlclip1/01/clip_image002.jpg
  
2)程序设计及调试
  
甲机:
  
#include  <reg51.h>
  
  #define uchar  unsigned char  
  
  #define uint  unsigned int
  
  void main()
  
  {     
  
         uchar temp=0;
  
      TMOD=0x20;               //设置定时器T1为方式2
  
      TH1=0xfd;                   //波特率9600
  
      TL1=0xfd;
  
      SCON=0x40;                    //串口初始化方式1发送,不接收
  
      PCON=0x00;                    // SMOD=0
  
      TR1=1;                        //启动T1
  
      P1=0xff;               //设置P1口为输入
  
       while(1)
  
      {     
  
            while(TI==0);        //如果TI=0,未发送完,循环等待
  
            TI=0;                    //已发送完,把TI清0
  
                temp=P1;              //读入P1口开关的状态数据
  
            SBUF=temp;}}             //数据送串行口发送
  
乙机:
  
#include  <reg51.h>
  
  #define uchar  unsigned char  
  
  #define uint  unsigned int
  
  void main( )
  
  {     
  
          uchar temp=0;
  
      TMOD=0x20;               //设置定时器T1为方式2
  
      TH1=0xfd;                   //波特率9600
  
      TL1=0xfd;
  
      SCON=0x50;                    //设置串口为方式1接收,REN=1
  
      PCON=0x00;                    //SMOD=0
  
      TR1=1;                        //启动T1
  
      while(1)
  
  {     
  
         while(RI==0);               // 若RI为0,未接收到数据
  
     RI=0;                      //  接收到数据,则把RI清0
  
      temp=SBUF;                  // 读取数据存入temp中
  
     P1=temp;}}            // 接收的数据送P1口控制8个LED的亮与灭
  
实验二:多机通信的应用设计
  
一、实验内容
  
实现主单片机分别与3个从单片机串行通信,原理电路见图。用户通过分别按下开关k1k2k3来选择主机与对应1#2#3#从机串行通信,当黄色LED点亮,表示主机与相应的从机连接成功;该从机的8个绿色LED闪亮,表示主机与从机在进行串行数据通信。如果断开k1k2 k3,则主机与相应从机的串行通信中断。   
  
二、实验原理及步骤
  
1. 实现主、从机串行通信,各从机程序都相同,只是地址不同。
  
串行通信约定如下。
  
 (13台从机的地址为01H03H
  
 (2)主机发出的0xff为控制命令,使所有从机都处于SM2=1的状态。
  
 (3)其余的控制命令:00H—接收命令,01H—发送命令。这两条命令是以数据帧的形式发送的。
  
 (4)从机的状态字如图所示。
  
file:///C:/Users/zyt/AppData/Local/Temp/msohtmlclip1/01/clip_image004.jpg
  
其中:
  
ERRD7位)=1,表示收到非法命令。
  
TRDYD1位)=1,表示发送准备完毕。
  
RRDYD0位)=1,表示接收准备完毕。
  
串行通信时,主机采用查询方式,从机采用中断方式。主机串口设为方式3,允许接收,并置TB81。因只有1个主机,所以主机SCON控制寄存器中的SM2不要置1,故控制字为11011000,即0xd8。   
  
三、电路设计及调试
  
1)实验电路
  
file:///C:/Users/zyt/AppData/Local/Temp/msohtmlclip1/01/clip_image006.jpg
  
2)程序设计及调试
  
//主机程序
  
#include <reg51.h>
  
#include <math.h>
  
sbit switch1=P0^0;               //定义k1P0.0连接
  
sbit switch2=P0^1;        //定义k2P0.1连接
  
sbit switch3=P0^2; //定义k3P0.2连接
   
void main()                  //主函数
  
{
  
       EA=1;                          //总中断允许
  
       TMOD=0x20; //设置定时器T1 定时方式2 自动装载定时常数
  
       TL1=0xfd;                    //波特率设为9600
  
       TH1=0xfd;                                 
  
       PCON=0x00;  //SMOD=0,不倍增
  
       SCON=0xd0;  //SM2设为0TB8设为0
  
       TR1=1;          //启动定时器T1
  
       ES=1;            //允许串口中断
  
       SBUF=0xff;   //串口发送0xff
  
while(TI==0);               //判是否发送完毕
  
       TI=0;                           //发送完毕,TI0
  
      while(1)
  
       {     
  
              delay_ms(100);
  
              if(switch1==0)              //判是否k1按下,k1按下往下执行
  
              {
  
              TB8=1;   //发送的第9位数据为1,送TB8,准备发地址帧
  
              SBUF=0x01;//串口发1#从机的地址0x01以及TB8=1
  
              while(TI==0);               //判是否发送完毕
  
              TI=0;                    //发送完毕,TI0
  
              TB8=0;  //发送的第9位数据为0,送TB8,准备发数据帧
  
              SBUF=0x00;  //串口发送0x00以及TB8=0
  
              while(TI==0); /判是否发送完毕
  
              TI=0;             //发送完毕,TI0
  
              }  
  
if(switch2==0)              //判是否k2按下,k2按下往下执行
  
              {
  
                     TB8=1;          //发送的第9位数据为1,发地址帧
  
                     SBUF=0x02;   //串口发2#从机的地址0x02
  
                     while(TI==0);        /判是否发送完毕
  
                     TI=0;                    //发送完毕,TI0
  
                     TB8=0;                 //准备发数据帧
  
                     SBUF=0x00;         //发数据帧0x00TB8=0
  
                     while(TI==0);        //判是否发送完毕
  
                     TI=0;                    //发送完毕,TI0
  
              }   
  
if(switch3==0)              //判是否k3按下,如按下,则往下执行
  
              {
  
                     TB8=1;          //准备发地址帧
  
                     SBUF=0x03;         //3#从机地址
  
                     while(TI==0);        //判是否发送完毕
  
                     TI=0;                    //发送完毕,TI0
  
                     TB8=0;                 //准备发数据帧
  
                     SBUF=0x00;         //发数据帧0x00TB8=0
  
                     while(TI==0);        //判是否发送完毕
  
                     TI=0;                    //发送完毕,TI0
  
              }
  
       }
  
}   
  
void  delay_ms(unsigned int i)              //函数功能:延时
  
  {
  
  unsigned char j;
  
  for(;i>0;i--)                  
  
         for(j=0;j<125;j++)        
  
         ;
  
  }
  
//从机1串行通信程序
  
#include <reg51.h>
  
#include <math.h>
  
sbit led=P2^0;               //定义P2.0连接的黄色LED
  
bit rrdy=0;      //接收准备标志位rrdy=0,表示未做好接收准备
  
bit trdy=0;     //发送准备标志位trdy=0,表示未做好发送准备
  
bit err=0;        //err=1,表示接收到的命令为非法命令
  
void main()                                //从机1主函数
  
  {
  
         EA=1;     //总中断打开
  
         TMOD=0x20;//定时器1 工作方式2,自动装载,用于串口设置波特率
  
         TL1=0xfd;      
  
         TH1=0xfd;                   //波特率设为9600
  
         PCON=0x00;                // SMOD=0
  
         SCON=0xd0;                //SM2设为0,TB8设为0
  
         TR1=1;                        //启动定时器T1
  
         P1=0xff;                      // 向P1写入全1,8个绿色LED全灭
  
         ES=1;                          //允许串口中断
  
         while(RI==0);        //接收控制指令0xff
  
  if(SBUF==0xff)  err=0; //如果接收到的数据为0xff,err=0,表示正确
  
         else err=1;                    //err=1,表示接收出错
  
         RI=0;                           //接收中断标志清0
  
         SM2=1;                        //多机通讯控制位,SM2置1
  
        while(1);}
  
void int1()  interrupt 4,   //函数功能:定时器T1中断函数
  
  {
  
         if(RI)                           //如果RI=1
  
         {
  
                if(RB8)         //如果RB8=1,表示接收的为地址帧
  
                {
  
                       RB8=0;                        
  
         if(SBUF==0x01)     //如收的数据为地址帧0x01,是本从机的地址
  
                       {
  
                              SM2=0;   //则SM2清0,准备接收数据帧
  
                              led=0;    //点亮本从机黄色发光二极管
  
                       }
  
                }
  
led=1;     // 熄灭本从机黄色发光二极管   
  
         }
  
         RI=0;      
  
         }
  

                delay_ms(50);
  
         P1=0xff;        //熄灭本从机8个绿色发光二极管     
  
  }  
  
void  delay_ms(unsigned int i)      //函数功能:延时
  
  {
  
  unsigned char j;
  
  for(;i>0;i--)                  
  
  for(j=0;j<125;j++)        
  
  ;}
  
//从机2串行通信程序
  
  #include  <reg51.h>
  
  #include  <math.h>
  
  sbit led=P2^0;
  
  bit rrdy=0;
  
  bit   trdy=0;
  
  bit err=0;
  
  void  delay_ms(unsigned int i)
  
  {unsigned char j;
  
  for(;i>0;i--)                  
  
  for(j=0;j<125;j++;}  
  
void main()                         //从机2主程序
  
  {
  
         EA=1;                          //总中断打开
  
         TMOD=0x20;//定时器1 工作方式2 自动装载 用于串口设置波特率
  
         TL1=0xfd;      //SM2设为1, TB8设为0
  
         TR1=1;          //定时器1 打开
  
         P1=0xff;
  
         ES=1;            //允许串口中断
  
         while(RI==0); //接收控制指令 0xff
  
         if(SBUF==0xff) err=0;
  
         else err=1;
  
         RI=0;
  
         SM2=1;
  
        while(1);
  
  }    
  
  void int1()  interrupt 4    //函数功能:串口中断函数         
  
  {if(RI)
  
         {if(RB8)
  
                {RB8=0;
  
                if(SBUF==0x02)
  
                       {SM2=0;
  
                      led=0;
  
                       }
  
                }
  
                else
  
                {      rrdy=1;P1=SBUF;
  
                       SM2=1;led=1;
  
                }
  
                RI=0;      
  
         }
  
         delay_ms(50);
  
         P1=0xff;}   
  
//从机3串行通信程序
  
  #include  <reg51.h>
  
  #include  <math.h>
  
  sbit led=P2^0;
  
  bit rrdy=0;
  
  bit   trdy=0;
  
  bit err=0;
  
  void  delay_ms(unsigned int i)      //函数功能:延时
  
  {unsigned char j;
  
  for(;i>0;i--)                  
  
         for(j=0;j<125;j++);
  
  }   
  
void main()           //从机3主程序
  
  {  EA=1;                    //总中断打开
  
         TMOD=0x20;        //T1方式2,用于串口设置波特率
  
         TL1=0xfd;TH1=0xfd;    //波特率设为9600
  
         PCON=0x00;         //波特率不倍增  0x80 为倍增
  
         SCON=0xf0;         //SM2设为1,TB8设为0
  
         TR1=1;                    //接通T1
  
         P1=0xff;ES=1;
  
         while(RI==0);        //接收控制指令 0xff
  
         if(SBUF==0xff) err=0;
  
         else err=1;
  
         RI=0;SM2=1;
  
     while(1);}    
  
void int1()  interrupt 4    //函数功能:串行口中断函数
  
  {if(RI)
  
         {if(RB8)
  
                {  RB8=0;
  
                if(SBUF==0x03)
  
                {
  
                     SM2=0;led=0;}
  
                }
  
                else
  
                {rrdy=1;P1=SBUF;
  
                SM2=1;led=1; }
  
                RI=0;      }
  
         delay_ms(50);
  
         P1=0xff;}    
  
3)实验中遇到的问题
  
按下单片机相应的按钮,小灯泡不亮。
总结(对上机实验结果进行分析,上机心得体会及改进意见
实验一:按下按钮后,通过开关可以通过开关控制灯泡的亮灭,
  
实验二:串行通信时,主机采用查询方式,从机采用中断方式。主机串行口设为方式3,允许接收,并置TB8为1.因为只有一个主机,所以主机的SCON控制寄存器中的SM2不要置1,故控制字为11011000,即0xd8.这个实验实现主从机的串行通信,各从机的程序都是相同的,只是地址不同。串行通信的约定如下:
  
(1)3台从机的地址为01H~03H。
  
(2)主机发出的0xff为控制命令,使所有从机都处于SM2=1的状态。
  
(3)其余的控制命令:00H—接收命令,01H—发送命令。这两条命令是以数据帧的形式发送的。
  
(4)从机的状态字如图所示。 
  
file:///C:/Users/zyt/AppData/Local/Temp/msohtmlclip1/01/clip_image007.jpg   
  
本次实验增强了我们的探索能力,不意味的依赖答案,而是自己寻求解题思路,在一号的学习中起到了特别大的帮助。本次试验教会我们很多内容,特别是在遇到问题是如何去处理,如何正确的找到问题所在,这才是实验课的核心意义。
  


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:696346 发表于 2020-3-14 23:55 | 只看该作者
求电路图,仿真了,但是不成功。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表