📄 linmac.bak
字号:
_sendCRC: MOV A,R7; LinCRC
CPL A ; A=#0FFH-A
MOV R3,A;_LinLastSent
MOV SBUF,A
__RxReti: AJMP _RxReti
;********************************************************************************
;Evaluating the ID-field
;********************************************************************************
_evaluate_ID:
MOV A,SBUF
MOV LinID,A
ANL LinID,#3FH
RL A
RL A ; ACC = FL,FL,X,X|X,X,P1,P0
; get Frame-Length
MOV LinFrameLength,#2
RLC A
JNC _addRLC ; ---> one additional RLC has to be done
MOV LinFrameLength,#4
RLC A
JNC _getParity
MOV LinFrameLength,#8
ljmp _getParity
_addRLC: RLC A
; ACC = X,X,X,X,P1,P0,C,FL
_getParity: ANL A,#0CH
MOV _Parity,A
_TestParity :
;Parity Check
MOV A,LinID ; renew FrameID in accumulator
ANL A,#17H ; Mask Accumulator for Parity0
MOV C,P ; read Parity from Program Status Word
MOV calcPar0,C ; store Parity 0
MOV A,LinID ;renew FrameID in accumulator
ANL A,#3AH ; Mask Accumulator for Parity1
MOV C,P
CPL C ; odd Parity
MOV calcPar1,C ;store Parity 0
;Parity Ready
;check parity-bits
MOV A,_Parity ; _Parity is in bitadressable RAM ... Bit 2&3 are Par0 & Par1, Bit 5&6 are calcPAr0 and calcPar1
SWAP A
CJNE A,_Parity,_Parity_Error
CLR LinParityError
SETB LinIDreceived
MOV _ByteLeft,LinFrameLength
DEC _ByteLeft
MOV _LinCRC,#0
AJMP _Eventreturn
_Parity_Error:
SETB LinParityError
AJMP _Errorreturn
;#############################################################################
;# UART Tx-routine #
;#############################################################################
IntUARTTx:
PUSH ACC
PUSH PSW
ORL PSW,#18H; : regbank 3
CLR TI
MOV A,LinState
CJNE A,#07H,_TxReti ;test Flags
SETB LinTxData; this Bit indicates, that the node is tranmitting data
;send the first data byte
MOV A,#LinData
ADD A,R6; _ByteLeft
MOV R1,A
MOV SBUF,@R1; send the first Databyte
MOV _LinLastSent,@R1
_TxReti:
POP PSW
POP ACC
RETI
$IF (_HW_SYNC_COUNTER)
;####################################################################################
;# Timer1 ISR #
;####################################################################################
IntTimer1:
PUSH PSW
ORL PSW,#18H; ; use Registerbank 3
CPL TR0 ;enable/disable timer0 for bittiming evaluation
CLR TF1
CLR TR1 ; stop counter
JNB TR0,_LoadNewBaudVal
;start of counter
MOV TH1,#0FFH ;preload counter
MOV TL1,#0FCH
SETB TR1 ;start counter
POP PSW
RETI
$ENDIF
$IF (_SW_SYNC_COUNTER)
;######################################################################################
;# external Int1 ISR #
;######################################################################################
IntExt1:
PUSH PSW
ORL PSW,#18H; ; use Registerbank 3
SETB TR0
DJNZ R4,_counting ; R4 in Registerbak 2 is _SyncEdgeCount
CLR TR0
CLR EX1 ; disable external int
SJMP _LoadNewBaudVal
_counting:
POP PSW
RETI
$ENDIF
;****************************
;calculating and loading the new
;baudrate. Same function for HW or SW counter
_LoadNewBaudval:
PUSH ACC
PUSH B
;calculating the new baudrategenerator reload value from TH0 and TL0
;the formular is:
;THL0/4 with round on the last bit
MOV B,TH0
MOV A,TL0
MOV R0,#2
_div_2_16:
XCH A,B ; divide 16bit-value by 2
CLR C
RRC A ; High-byte
XCH A,B
RRC A ; Low-byte
DJNZ R0,_div_2_16 ; 2 times to divide by 4
JNC _no_round_up ; test if the result has to be round up
INC A ; round up
JNZ _no_high_inc ; test if high-byte also needs to be increased due to the round up
INC B
_no_high_inc:
_no_round_up:
;flush the UART-buffer, so that the next falling edge is interpreted as Start of the Startbit
MOV BRGCON,#2 ; stop the generator
CLR ESR ; disable receive-int
MOV BRGR1,#0 ; maximum baudrate
MOV BRGR0,#0
MOV BRGCON,#3 ;enable baudrategenerator
CLR RI
JNB RI,$ ;wait for next receive-int
;load the calculated value into the baudrategenerator
MOV BRGCON,#2 ;disable baudrategenerator
MOV BRGR1,B ; load high byte
MOV BRGR0,A ; load low byte
MOV BRGCON,#3 ; start generator again
SETB LinSynced
POP B
AJMP _EventReturn ; this Symbol can be found in the Rx-ISR. A little bit cruel to jump into another
; ISR, but at least it safes some byte.
;############################################################################
;# Initialisation Routine #
;############################################################################
InitLinMac:
; reset all Flags
MOV LinState,#0
MOV LinError,#0
;Initialise Baudrategenerator for default baudrate
MOV BRGCON,#2
MOV BRGR0,#BAUDGENELOW
MOV BRGR1,#BAUDGENEHIGH
; put UART to 8-bit mode
ANL PCON,#0BFH
MOV SCON,#050H
ORL PCON,#040H ; Make FE-bit visible
MOV SSTAT,#21H ; seperate Rx and Tx int, Break generates an Int
;initialise Sync-Sequence evaluation
MOV TAMOD,#0 ;set Timer mode
$IF (_HW_SYNC_COUNTER)
MOV TMOD,#01010001b ; Timer0 as 16bit Timer
; Timer1 as 16bit counter with preloadvalue
CLR TR1
$ENDIF
$IF (_SW_SYNC_COUNTER)
ANL TMOD,#0F0H
ORL TMOD,#01H ; Timer0 as 16bit Timer
SETB IT1 ; edge trigger
$ENDIF
MOV BRGCON,#3 ;start baudrate generator
ANL SSTAT,#0F1H ; reset the SSTAT register
ANL SCON,#7CH ; CLR TI, CLR RI, CLR FE
;set interrupt priorities
;UART is absolutely not time-critical, so Priority 0 (reset value)
;The Sync-Measurement is very time-critical, so it gets Priority 3 (Ext1 or Timer1)
$IF (_HW_SYNC_COUNTER)
ORL IP0H,#08H
ORL IP0,#08H
$ENDIF
$IF (_SW_SYNC_COUNTER)
ORL IP0H,#04H
ORL IP0,#04H
$ENDIF
;allow UART Tx and Rx interrupt
SETB ESR
SETB EST
RET
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -