📄 lincmpsl.a51
字号:
; 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 ParityError
SETB LinIDreceived
MOV _ByteLeft,FrameLength
DEC _ByteLeft
MOV _LinCRC,#0
CLR RI
ljmp _toLinInt
_Parity_Error:
SETB ParityError
ljmp _toLinError
;############## process the synchronisation #######################
_check_on_sync:
MOV A,SBUF
CJNE A,#055H,__reset_return
SETB LinSynced
ljmp _normal_return
__reset_return : ljmp _reset_return
;********************************************************************************************************
;********************************************************************************************************
;#########################################################
;End of Interupt-routine
;
;Protocol management functionalities
rseg LIN_MAC
InitLinMac:
CALL InitBreakDetect
MOV LinState,#LIN_WAIT_BREAK
CLR LinWakeitup
CLR LinSynced
MOV TH1,#BAUDRATERELOADVAL
ORL TMOD,#020H
ORL SCON,#050H
ORL PCON,#0C0H
ORL P1M1,#02H
ORL P1M2,#03H
SETB TR1
CALL InitTimeOuts
SETB ES
RET
;********************************************************************************************************
;********************************************************************************************************
;********************************************************************************************************
;********************************************************************************************************
;Code for the Break-detection
;This module performs the LIN-Break-Detection by using the I睠-Interface and the Timer1
;The SCL-Line has to be stuck at VCC, SDAT to the LIN-Rx-Line.
;If a start-cond. is detected, the timer has to be loaded with a time-out-value, and then started.
;The stop-condition stops and resets the timer.
;If the timer has an overflow, a break is detected.
;Interrupt Vectors
cseg at 063H ;Comparator-InteruptVector
ljmp CmpInt
cseg at 01BH ;Timer0-Interupt-Vector
ljmp Timer1Int
;Data Segments
rseg S_BREAK_DETECT_DATA
BreakTimeOut: DS 2
rseg S_TIMERI_INT
TimerIInt: reti
;Code Segments
rseg S_Timer1_INT ;if this routine is accessed, a Break-Signal has occured
Timer1Int:
CLR EC1; disable Comparator-Interrupt
;enable UART again
CLR TR1 ;stop timer
CLR ET1 ; disable Timer-Int
MOV _OldDptrH,DPH
MOV _OldDptrL,DPL
;######### reset from sleep-mode --> wake up
JNB LinSleeps, _nowakeup
CLR TF0
CLR TR0
MOV DPTR,#LinWakeup
SETB ET0
ljmp _wakePtrset
_nowakeup:
MOV DPTR,#LinServiceRoutine
_wakePtrset:
MOV LinState,#LIN_WAIT_BREAK
SETB BreakFlag
lcall ResetTimeOut
;enable UART again
MOV TH1,#BAUDRATERELOADVAL ;preload baudrate
MOV TL1,#BAUDRATERELOADVAL ;preload baudrate
ANL TMOD,#0FH ;set timer to auto-reload mode
ORL TMOD,#020H
ANL SCON,#7CH; CLR FE, CLR TI, CLR RI
SETB ES ; enable serial Interface
SETB TR1 ; enable timer
_out: ;LCALL LinServiceRoutine ; Lin Call-Back funktion
;DPTR holds the location of the following function
PUSH DPL
PUSH DPH
MOV DPH,_OldDptrH
MOV DPL,_OldDptrL
reti
;Comparator Interrupt-Service-Routine ; if this routine is accessed, a 'normal' framing error has occured
rseg S_CMPInt
CMPInt: CLR ET1; disable Timer-Int
CLR EC1 ; no Comparator-Int
PUSH ACC
;SETB P1.7 just for debugging
MOV A,CMP1 ; test comparator value
ORL A,#02H
JZ _ret_cmpint
CALL ResetTimeOut
; Enable UART again
CLR TR1
MOV TH1,#BAUDRATERELOADVAL
MOV TL1,#BAUDRATERELOADVAL
ANL TMOD,#0FH
ORL TMOD,#020H
_ret_cmpint: POP ACC
ANL CMP1,#0FEH ; clear int-Flag
SETB ES ; enable serial Interface
SETB TR1
reti
;End of I睠 Interrupt-Service-Routine
rseg S_INIT_BREAK_DETECT
InitBreakDetect:
PUSH AR0
;Initialize Comparator
MOV PT0AD,#08H ;disbale digital function on Pin P0.3 CIN1B
ANL P0M2,#0F7H ;disable digital output for Pin P0.3
ORL P0M1,#08H
MOV CMP1,#38H ;set comparator parameter
MOV R0,#0 ;delay
DJNZ R0,$
ANL CMP1,#0FEH ;clear interrupt flag
POP AR0
ret
;********************************************************************************************************
;********************************************************************************************************
;********************************************************************************************************
;********************************************************************************************************
;Code for Time-Out detection
cseg at 0BH
ljmp Timer0Isr
rseg STimer0Isr
Timer0Isr:
PUSH PSW
PUSH ACC
CLR ET0 ; disable Interrupt
;count the time-out counter (4 Byte)
;two hardware-timer-register, two software-register (the two upper byte)
MOV ACC,_cnt_low
JNZ _no_underflow
MOV ACC,_cnt_high
JZ _handle_timeout
DEC _cnt_high
_no_underflow:
DEC _cnt_low
_reti:
SETB ET0
POP ACC
POP PSW
RETI
;set the system to sleep-mode
_handle_timeout:
JB LinSleeps,_wakeup ;Lin Sleeps, but the controller does not ... this must have been another external interrupt...wake up the system
POP ACC
POP PSW
_SettoSleep:
MOV _OldDptrH,DPH
MOV _OldDptrL,DPL
;ANL CMP1,#0FEH ; clear int-Flag
CLR TF0
CLR TR0
CLR ET0
CLR EC1
CLR ET1
SETB TR1
SETB LinSleeps
SETB ES
MOV DPTR,#LinSettoSleep;
PUSH DPL
PUSH DPH
MOV DPL,_OldDptrL
MOV DPH,_OldDptrH
reti
;the wake-up procedure consists of two different timer values.
;the slave has to try 3 times, if the master has not been waken up
_wakeup:
CLR TR0
MOV A,_wakeup_trial
JNZ _short_wakeup
;long wakeup
MOV _wakeup_trial,#2
MOV TH0,#_LIN_WAKELONG_LH
MOV TL0,#_LIN_WAKELONG_LL
MOV _cnt_low,#_LIN_WAKELONG_HL
MOV _cnt_high,#_LIN_WAKELONG_HH
ljmp _send_wakeup_char
_short_wakeup:
DEC A
MOV _wakeup_trial,A
MOV TH0,#_LIN_WAKESHORT_LH
MOV TL0,#_LIN_WAKESHORT_LL
MOV _cnt_low,#_LIN_WAKESHORT_HL
MOV _cnt_high,#_LIN_WAKESHORT_HH
_send_wakeup_char:
SETB TI ; --> send wakeup char
SETB TR0
ljmp _reti
rseg SInitTimeOuts
InitTimeOuts:
MOV IP1H,#1
MOV IP1,#1
ORL TMOD,#01H
CALL ResetTimeOut
CLR TF0
SETB ET0
SETB TR0
ret
ResetTimeOut:
CLR TR0
MOV TH0,#_LIN_TIMEOUT_LH
MOV TL0,#_LIN_TIMEOUT_LL
MOV _cnt_low,#_LIN_TIMEOUT_HL
MOV _cnt_high,#_LIN_TIMEOUT_HH
SETB TR0
SETB ET0
ret
rseg sSendWakeUp
SendWakeUp:
JNB LinSleeps,__out
SETB SleepPin
MOV _wakeup_trial,#1
CLR TR0
MOV TH0,#_LIN_WAKESHORT_LH
MOV TL0,#_LIN_WAKESHORT_LL
MOV _cnt_low,#_LIN_WAKESHORT_HL
MOV _cnt_high,#_LIN_WAKESHORT_HH
SETB TR0
CLR TF0
SETB ET0
CLR TF1
CLR RI
SETB TR1
CLR ET1
;start wakeup transmission
SETB ES
SETB TI
SETB EA
__out: ret
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -