您的位置:首页 > 其它

RS-485总线多机通信

2011-05-03 10:18 309 查看


;KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK RS-485总线多机通信 KKKKKKKKKKKKKKKKKKKK

;Rev:01.01
;DATE:2005.06.16
;作者:KOCOM/黄业胜
;使用芯片:AT89C2051、SP485
;使用晶振:18.432M
;电路描述:简单RC上电复位、P1.7--P1.5分别接LED和限流电阻到VCC,P1.4--P1.2分别接KEY轻触开关到GND

;琑xD连接到SP485的1脚R,
; TxD连接到SP485的4脚D,P3.7连接到SP485的2、3脚RE/DE,SP485的6脚DATA_A接上拉电

;阻4.7KP485的7脚DATA_B接下拉电阻4.7K
; 各分机的DATA_A、DATA_B、GND分别对应并接,再经RS-485/232转换接口连接至PC。
;操作说明:本实验只连接了3台分机和1台PC,分机在上电前先按住KEY1--KDY3中的某一键,以便在程序初始

;化时自动设置相应的默认地址
; 如上电前按住KEY1,则该分机相应地址为12340303H,同理KEY2---12340407,KEY3---12346789.

;功能描述:在1#分机按下KEY2,1#将发送数据呼叫2#,2#进行地址验证和数据校验后,点亮或熄灭相应LED,

;并向1#回复应答信号,
; 1#分机收到应答信号后相应LED闪烁3次。
; PC端串口调试软件可以监测到总线上的数据,并可与各分机双向通信。
; PC设置波特率为9600,8位数据,奇或偶校验,数据收/发以十六进制。
; PC如发55 12 34 04 07 00 00 00 00 92 6D 70 AA呼叫1#分机,选择1#将回复55 00 00 00 00 12

34 04 07 AA 55 07 AA
;呼叫时,选择波特率2400bps,数据位8位,停止位1位,校验位none,流控制none;PC发送数据时,只能采用HEX

发送方式,一个byte一个byte发送!
; PC如发55 12 34 04 07 12 34 03 03 92 6D 74 AA,则会看到1#和2#均有动作。
;********************资源分配****************
;@R0--接收数据时作数据保存地址指针调整
;@R1--发送数据时作发送单元地址指针调整
;********************串口通信知识****************
;工作方式2和方式3都是11位异步收发串行通信,两者的差异仅在波特率上有所不同,方式2:波特率=2

SMOD*Fos/64(smod=0或1)
;方式3:波特率=2 SMOD*Fosc/32*12*(M-T初)
;(1)数据发送 TI=0,发送数据前,先由软件设置TB8,可使用如下指令完成:SETB TB8; CLR TB8;然后再向SBUF

写入8位数据,并以此启动
;串行发送。一帧数据发送完毕后,CPU自动将TI置1,
;(2)数据接收REN=1,RI=0时,启动接收若SM2=0,接收到的8位数据送SBUF,第9位送RB8.若SM2=1,接收到的第9位

数据为0,数据不送SBUF,
;接收到的第9位数据为1,数据送SBUF,第9位送RB8.
;********************串口通信知识****************
;SM0 SM1=11;工作方式3;11位异步收发波特率可变(T1溢出率/n,n=32或16),SM2等于1,表示多机通信,REN接

收控制为1表示应许接收!
;在方式2或方式3中,若SM2=0,串行口以单机发送或接收方式工作,TI和RI以正常方式被激活并产生中断请求


;若SM2=1,RB8=1时,RI被激活并产生中断请求;
;TB8在方式2和方式3时,TB8是发送第9位数据,在多机通信中,以TB8位的状态表示主机发送的是地址还是数

据:TB8=1表示地址,TB8=0表示数据。
;TI发送中断标志位。TI=1,表示已结束一帧数据发送,注意;TI在任何工作方式下都必须有软件清零;
;RI同上
;AT89C51,串行发送中断TI和接收中断RI的中断入口地址都是0023H,因此在中断程序中必须有软件查询TI和RI

的状态才能确定究竟是接收还是发送中断,进而做相应处理。
;电源控制寄存器PCON,其中SMOD;串行口波特率倍增位,在工作方式1~工作方式3时,若SMOD=1,则串行口波

特率增加一倍。若SMOD=0,波特率不加倍!
;多机通讯原理,多机通讯时,主机向从机发送的信息分为地址帧和数据帧两类,以第9位可编程TB8做区分标

志,TB8=0,表示数据;TB8=1,表示地址。多机通讯充分利用
;89C51串行控制寄存器SCON中的多机通讯控制位SM2的特性。当SM2=1时,CPU接收的前8位数据是否送入SBUF取

决于接收的第9位RB8的状态;若RB8=1,将接收到的前8位数据送入
;SBUF,并置位RI产生中断请求;若RB8=0,则接收的前8位数据丢弃。即当从机SM2=1时,从机只能接受主机发送

的地址帧(RB8=1),对数据帧(RB8=0)不予理睬。
;当从机SM2=0时,从机可接收主机发送的所有信息?
;通讯开始时,主机首先发送地址帧,由于各从机的SM2=1

和RB8=1,所以各从机均分别发出串行接收终端请求,通过串行中断服务程序来判断主机发送的地址与本机从地

址是否相符,
;如果相符,则把自身的SM2清0,已准备接收随后传送来的数据帧。其余从机由于地址不符,则仍然保持SM2=1

状态,因而不能接收主机传送来的数据帧。
;多机通信过程:(1)主从机工作与方式2或方式3,主机置SM2=0,REN=1;从机置SM2=1,REN=1.(2)主机置位TB8=1,

向从机发送寻址地址帧,各从机因满足接收条件(SM2=1,RB8=1),从而接收
;到主机发来的地址,并与本机地址比较。(3)地址一致的从机(被寻址机)将SM2清0,并向主机返回地址,共

主机核对,地址不一致的从机(未被寻址机)保持SM2=1;
;(4)主机核对返回地址,若与此前发出的地址一致则准备发送数据;若不一致则返回(2)重新发送地址帧。(5)

主机向从机发送数据,此时主机的TB8=0,只有被选中的那台从机能接收到该数据。
;其他从机则舍弃该数据.(6)本次通信结束后,从机重新置SM2=1,等下次通讯。
LED1 BIT P1.7
LED2 BIT P1.6
LED3 BIT P1.5
KEY1 BIT P3.3
KEY2 BIT P3.4
KEY3 BIT P3.5
RXTX BIT P2.0

RXADDRESS_1 EQU 30H ;接收到的被叫端地址4byte
RXADDRESS_2 EQU 31H
RXADDRESS_3 EQU 32H
RXADDRESS_4 EQU 33H
RXDATA_A1 EQU 34H ;接收到的呼叫端地址4byte
RXDATA_A2 EQU 35H
RXDATA_A3 EQU 36H
RXDATA_A4 EQU 37H
RXDATA_D1 EQU 38H ;接收到的受控指令2byte
RXDATA_D2 EQU 39H
RXDATA_CRC EQU 3AH ;接收到的数据奇偶校验1byte
RXDATA_END EQU 3BH ;接收到的通信结束字AAH 1byte
LOOP4_ADDRESS_SAVE EQU 3CH ;循环接收4个地址码
LOOP8_DATA_SAVE EQU 3DH ;循环接收8个数据码
NOISE1 EQU 3EH ;按键消抖延时参数
LEDFLASH EQU 3FH ;LED闪烁次数
TXADDRESS_1 EQU 40H ;发送出去的终端地址4byte
TXADDRESS_2 EQU 41H
TXADDRESS_3 EQU 42H
TXADDRESS_4 EQU 43H
SELF_ADDRESS1 EQU 44H ;本机地址码存储单元44H--47H
SELF_ADDRESS2 EQU 45H
SELF_ADDRESS3 EQU 46H
SELF_ADDRESS4 EQU 47H
TXDATA_D1 EQU 48H
TXDATA_D2 EQU 49H
TXDATA_CRC EQU 4AH
TXLOOP_CRC8_BYTE12 EQU 4BH ;循环参数,循环校验8位CRC及连续发送12个字节

RX_BIT_START BIT 20H.0;开始接收标志,收到55H后置位,表示允许开始接收地址码
RX_BIT_DATAENABLE BIT 20H.1;允许接收数据标志,经验证本机地址后置位,表示允许接收数据码
FLASHDATA BIT 20H.2;数据刷新标志,当通信接收完成后置位,表示接收完毕,可进入指令控制程


TX_BIT_FINISH BIT 20H.3;当前字节数据发送完毕标志位

ORG 0000H
JMP START
ORG 0023H
JMP SINT
SINT:
JBC RI,RXWK ;若是接收中断,则清除RI标志位,并转接收处理
CLR TI ;若是发送中断,则清除TI标志位
SETB TX_BIT_FINISH;当前字节数据发送完毕,置位标志位
LJMP SEND
RXWK:
MOV A,SBUF
;MOV P0,A;调试时候用
JB RX_BIT_START,ADDRESS_SAVE ;确认收到55H起始字,转入地址码保存程序
CJNE A,#55H,SEND ;在起始标志位为0前,须检测到55H方可进入接收程序
SETB RX_BIT_START
MOV LOOP4_ADDRESS_SAVE,#4 ;为后续保存4个地址码作循环参数
MOV R0,#30H ;地址指针指向保存地址30H
LJMP SEND
ADDRESS_SAVE: ;保存接收到的被叫端地址
JB RX_BIT_DATAENABLE,DATA_SAVE ;若已经验证通过本机地址,则允许接收其后续的数据码
MOV @R0,A ;若未通过地址验证,则继续接收地址码
;MOV P0,A ;调试时候用
INC R0 ;调整保存地址
DJNZ LOOP4_ADDRESS_SAVE,SEND
ADDRESS_CHECK: ;本机地址验证
MOV A,RXADDRESS_1 ;取出接收到的被叫端地址码
CJNE A,SELF_ADDRESS1,ERRO_ADDRESS ;验证第1位地址码,地址不对则退出
MOV A,RXADDRESS_2 ;取出接收到的被叫端地址码
CJNE A,SELF_ADDRESS2,ERRO_ADDRESS ;验证第2位地址码,地址不对则退出
MOV A,RXADDRESS_3 ;取出接收到的被叫端地址码
CJNE A,SELF_ADDRESS3,ERRO_ADDRESS ;验证第3位地址码,地址不对则退出
MOV A,RXADDRESS_4 ;取出接收到的被叫端地址码
CJNE A,SELF_ADDRESS4,ERRO_ADDRESS ;验证第4位地址码,地址不对则退出
OK_ADDRESS_CHECK: ;地址验证通过
CLR SM2 ;允许接收数据中断,其它未经过地址验证的机子在收到数据

码时无法引起中断
SETB RX_BIT_DATAENABLE ;允许接收数据标志置位
MOV LOOP8_DATA_SAVE,#8 ;准备循环接收8位数据码
MOV R0,#RXDATA_A1 ;地址指针指向数据码保存地址,为DATA_SAVE程序段保存数据

作准备
LJMP SEND
ERRO_ADDRESS:
RESET_SIGN_BIT: ;标志位复位
CLR RX_BIT_START ;关闭开始接收标志,使下一次通信重新进入55H起始字验证
SETB SM2 ;只允许接收到的数据为地址码才引起中断
CLR RX_BIT_DATAENABLE ;关闭允许接收数据码标志,使下一次通信须重新进行本机地

址验证方可
LJMP SEND
DATA_SAVE:
MOV @R0,A
INC R0
DJNZ LOOP8_DATA_SAVE,SEND ;8个数据码未接收完毕则继续等待下一个数据
DATA_RECEIVE_OVER: ;数据接收完毕
SETB FLASHDATA ;数据刷新标志置位
LJMP RESET_SIGN_BIT ;转去对通信过程相关的标志位进行复位,并退出
SEND:
RETI

START:
MOV P1,#00H
ACALL DELAY
MOV P1,#0FFH
SET_ADDR1:
JB KEY1,SET_ADDR2
MOV SELF_ADDRESS1,#12H ;本机地址设为1234栋303号
MOV SELF_ADDRESS2,#34H
MOV SELF_ADDRESS3,#03H
MOV SELF_ADDRESS4,#03H
JMP SET_OK
SET_ADDR2:
JB KEY2,SET_ADDR3
MOV SELF_ADDRESS1,#12H ;本机地址设为1234栋303号
MOV SELF_ADDRESS2,#34H
MOV SELF_ADDRESS3,#04H
MOV SELF_ADDRESS4,#07H

JMP SET_OK
SET_ADDR3:
JB KEY3,SET_OK
MOV SELF_ADDRESS1,#12H ;本机地址设为1234栋303号
MOV SELF_ADDRESS2,#34H
MOV SELF_ADDRESS3,#67H
MOV SELF_ADDRESS4,#89H
SET_OK:
MOV P1,#0FFH
MOV SP,#07H
MOV P0,#0FFH

CLR RXTX ;485处于接收状态
CLR FLASHDATA
CLR RX_BIT_START ;关闭开始接收标志,使下一次通信重新进入55H起始字验证
CLR RX_BIT_DATAENABLE ;关闭允许接收数据码标志,通信须进行本机地址验证方可接收数据
CLR TX_BIT_FINISH
;mov scon,#0f0h
;mov tmod,#20h
;mov th1,#0fbh
mov tmod,#20h
mov th1,#0f3h
mov tl1,#0f3h
setb tr1
mov scon,#0f0h ;串口工作方式3,地址/数据验证控制,允许接收
mov pcon,#00h
;SETB SM2 ;只允许地址码引起中断,待与本机地址码验证通过方可由数据码接收

引起中继
SETB EA
SETB ES ;允许串口中断
;clr sm2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;与PC双

向通信试验,取消D/A验证

MAIN:
IFTXDATA:

JNB FLASHDATA,KEY_TEST ;若通信数据接收完毕,则进行数据处理,否则转下一程序段
LJMP RX_COMMAND
KEY_TEST:
JB KEY1,IFK2FX
MOV NOISE1,#00H
K1NIE:
JB KEY1,IFK2FX
DJNZ NOISE1,K1NIE
;MOV A,#91H
MOV TXDATA_D1,#91H
MOV TXADDRESS_1,#12H
MOV TXADDRESS_2,#34H
MOV TXADDRESS_3,#03H
MOV TXADDRESS_4,#03H
ACALL TXDATA
JNB KEY1,$

IFK2FX:
JB KEY2,IFK3FX
MOV NOISE1,#00H
K2NIE:
JB KEY2,IFK3FX
DJNZ NOISE1,K2NIE
;MOV A,#92H
MOV TXDATA_D1,#92H
MOV TXADDRESS_1,#12H
MOV TXADDRESS_2,#34H
MOV TXADDRESS_3,#04H
MOV TXADDRESS_4,#07H
ACALL TXDATA
JNB KEY2,$

IFK3FX:
JB KEY3,ENDIFKEY
MOV NOISE1,#00H
K3NIE:
JB KEY3,ENDIFKEY
DJNZ NOISE1,K3NIE
;MOV A,#93H
MOV TXDATA_D1,#93H
MOV TXADDRESS_1,#12H
MOV TXADDRESS_2,#34H
MOV TXADDRESS_3,#67H
MOV TXADDRESS_4,#89H
ACALL TXDATA
JNB KEY3,$

