通过设置单片机的串口可以方便实现三个或三个以上单片机之间的多机通信,构成主从式多机通信系统。串口通信的电器特性、逻辑电平和各种信息都有其自身的特点。89C51 系列单片机之间通过多机通信进行数据交换时,将串口设置为工作方式2 或者3,数据的接收受到SM2的控制。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下(主机+从机):
- //**************************************************************
- /*****************双机通信主机程序******************************
- *双机通信协议简介:
- 1.主机发送从机地址,例如0x01;
- 2.从机回复地址数据0x01;
- 3.主机发送字符长度len;
- 4.从机回复len;
- 5.主机发送字符串。
- *版本:0.0.1
- *作者:kxm
- *时间:09.06.10
- ***************************************************************/
- //**************************************************************
- #include "target.h"
- #include "key.h"
- #define REG_MAX 10 //缓冲区最大值
- uchar sendBuff[REG_MAX]; //串口缓冲区
- /********************************************************
- *函数名称:send_data_package(uchar address,uchar sendLen)
- *函数功能:向从机发送一个数据包
- *函数入口:从机地址address,发送数据长度sendLen
- *函数出口:无
- *说明:启动数据包发送时,应将数据放缓冲区内
- *********************************************************/
- void send_data_package(uchar address,uchar sendLen)
- {
- uchar temp;
- uchar i;
- TB8=1; //发送地址数据
- send_char(address);
- delay_us(10);
- temp=get_char(); //读取从机地址数据回复
- if(temp!=address) //若回复和发送不同,函数返回
- return;
- TB8=0; //发送数据长度
- send_char(sendLen);
- delay_us(10);
- temp=get_char();
- if(temp!=sendLen)
- return;
- for(i=0;i<sendLen;i++)
- send_char(sendBuff[i]);
- }
- void main()
- {
- uchar keyValueRead;
- uchar keyReg[2]={0x00,0x00};
- uchar c;
- usart0_initial(); //串口初始化
- init_key(); //按键初始化
- while(1)
- {
- keyValueRead=get_key_value();
- if(keyValueRead!=KEY_NULL)
- {
- if(keyValueRead==KEY_ONE)
- c=0x01;
- if(keyValueRead==KEY_TWO)
- c=0x02;
- if(keyValueRead==KEY_THREE)
- c=0x03;
- if(keyValueRead==KEY_FOUR)
- c=0x04;
- if(keyValueRead==KEY_FIVE)
- c=0x05;
- keyReg[1]=keyReg[0];
- keyReg[0]=c;
- sendBuff[0]=keyReg[0]; //将发送给地址为0x02的从机的内容放入发送缓冲
- send_data_package(0x02,0x01); //将缓冲区内容发给0x02从机
- sendBuff[0]=keyReg[1]; //将发送给地址为0x01的从机的内容放入发送缓冲
- send_data_package(0x01,0x01); //将缓冲区内容发给0x01从机
- }
- }
- }
复制代码- #include "Include.h"
- #include "led.h"
- #include "target.h"
- #define machineAddress 0x01 //本从机地址定义
- uchar displayBuff[2]; //从机显示缓冲区,本从机只有一个显示区
- uchar getCharStep;
- void main()
- {
- usart0_init();
- led_init();
- displayBuff[0]=0x00;
- getCharStep=0x00;
- sei();
- while(1)
- {
- ledWrite(displayBuff[0]+'0',0x01,DIGITAL);
- }
- }
- void uart_get_char(void) interrupt 4
- {
- uchar temp;
- static count,i;
- temp=SBUF;
- RI=0;
- RB8=0;
- if(getCharStep==0x00) //第一阶段接收从机地址
- {
- if(temp==machineAddress) //地址相符
- {
- send_char(temp); //回复主机
- SM2=0; //进入接收数据阶段
- }
- else
- {
- return;
- }
- }
- if(getCharStep==0x01) //第二阶段接收数据长度
- {
- count=temp;
- send_char(temp);
- i=0x01;
- }
- if(getCharStep==0x02) //第三阶段接收数据
- {
- if(i!=count) //本实例实际count=0x01,此段程序为扩展接收多个数据使用
- {
- displayBuff[i-0x01]=temp;
- i++;
- }
- else //接收数据完毕
- {
- SM2=1; //启动地址位接收
- displayBuff[i-0x01]=temp;
- }
- }
- if(getCharStep<0x02)
- getCharStep++;
- else if(SM2==1)
- getCharStep=0x00;
- }
复制代码
所有资料51hei提供下载:
多机通信系统.zip
(33.43 KB, 下载次数: 96)
|