|
通過(guò)設(shè)置單片機(jī)的串口可以方便實(shí)現(xiàn)三個(gè)或三個(gè)以上單片機(jī)之間的多機(jī)通信,構(gòu)成主從式多機(jī)通信系統(tǒng)。串口通信的電器特性、邏輯電平和各種信息都有其自身的特點(diǎn)。89C51 系列單片機(jī)之間通過(guò)多機(jī)通信進(jìn)行數(shù)據(jù)交換時(shí),將串口設(shè)置為工作方式2 或者3,數(shù)據(jù)的接收受到SM2的控制。
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
單片機(jī)源程序如下(主機(jī)+從機(jī)):
- //**************************************************************
- /*****************雙機(jī)通信主機(jī)程序******************************
- *雙機(jī)通信協(xié)議簡(jiǎn)介:
- 1.主機(jī)發(fā)送從機(jī)地址,例如0x01;
- 2.從機(jī)回復(fù)地址數(shù)據(jù)0x01;
- 3.主機(jī)發(fā)送字符長(zhǎng)度len;
- 4.從機(jī)回復(fù)len;
- 5.主機(jī)發(fā)送字符串。
- *版本:0.0.1
- *作者:kxm
- *時(shí)間:09.06.10
- ***************************************************************/
- //**************************************************************
- #include "target.h"
- #include "key.h"
- #define REG_MAX 10 //緩沖區(qū)最大值
- uchar sendBuff[REG_MAX]; //串口緩沖區(qū)
- /********************************************************
- *函數(shù)名稱:send_data_package(uchar address,uchar sendLen)
- *函數(shù)功能:向從機(jī)發(fā)送一個(gè)數(shù)據(jù)包
- *函數(shù)入口:從機(jī)地址address,發(fā)送數(shù)據(jù)長(zhǎng)度sendLen
- *函數(shù)出口:無(wú)
- *說(shuō)明:?jiǎn)?dòng)數(shù)據(jù)包發(fā)送時(shí),應(yīng)將數(shù)據(jù)放緩沖區(qū)內(nèi)
- *********************************************************/
- void send_data_package(uchar address,uchar sendLen)
- {
- uchar temp;
- uchar i;
- TB8=1; //發(fā)送地址數(shù)據(jù)
- send_char(address);
- delay_us(10);
- temp=get_char(); //讀取從機(jī)地址數(shù)據(jù)回復(fù)
- if(temp!=address) //若回復(fù)和發(fā)送不同,函數(shù)返回
- return;
- TB8=0; //發(fā)送數(shù)據(jù)長(zhǎng)度
- 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]; //將發(fā)送給地址為0x02的從機(jī)的內(nèi)容放入發(fā)送緩沖
- send_data_package(0x02,0x01); //將緩沖區(qū)內(nèi)容發(fā)給0x02從機(jī)
- sendBuff[0]=keyReg[1]; //將發(fā)送給地址為0x01的從機(jī)的內(nèi)容放入發(fā)送緩沖
- send_data_package(0x01,0x01); //將緩沖區(qū)內(nèi)容發(fā)給0x01從機(jī)
- }
- }
- }
復(fù)制代碼- #include "Include.h"
- #include "led.h"
- #include "target.h"
- #define machineAddress 0x01 //本從機(jī)地址定義
- uchar displayBuff[2]; //從機(jī)顯示緩沖區(qū),本從機(jī)只有一個(gè)顯示區(qū)
- 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) //第一階段接收從機(jī)地址
- {
- if(temp==machineAddress) //地址相符
- {
- send_char(temp); //回復(fù)主機(jī)
- SM2=0; //進(jìn)入接收數(shù)據(jù)階段
- }
- else
- {
- return;
- }
- }
- if(getCharStep==0x01) //第二階段接收數(shù)據(jù)長(zhǎng)度
- {
- count=temp;
- send_char(temp);
- i=0x01;
- }
- if(getCharStep==0x02) //第三階段接收數(shù)據(jù)
- {
- if(i!=count) //本實(shí)例實(shí)際count=0x01,此段程序?yàn)閿U(kuò)展接收多個(gè)數(shù)據(jù)使用
- {
- displayBuff[i-0x01]=temp;
- i++;
- }
- else //接收數(shù)據(jù)完畢
- {
- SM2=1; //啟動(dòng)地址位接收
- displayBuff[i-0x01]=temp;
- }
- }
- if(getCharStep<0x02)
- getCharStep++;
- else if(SM2==1)
- getCharStep=0x00;
- }
復(fù)制代碼
所有資料51hei提供下載:
多機(jī)通信系統(tǒng).zip
(33.43 KB, 下載次數(shù): 96)
2019-7-24 09:59 上傳
點(diǎn)擊文件名下載附件
|
|