⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lincmpsl.a51

📁 这是关于基于philips的764单片机的LIN程序设计
💻 A51
📖 第 1 页 / 共 2 页
字号:
NAME LINCMPSL ;Lin I睠-Slave
$INCLUDE (Relpc764.inc)
$INCLUDE (TJA1020.inc)
$INCLUDE (LINCMPSL.inc)

;###########################################################################################
;# This routines hold the Lin Mac-layer and LL-Layer.													 #
;#																														 #
;#Used Hardware:																									 #
;# Timer 0 and Timer 1																							 #
;# Comparator 1																									 #
;# UART																												 #
;#																														 #
;###########################################################################################

;Segments for the Lin-Protcol Layer
LIN_DATA 		SEGMENT DATA
LIN_MAC  		SEGMENT CODE
LIN_UART_INT 	SEGMENT CODE

;Segments for the Break detection
S_CMPInt SEGMENT CODE
S_TIMER1_INT SEGMENT CODE
S_TIMERI_INT SEGMENT CODE
S_INIT_BREAK_DETECT SEGMENT CODE
S_BREAK_DETECT_DATA SEGMENT DATA

;Segments for the Time-Out Counter
SGoToSleep 			SEGMENT CODE
SInitTimeOuts     SEGMENT CODE
SSendWakeup			SEGMENT CODE
STimer0Isr			SEGMENT CODE
SCounterData		SEGMENT DATA

;public definitions
;all these symbols will be available in other moduls
PUBLIC InitLinMac, FrameLength, LinID, LinData, LinError, LinState  
PUBLIC BreakFlag, LinSynced, LinIDreceived, LinRxData, LinTxData, LinDataRdy, LinFrameOk, LinSleeps, LinWakeitup
PUBLIC ParityError, ValidationError, ChecksumError
PUBLIC SendWakeup


;Data for Lin Protocol Layer
rseg LIN_DATA
_LinLastSent:	DS 1  ;last byte sent
_ByteLeft:		DS 1  ; number of bytes left to be sent
_LinCRC:			DS 1  ; temp CRC-sum
FrameLength:	DS 1  ; Lin Frame length, determined from the ID
LinData:			DS 8  ; Lindata buffer
LinID:			DS 1  ; LinID
_OldDptrL:		DS 1  ; backup of the datapointer
_OldDptrH:  	DS 1

dseg at (_FLAGS_ADR)
LinStateByte: db 1   ;Lin Statusbyte
LinErrorByte: db 1   ;Lin Errorbyte

dseg at (_FLAGS_ADR+2)
_ParityByte:   db 1  ;Lin Paritybits

;Data for Time-Out Counter
rseg SCounterData
_cnt_low: 		DS 1  ;to count a whole timeout, 4 bytes are needed
_cnt_high:  	DS 1  ;two bytes are already provided by the timer, so we need two additional bytes in RAM
_wakeup_trial:	DS 1  ;number of the actual wakeup-trial

;********************************************************************************************************
;********************************************************************************************************
;********************************************************************************************************
;********************************************************************************************************

;Code for the Lin Protocol Layer

;************************************
;Interrupt-Service Routine UART
cseg at 023H
ljmp LinUartInt

rseg LIN_UART_INT
LinUartInt:	
				CLR ES
				PUSH PSW
				PUSH ACC
				PUSH AR1
				
;#####################################################################################
;test the Sleep condition
			JNB LinSleeps,_MasterTask
			JB  RI,_sleepRx
_sleepTx: ;transmission while Lin sleeps, only possible if the wakeup-signal should be send or was sent
			CLR FE
			JB LinWakeitup,_after ; test if this tx is before or after the 0x80-char transmission
	_before:
			SETB LinWakeitup    ; send the wakeup-char
			CLR TI
			MOV SBUF,#80H
			ljmp _normal_return
	_after:
			CLR TI               ; just notify
			
			ljmp _normal_return	
			
_sleepRx:
			JNB LinWakeitup,_MasterTask   ; notify reception of wakeup character
			CLR LinWakeitup
			ljmp _normal_return
						

_MasterTask: 
			JNB FE,_normalData
;#############################################
;Check on Break
;Framing Error  *

		;When a framing error occurred, the Lin-protocol statemachine is resettet (wait for break)
		;the number of '0's in SBUF is looked up and, basing on this number, the time, which is left for a sync-break,
		;is calculated. This value is loaded into the timing-register of timer 1, the timer and the 
		;comparator are enabled, and the UART disabled. 
				CLR FE
				CLR TR1
 				PUSH AR0
 				
				ANL LinState,#80 ;clear all Flags, except LinSleeps
				MOV LinState,#0
				MOV LinError,#0						
				MOV _LinCRC,#0	
				ANL TMOD,#0FH   ;set the Timer1 to counter-mode
				ORL TMOD,#10H
				;calculate pre-load value for break-detection
				MOV R1,#BREAKTIMEH;preload R1 with high-byte of 11bit-times
				MOV R0,#BREAKTIMEL;preload R0 with low-byte of 11bit-times
				MOV A,SBUF  ; store SBUF in accumulator
_loop1:		JZ _end_calculate
$IF (TICKSPERBITH>0) ;--> depends on baudrate and osc-frequency, if TICKSPERBITH is greater than '0'
				XCH A,R1                                                    ;*only if necessary
				SUBB A,#TICKSPERBITH
				XCH A,R1
$ENDIF
				XCH A,R0
				SUBB A,#TICKSPERBITL ;subsctract 1 bit-time from 11-bit-time           *
				XCH A,R0                                                    ;*
				JNC _loop1   ; test overflow                                 *
				DEC R1		 ; if 'yes', increase high-byte       
				CLR C 
            RLC A
            ljmp _loop1