ENDIFKEY:
JBC FLASHDATA,RX_COMMAND

LJMP END_COMMAND
RX_COMMAND: ;对接收的数据进行处理
CLR FLASHDATA
MOV A,RXDATA_END
CJNE A,#0AAH,NOPASS
MOV B,#0 ;由接收到的8位数据产生1位CRC,暂存于B
MOV TXLOOP_CRC8_BYTE12,#8
MOV R1,#RXADDRESS_1 ;指针指向接收到的数据起始单元
CRC_CHECK:
MOV A,@R1
INC R1
ADD A,#0;奇偶标志每个指令周期都由硬件来置位或清零,以表示累加器A中1的位数的奇偶数,若1的位数为

奇数,则P置位,否则清零;
MOV C,PSW.0;这个P时状态寄存器中的第0位即PSW.0,为基数偶数校验位!
MOV A,B
RLC A
MOV B,A
DJNZ TXLOOP_CRC8_BYTE12,CRC_CHECK
CJNE A,RXDATA_CRC,NOPASS
/*MOV DPTR,#INFORMATION
FIND_HEAD:
INC DPTR
CLR A
MOVC A,@A+DPTR
CJNE A,#0BBH,FIND_HEAD
INC DPTR
CLR A
MOVC A,@A+DPTR
CJNE A,#0C6H,FIND_HEAD
INC DPTR
CLR A
MOVC A,@A+DPTR
CJNE A,#0D2H,FIND_HEAD
INC DPTR
CLR A
MOVC A,@A+DPTR
CJNE A,#0B5H,FIND_HEAD
INC DPTR
CLR A
MOVC A,@A+DPTR
CJNE A,#0CAH,FIND_HEAD
INC DPTR
CLR A
MOVC A,@A+DPTR
CJNE A,#0A4H,FIND_HEAD
;...... ;数据校验!!!!!!
;......
*/
MOV A,RXDATA_D1 ;校验功能码
MOV P1,RXDATA_D1
CPL A
CJNE A,RXDATA_D2,NOPASS
LJMP Checkout_PASS
NOPASS:
LJMP END_COMMAND
Checkout_PASS:
MOV RXDATA_CRC,#0
MOV RXDATA_END,#0 ;清除验证码,防止FLASHDATA被误置位而误进入RX_COMMAND
MOV A,RXDATA_D1 ;取出功能码
CJNE A,#0AAH,NEXD0
MOV LEDFLASH,#3

LEDDISP1:
MOV A,TXDATA_D1
CJNE A,#91H,LEDDISP2
MOV A,#01111111B
LJMP LEDPLY
LEDDISP2:
CJNE A,#92H,LEDDISP3
MOV P1,#10111111B
MOV A,#10111111B
LJMP LEDPLY
LEDDISP3:
CJNE A,#93H,LEDDISP_END
MOV A,#11011111B
LJMP LEDPLY
LEDDISP_END:

LEDPLY:
MOV P1,A
ACALL DELAY
MOV P1,#11111111B
ACALL DELAY
DJNZ LEDFLASH,LEDPLY
LJMP NEXD3
NEXD0:
CJNE A,#91H,NEXD1
;MOV P1,#01111111B
CPL LED1
MOV TXDATA_D1,#0AAH ;接收正确,回复ACK
MOV TXADDRESS_1,RXDATA_A1
MOV TXADDRESS_2,RXDATA_A2
MOV TXADDRESS_3,RXDATA_A3
MOV TXADDRESS_4,RXDATA_A4
ACALL DELAY
ACALL DELAY
ACALL TXDATA
LJMP NEXD3
NEXD1:
CJNE A,#92H,NEXD2
;MOV P1,#10111111B
CPL LED2
MOV TXDATA_D1,#0AAH ;接收正确,回复ACK
MOV TXADDRESS_1,RXDATA_A1
MOV TXADDRESS_2,RXDATA_A2
MOV TXADDRESS_3,RXDATA_A3
MOV TXADDRESS_4,RXDATA_A4
ACALL DELAY
ACALL DELAY
ACALL TXDATA
LJMP NEXD3
NEXD2:
CJNE A,#93H,NEXD3
;MOV P1,#11011111B
CPL LED3
MOV TXDATA_D1,#0AAH ;接收正确,回复ACK
MOV TXADDRESS_1,RXDATA_A1
MOV TXADDRESS_2,RXDATA_A2
MOV TXADDRESS_3,RXDATA_A3
MOV TXADDRESS_4,RXDATA_A4
ACALL DELAY
ACALL DELAY
ACALL TXDATA
LJMP NEXD3
NEXD3:
END_COMMAND:
LJMP IFTXDATA

DELAY:
MOV R5,#4
LOOP1:
DJNZ R7,$
DJNZ R6,LOOP1
DJNZ R5,LOOP1
RET

TXDATA:
MOV TXDATA_CRC,#0
MOV TXLOOP_CRC8_BYTE12,#8
MOV R1,#TXADDRESS_1 ;指针指向待发数据的起始单元
CRC_TakePlace:
MOV A,@R1
INC R1
ADD A,#0
MOV C,P
MOV A,TXDATA_CRC
RLC A
MOV TXDATA_CRC,A
DJNZ TXLOOP_CRC8_BYTE12,CRC_TakePlace

SETB RXTX
MOV A,#55H ;发送起始字55H
SETB TB8;表示地址帧
MOV SBUF,A
JNB TX_BIT_FINISH,$
CLR TX_BIT_FINISH

MOV A,TXADDRESS_1 ;发送终端地址码1
MOV SBUF,A
JNB TX_BIT_FINISH,$
CLR TX_BIT_FINISH

MOV A,TXADDRESS_2 ;发送终端地址码2
MOV SBUF,A
JNB TX_BIT_FINISH,$
CLR TX_BIT_FINISH

MOV A,TXADDRESS_3 ;发送终端地址码3
MOV SBUF,A
JNB TX_BIT_FINISH,$
CLR TX_BIT_FINISH

MOV A,TXADDRESS_4 ;发送终端地址码4
MOV SBUF,A
JNB TX_BIT_FINISH,$
CLR TX_BIT_FINISH

CLR TB8;表示数据帧
MOV A,SELF_ADDRESS1 ;发送本机地址码1
MOV SBUF,A
JNB TX_BIT_FINISH,$
CLR TX_BIT_FINISH

MOV A,SELF_ADDRESS2 ;发送本机地址码2
MOV SBUF,A
JNB TX_BIT_FINISH,$
CLR TX_BIT_FINISH

MOV A,SELF_ADDRESS3 ;发送本机地址码3
MOV SBUF,A
JNB TX_BIT_FINISH,$
CLR TX_BIT_FINISH

MOV A,SELF_ADDRESS4 ;发送本机地址码4
MOV SBUF,A
JNB TX_BIT_FINISH,$
CLR TX_BIT_FINISH

MOV A,TXDATA_D1 ;发送数据原码
MOV SBUF,A
JNB TX_BIT_FINISH,$
CLR TX_BIT_FINISH

;MOV A,TXDATA_D2 ;发送数据反码
MOV A,TXDATA_D1
CPL A
MOV SBUF,A
JNB TX_BIT_FINISH,$
CLR TX_BIT_FINISH

MOV A,TXDATA_CRC ;发送CRC校验字
MOV SBUF,A
JNB TX_BIT_FINISH,$
CLR TX_BIT_FINISH

MOV A,#0AAH ;发送结束字AAH
MOV SBUF,A
JNB TX_BIT_FINISH,$
CLR TX_BIT_FINISH
CLR RXTX
RET

INFORMATION:
DB "KOCOM Communication Part"
DB "Rev:01.01"
DB "DATE:2005.06.16"
DB "R&D/黄业胜"
END
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: