51 單片機(jī)的多機(jī)通信
;51 單片機(jī)的多機(jī)通信,有些特殊。它專有一個控制位 SM2?。
;當(dāng)把 SM2 設(shè)置為 1 后,單片機(jī)的串口,就僅僅接收《第 9 位為 1 的數(shù)據(jù)》。
;對方發(fā)送的《第 9 位為 0 的數(shù)據(jù)》 ,接收機(jī)的串口是不理會的。
;本來,串行通信的第 9 位數(shù)據(jù),通常都理解成奇偶校驗位,還是可有可無的。
;但是,在 51 單片機(jī)多機(jī)通信的場合,第 9 位的意義就變了,而且還不可缺少。
;嗯,看來,還得把串口設(shè)置成方式 2 或方式 3,這才是《9 位數(shù)據(jù)》的通信方式。
;為了用 T1 控制波特率,還是用方式 3 比較合適。
;
;多機(jī)通信的流程如下:
;
;1.各從機(jī),先設(shè)置 SM2 為 1,處于只接收《第 9 位為 1》的狀態(tài)。
;2.主機(jī),以《第 9 位為 1》的形式發(fā)送一個字節(jié)到全部從機(jī)。
;3.各從機(jī)把收到字節(jié),與本機(jī)的號碼相對比,應(yīng)該只有一臺從機(jī)是相同的。
;4.該從機(jī),可以把自己的 SM2 清零了,此后,它就可以和主機(jī)進(jìn)行雙機(jī)通信。
;5.主機(jī)和該從機(jī)雙機(jī)通信時,應(yīng)該用《第 9 位為 0》的形式,以免被其它從機(jī)竊聽。
;6.當(dāng)該從機(jī)收到表示結(jié)束通信的字節(jié)時,再把自己的 SM2 置 1。
;看到了吧 ?
;SM2=1、SM2=0,都是在從機(jī)中進(jìn)行修改,主機(jī)的 SM2 是 1 還是 0,無所謂。
;
;主機(jī)還是用 SM2=0 吧,省去從機(jī)發(fā)送的時,設(shè)定第九位的麻煩。
;如果非得想要設(shè)定,也可以把第九位當(dāng)做奇偶校驗位。
;
;有一個關(guān)于多機(jī)通信的題目:
;單片機(jī)通信,一個主機(jī),二個從機(jī)。
;主機(jī) P1 口設(shè)置要送的地址,P2 口設(shè)置要送的數(shù)據(jù)。
;從機(jī) P1 口設(shè)置本機(jī)的地址,P2 口顯示主機(jī)發(fā)送過來的數(shù)據(jù)。
;根據(jù)題目要求,做而論道畫出了一個簡化電路圖如下:
;做而論道修改成功的程序如下:
;==============================================
;主機(jī):P1 口設(shè)置要送的地址,P2 口設(shè)置要送的數(shù)據(jù)
;----------------------------------------------
? ? ORG ? 0000H
? ? JMP ? MAIN
? ? ORG ? 0023H
? ? LJMP ?UART_INT
MAIN:?
? ? MOV ? SCON, #0D0H ?;方式3(9位數(shù)據(jù)),雙機(jī)通信
? ? MOV ? TMOD, #20H ? ;T1定時模式2
? ? MOV ? TH1, #0FDH ? ;9600 bps @ 11.0592MHz
? ? MOV ? TL1, #0FDH ? ;
? ? SETB ?TR1 ? ? ? ? ?;啟動T1
? ? SETB ?ES
? ? SETB ?EA
;-----------------------
WAIT:
? ? JB ? ?P3.7, $ ? ? ?;等待按下
? ? MOV ? R6, #20
? ? DJNZ ?R7, $ ? ? ? ?;延時
? ? DJNZ ?R6, $ - 2
? ? JB ? ?P3.7, WAIT ? ;消抖
? ? JNB ? P3.7, $ ? ? ?;等待釋放
;-----------------------
? ? SETB ?TB8 ? ? ? ? ?;和全部從機(jī)通信
? ? MOV ? SBUF, P1 ? ? ;給從機(jī)發(fā)送地址
? ? CLR ? F0
? ? JNB ? F0, $ ? ? ? ?;等待發(fā)送完畢
? ? CLR ? F0
;-----------------------下面等待從機(jī)回信
? ? MOV ? R6, #3
WAIT2:
? ? DJNZ ?R7, $
? ? JB ? ?F0, SEND_DATA;
? ? DJNZ ?R6, WAIT2 ? ?;等三次
? ? SJMP ?WAIT ? ? ? ? ;從機(jī)未開機(jī),不等了
;-----------------------
SEND_DATA:
? ? CLR ? TB8 ? ? ? ? ?;只和叫通的從機(jī)通信
? ? CLR ? F0
? ? MOV ? SBUF, P2 ? ? ;發(fā)送數(shù)據(jù)
? ? SJMP ?WAIT
;-----------------------
UART_INT:
? ? JBC ? TI, ACK1 ? ? ;發(fā)送完畢轉(zhuǎn)移
? ? CLR ? RI
? ? MOV ? A, SBUF
? ? CJNE ?A, #55H, ACK0;回信不正確轉(zhuǎn)移
ACK1: ?SETB ?F0 ? ? ? ?;設(shè)置標(biāo)志
ACK0: ?RETI
;----------------------- ??
END
;==============================================
;==============================================
;從機(jī):P1 口設(shè)置本機(jī)的地址,P2 口顯示主機(jī)發(fā)來的數(shù)據(jù)
;----------------------------------------------
? ? ORG ? 0000H
? ? JMP ? MAIN
? ? ORG ? 0023H
? ? JMP ? RCE
MAIN:
? ? MOV ? SCON, #0F0H ?;方式3(9位數(shù)據(jù)),多機(jī)通信
? ? MOV ? TMOD, #20H ? ;T1定時模式2
? ? MOV ? TH1, #0FDH ? ;9600 bps @ 11.0592MHz
? ? MOV ? TL1, #0FDH ? ;
? ? SETB ?TR1 ? ? ? ? ?;啟動T1
? ? SETB ?ES
? ? SETB ?EA
? ? LJMP ?$
;----------------------- ??
RCE:
? ? JBC ? TI, DIFF
? ? CLR ? RI
? ? JNB ? SM2, DATA1
? ? MOV ? A, SBUF
? ? CJNE ?A, P1, DIFF
? ? CLR ? SM2 ? ? ? ? ?;地址正確,改為雙機(jī)通信
? ? MOV ? SBUF, #55H ? ;發(fā)送回信
DIFF:
? ? RETI
;----------------------- ??
DATA1:
? ? MOV ? P2, SBUF
? ? SETB ?SM2 ? ? ? ? ?;設(shè)為多機(jī)通信
? ? RETI
;--------------------------------------------
END
;============================================
;這個題目的要求比較簡單,主從叫通后,僅僅通信了一個字節(jié)就完事了。
;這么簡單,也可以不用交互式的通信,叫通從機(jī)后,主機(jī)只要再用 TB8=0 發(fā)送一次數(shù)據(jù)即可。