_end_calculate:
				MOV TH1,R1          
				MOV TL1,R0
				CLR TF1
				ANL CMP1,#0FEH ; clear int-Flag 
				SETB ET1   ;enable Timer 1 Interrupt
				SETB EC1   ;enable Comp-Interrupt
				SETB TR1   ;start timer
				
				POP AR0
				CLR ES ;disable serial int
				ljmp _break_return
								

;#####################################################################################
;Normal Data Transmitted or Received
_normalData:
			JNB TI,_RIisset
			; test if this node is data transmitting node and the TI flag has been set by the application-program
			CLR TI
			JNB BreakFlag,_ljmp_normal_return
			JNB LinSynced,_ljmp_normal_return
			JNB LinIDreceived,_ljmp_normal_return
			JB  LinFrameOk,_ljmp_normal_return
			JB  LinTxData,_ljmp_normal_return
			JB  LinRxData,_ljmp_normal_return
			SETB LinTxData; this Bit indicates, that the node is tranmitting data
			;send the first data byte
			MOV A,#LinData
			ADD A,_ByteLeft
			MOV R1,A
			MOV  SBUF,@R1; send the first Databyte
			MOV _LinLastSent,@R1
			ljmp _normal_return
			
_ljmp_normal_return:
			ljmp _normal_return
			
;#############################################################			
;from this point, RI is set
_RIisset:  ;----> Test the current state of the Lin protocol 
			JB BreakFlag,_testsyncbit
			ljmp _reset_return; normal character received without break?!?! that means a protocol-reset
_testsyncbit:
			JB LinSynced,_testIDBit
			ljmp _check_on_sync
_testIDBit:
			JB LinIDreceived,_testdatardy
			ljmp _check_on_ID
_testdatardy:
			JNB LinDataRdy,_process_data
;#### CRC has been received #################
_process_CRC:
			;test if the CRC was transmittet by this node itself (Flag LinTxData)
			MOV A,SBUF;  CRC in Accumulator
			JNB LinTxData,_checkCRC
			CJNE A,_LinLastSent,_validationError ;validation
			;now check the CRC
_checkCRC:
			ADD A,_LinCRC
			CJNE A,#0FFH,_CRCError ; sum must be 0xFF
;Lin Frame Ok
			SETB LinFrameOk
			CLR LinTxData
			CLR LinRxData
				
			MOV A,LinID; check on Lin CommandFrame
			CJNE A,#3CH,_toLinInt
		;Commandframe
			MOV A,LinData+7
			JNZ _reset_return
			
		   SETB ES
			CLR RI
			POP AR1
			POP ACC
			POP PSW
			ljmp _SettoSleep
;######################################################
				
_CRCError:	SETB ChecksumError
				ljmp _toLinError			

;##### normal databyte has been received ##############
_process_data:
				JB LinTxData,_do_not_set_bit
				JB LinRxData,_do_not_set_bit
				SETB LinRxData
_do_not_set_bit:				
				MOV A,#LinData
				ADD A,_ByteLeft
				MOV R1,A
				MOV @R1,SBUF ;receive the data
				
		;calculate CRC
_calcCRC:	MOV A,_LinCRC
				ADDC A,@R1
				JNC _noadd
				INC A
_noadd:
				MOV _LinCRC,A ;save CRC			
				;test if this was the last byte
				MOV A,_ByteLeft
				JNZ _next_is_data
            SETB LinDataRdy
_next_is_data:
				DEC _ByteLeft
				JNB LinTxData,_normal_return; again, test if this node has to transmit the Lin-data
				;validate the last data
				MOV A,@R1
				CJNE A,_LinLastSent,_validationError
				JB LinDataRdy,_sendCRC
;send the next databyte
				MOV A,#LinData
				ADD A,_ByteLeft
				MOV R1,A
				MOV SBUF,@R1
				MOV _LinLastSent,@R1
				ljmp _normal_return
_sendCRC:	MOV A,#0FFh
				CLR C
				SUBB A,_LinCRC
				MOV _LinLastSent,A
				MOV SBUF,A
				ljmp _normal_return
		
;##############################################################################		
;   here are the return from interrupt functionalities
;   they	are located in the middle of the ISR to support the +-128-byte jumps

_reset_return: 
			  ANL LinState,#LIN_WAIT_BREAK ;Clear all Flags
			  CLR TI

_normal_return:
			  SETB ES
_break_return:			  
			  CLR RI
			  POP AR1
			  POP ACC
			  POP PSW
			  RETI
			  
_validationError:
				SETB ValidationError
				ljmp _toLinError
				
_toLinError: 
				MOV LinState,#LIN_WAIT_BREAK
_toLinInt:
				CLR RI
				POP AR1
				POP ACC
				POP PSW
				MOV _OldDptrh,DPH
				MOV _OldDptrL,DPL
				MOV DPTR,#LinServiceRoutine
				PUSH DPL
				PUSH DPH
				MOV DPH,_OldDptrH
				MOV DPL,_OldDptrL
				SETB ES
				reti
;#######################################################################################
				

				
;################## process the LinID ##################################################
_check_on_ID:
				; evaluate ID
				MOV A,SBUF
				;CJNE A,_LinLastSent,_validationError ; the masternode always sends the ID  ;;outcomment --> this is the slavenode code
				MOV LinID,A
		      ANL LinID,#3FH
		
				RL A
				RL A      ; ACC = FL,FL,X,X|X,X,P1,P0
			; get Frame-Length
				MOV FrameLength,#2
				RLC A
				JNC _addRLC ; ---> one additional RLC has to be done
				MOV FrameLength,#4
			   RLC A
				JNC _getParity
				MOV FrameLength,#8
				ljmp _getParity
_addRLC:    RLC A				

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -