单片机多机通信带校正

发布者:花开堂前最新更新时间:2015-12-24 来源: eefocus关键字:单片机  多机通信  校正 手机看文章 扫描二维码
随时随地手机看文章

一、多机通信原理

    在多机通信中,主机必须要能对各个从机进行识别,在51系列单片机中可以通过SCON寄存器的SM2位来实现。当串口以方式2或方式3发送数据时,每一帧信息都是11位,第9位是数据可编程位,通过给TB8置1或置0来区别地址帧和数据帧,当该位为1时,发送地址帧;该位为0时,发送数据帧。

    在多机通信过程中,主机先发送某一从机的地址,等待从机的应答,所有的从机接收到地址帧后与本机地址进行比较,若相同,则将SM2置0准备接收数据;若不同,则丢弃当前数据,SM2位不变。

二多机通信电路图

此处,U1作为主机,U2为从机1,U3为从机2。

三、C语言程序

(1)主机程序

#include
#include

#define _SUCC_   0x0f//数据传送成功
#define _ERR_    0xf0//数据传送失败
unsigned char Table[9]={0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};
unsigned char Buff[20];  //数据缓冲区
unsigned char temp=0xff;
sbit KEY1=P1^6;
sbit KEY2=P1^7;
//unsigned char addr;

//延时1ms函数
void delay_1ms(unsigned int t)
{
 unsigned int x,y;
 for(x=t;x>0;x--)
  for(y=110;y>0;y--);
}
//缓冲区初始化
void Buff_init()
{
 unsigned char i;    //将Table里的数据放到缓冲区里
 for(i=0;i<9;i++)  
 {
  Buff[i]= Table[i];
  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;i //发送数据
 {
  check=check^Buff[i];
  TB8=0;
  SBUF=Buff[i];   
  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()
{
 Buff_init();
 serial_init();
 while(1)
 {
  if(KEY1==0)
  {
   delay_1ms(5);
   if(KEY1==0)
   {
    while(!KEY1);
    ADDR_data(0x01);
   }
  }
  if(KEY2==0)
  {
   delay_1ms(5);
   if(KEY2==0)
   {
    while(!KEY2);
    ADDR_data(0x02);
   }
  }

 }
}[page]

(2)从机1程序

#include
#include

#define addr     0x01//从机1的地址
#define _SUCC_   0x0f//数据传送成功
#define _ERR_    0xf0//数据传送失败
unsigned char aa=0xff;//主机与从机之间通信标志
unsigned char Buff[20];//数据缓冲区

//串口初始化函数
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;i//接收数据
 {
  while(!RI);
  if(RB8==1)   //若接收到地址帧,则返回0xfe
   return 0xfe;
  Buff[i]=SBUF;   
  check=check^(Buff[i]);
  RI=0;
 }

 while(!RI);    //接收校验字节
 if(RB8==1)    //若接收到地址帧,则返回0xfe
  return 0xfe;
 temp=SBUF;
 RI=0;
      
 check=temp^check;  //将从主机接收到的校验码与自己计算的校验码比对
 if(check!=0)   //校验码不一致,表明数据接收错误,向主机发送错误信号,函数返回0xff
 {
  TI=0;
  TB8=0;
  SBUF=_ERR_;
  while(!TI);
  TI=0;
  return 0xff;
 }
 TI=0;           //校验码一致,表明数据接收正确,向主机发送成功信号,函数返回0x00
 TB8=0;
 SBUF=_SUCC_;
 while(!TI);
 TI=0;
 return 0;

void main()
{
 serial_init();
 while(1)
 {
  SM2=1;              //接收地址帧
  while(aa!=addr)  //从机等待主机请求自己的地址
  {
   RI=0;
   while(!RI);
   aa=SBUF;
   RI=0;
  }

  TI=0;     //一旦被请求,从机返回自己的地址作为应答,等待接收数据
  TB8=0;
  SBUF=addr;
  while(!TI);
  TI=0;

  SM2=0;                  //接收数据帧
  aa=0xff;    //从机接收数据,并将数据保存到数据缓冲区
  while(aa==0xff)
  {
   aa=RECE_data(Buff);
  }
  if(aa==0xfe)
   continue; 
  P1=Buff[1];      //查看接收到的数据
 }
}

(3)从机2程序

#include
#include

#define addr     0x02//从机2的地址
#define _SUCC_   0x0f//数据传送成功
#define _ERR_    0xf0//数据传送失败
unsigned char aa=0xff;//主机与从机之间通信标志
unsigned char Buff[20];//数据缓冲区

//串口初始化函数
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;i//接收数据
 {
  while(!RI);
  if(RB8==1)   //若接收到地址帧,则返回0xfe
   return 0xfe;
  Buff[i]=SBUF;   
  check=check^(Buff[i]);
  RI=0;
 }

 while(!RI);    //接收校验字节
 if(RB8==1)    //若接收到地址帧,则返回0xfe
  return 0xfe;
 temp=SBUF;
 RI=0;
      
 check=temp^check;  //将从主机接收到的校验码与自己计算的校验码比对
 if(check!=0)   //校验码不一致,表明数据接收错误,向主机发送错误信号,函数返回0xff
 {
  TI=0;
  TB8=0;
  SBUF=_ERR_;
  while(!TI);
  TI=0;
  return 0xff;
 }
 TI=0;           //校验码一致,表明数据接收正确,向主机发送成功信号,函数返回0x00
 TB8=0;
 SBUF=_SUCC_;
 while(!TI);
 TI=0;
 return 0;

void main()
{
 serial_init();
 while(1)
 {
  SM2=1;              //接收地址帧
  while(aa!=addr)  //从机等待主机请求自己的地址
  {
   RI=0;
   while(!RI);
   aa=SBUF;
   RI=0;
  }

  TI=0;     //一旦被请求,从机返回自己地址作为应答,等待接收数据
  TB8=0;
  SBUF=addr;
  while(!TI);
  TI=0;

  SM2=0;                  //接收数据帧
  aa=0xff;    //从机接收数据,并将数据保存到数据缓冲区
  while(aa==0xff)
  {
   aa=RECE_data(Buff);
  }
  if(aa==0xfe)
   continue; 
  P1=Buff[2];      //查看接收到的数据
 }
}

关键字:单片机  多机通信  校正 引用地址:单片机多机通信带校正

上一篇:单片机多机通信之变量初始化的重要…
下一篇:单片机的MRC多重加密技术

推荐阅读最新更新时间:2024-03-16 14:41

PIC单片机12F629烧录器电路设计与制作
有人问: IC 烧录能不能也作一个教学呢? 木村豆桃哉在想...用LEAPER-48万用烧录器 1.把手往下扳 2.把IC放上去 3.关上把手 4.选择IC厂牌/编号 5.载入HEX档 6.按下烧录 7.等PASS出现就好了 为什么要教学呢??? 所以...应该是没有万用烧录器的话要怎麽办呢?所以木村豆桃哉决定要来试试看,那个烧录器的 电路 是真还是假.如果不能用的话,不是发佈了错误讯息害人了吗? 但是又想...有万用烧录器可以用,为什麽要再做一个烧录器呢?超级矛盾~ 好奇嘛,做了一个试试看呗... 上网看了原版的线路图...头都晕了 @_@ 原图烧12F629还要修改... 再找找其他简单一点的图吧 在网路上找到一个用Z
[单片机]
PIC<font color='red'>单片机</font>12F629烧录器电路设计与制作
AVR单片机熔丝位问题
初学者对熔丝经常不解,AVR芯片使用熔丝来设定时钟、启动时间、一些功能的使能、BOOT区设定、当然还有最让初学者头疼的保密位,设不好锁了芯片很麻烦。要想使MCU功耗最小也要了解一些位的设定。 1:未编程 0:编程 1.BOD(Brown-out Detection) 掉电检测电路 BODLEVEL(BOD电平选择): 1: 2.7V电平; 0:4.0V电平 BODEN(BOD功能控制): 1:BOD功能禁止;0:BOD功能允许 使用方法:如果BODEN使能(复选框选中)启动掉电检测,则检测电平由BODLEVEL决定。一旦VCC下降到触发电平(2.7v或4.0v)以下,MCU复位;当VCC电平大于触发电平后,经过tTOU
[单片机]
第9课 定时器
在对单片机应用项目进行编程时,经常需要插入一定的延时程序,此时一般有两种方案可选择,一是采用软件手段 插入一段延时程序,二是采用单片机内部的硬件资源 定时器。对于软件手段,我们在前面的课程已经详细讲到过,它最大的缺点就是占用单片机的 机时 ,也就是耗费单片机的 精力 ,从而降低了单片机的工作效率。而定时器则不同,它是单片机内部一个独立的功能模块,定时器一旦设置后,定时器便自动开始计时,当计时时间满后,便产生相应的中断,去处于中断函数内的程序,而在计时这段时间内,定时器和CPU是分别独立工作的,CUP此时就可以有时间去做其它的事情。所以为了提高单片机的工作效率和实现精确的延时,目前几乎所有的半导休生产厂商在设计单片机时,在内部
[单片机]
第9课 定时器
一文详解80C51单片机的指令系统
指令是指示计算机执行某种操作的命令,计算机能识别执行的只能是二进制代码,以二进制代码来描述指令功能的语言,称为机器语言。 由于机器语言不便于人们识别,记忆,理解和使用,因此便对每条机器语言指令用助记符号来形象表示,这就便形成了汇编语言。 一条指令是机器语言的一个语句,包括操作码字段和操作数字段。一台计算机所具有的全部指令的集合,称为这台计算机的指令系统。 不同的微处理器,其指令系统一般是不同的。 80C51单片机指令系统共有111条指令,具体特点如下: 1)执行时间短,单机器周期指令(64条),双机器周期指令(45条),而四机器周期指令只有2条; 2)指令编码字节少,单字节指令(49条),双字节指令(45条)和最长的三字节
[单片机]
一文详解80C51<font color='red'>单片机</font>的指令系统
中颖电子:贸易战影响不大,锂电池管理芯片应用增加
近日,中颖电子接待了来自海通证券、富春投资、六禾投资等18家机构的调研活动,披露了家电智能化产品研发、工控单芯片及锂电池管理芯片销量情况、AMOLED产品线的研发等相关情况。 对于当前中美贸易摩擦对公司的影响,中颖电子表示,美国的贸易对抗清单太广,对我们还是有产生些微影响,但是影响的比例不大,客户本来就有小比例的终端产品是销往美国的。主要体现在短期冲击上,中美贸易摩擦,让客户对未来市场判断趋于谨慎,减少备货订单,影响公司短期的营运增速。由于我国已发展成为全球最大的家电、电子产品制造基地,而且国家政策上积极支持芯片国产化,普遍对客户长期加大国产芯片的采购意愿有所鼓励,国内客户对公司工控单芯片、锂电池管理芯片的接受度不断提高。
[嵌入式]
中颖电子:贸易战影响不大,锂电池管理芯片应用增加
IC Insights预计2020微处理器销售额突破790亿美元
IC Insights日前更新了2020年McClean报告,报告中显示,微处理器销售额预计在2020年增长1.4%,达到近793亿美元,在前一年,2019年市场下降了2.4%,这也是全球处理器市场10年来的收入下降。 年中预测显示,如果明年大部分地区市场的疫苗可用,并且不存在健康隐患的话,那么到2021年,MPU的总销售额将增长8.8%,达到863亿美元的新的年度最高水平。 图1 根据年中更新预测,按终端设备类别划分的处理器市场分布 在处理器市场,传统个人电脑、平板电脑、服务器、超级计算机和所有其他类型计算机中使用的中央处理器(CPU)的销售都增加,主要是由于Covid-19病毒引发的互联网使用量增加。 IC
[嵌入式]
IC Insights预计2020微处理器销售额突破790亿美元
【51单片机快速入门指南】4.3.3: MPU6050使用Mahony AHRS算法实现六轴姿态融合获取四元数、欧拉角
STC89C516 32MHz Keil uVision V5.29.0.0 PK51 Prof.Developers Kit Version:9.60.0.0 上位机:Vofa+ 1.3.10 移植自MPU6050姿态解算——Mahony互补滤波 —— 大写的小写字母 加入了输入数据范围的自动处理,即使更改量程也能正确解算。 源码 为了避免所用RAM超标,部分变量设为idata类型,移植时需注意。 所用MCU为STC89C516 晶振16MHz 6T模式 stdint.h见【51单片机快速入门指南】1:基础知识和工程创建 软件I2C程序见【51单片机快速入门指南】4: 软
[单片机]
【51<font color='red'>单片机</font>快速入门指南】4.3.3: MPU6050使用Mahony AHRS算法实现六轴姿态融合获取四元数、欧拉角
PIC单片机引脚中断程序的设计技巧
1 简 述 所有的中档系列PIC单片机,PORTB端口最高的4个引脚(RB7"RB4)在设为输入模式时,当输入电平由高到低或由低到高发生变化时,可以让单片机产生中断。这就是通常所说的引脚状态变化中断。 在设计引脚中断程序时,有三个需要特别注意的地方。一是,在清除P0RTB中断标志位RBIF之前,必须安排一条必不可少的,以PORTB端口数据寄存器PORTB为源寄存器的读操作指令。放置这一指令的目的有时并不只是为了读取有用的数据,而是为了取消状态变化的硬件信号,以便顺利清除RBIF标志位,为下一次中断做好准备。二是,由于端口PORTB是引脚电子变化中断,即无论引脚出现上升沿还是下降沿都会产生中断请求,所以必须处理好不需要的虚假
[应用]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
502 Bad Gateway

502 Bad Gateway


openresty
设计资源 培训 开发板 精华推荐

502 Bad Gateway

502 Bad Gateway


openresty
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

502 Bad Gateway

502 Bad Gateway


openresty
502 Bad Gateway

502 Bad Gateway


openresty
502 Bad Gateway

502 Bad Gateway


openresty
随便看看
    502 Bad Gateway

    502 Bad Gateway


    openresty
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
502 Bad Gateway

502 Bad Gateway


openresty