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

📄 canctrl.s

📁 完整的can网通行的底层驱动程序及其详细的说明
💻 S
字号:
;************************************************************
;	SUB FUNCTION for  input and output of mc68332
;   File name :CanCtrl.S
;	For PCB CPU9810
;************************************************************

;**********************************************************************
;	CAN地址和寄存器地址定义
;**********************************************************************
#ifdef	IS_MMI_PROG	
//MMI程序时
  #define CAN_DATA	0xffffa000	;cs8
  #define CAN_ADD		0xffffa800	;cs9
#else
//CPU程序时
  #define CAN_DATA	0xffffa000
  #define CAN_ADD		0xffffa800
#endif

#define PC_MOD		0 
#define PC_CMR		1 
#define PC_SR		2 
#define PC_IR		3
#define PC_IER		4
#define PC_BTR0		6
#define PC_BTR1		7
#define PC_OCR		8
#define PC_TEST		9
#define PC_ALC		11 
#define PC_ECC		12
#define PC_EWLR		13
#define PC_RXERR	14
#define PC_TXERR	15
#define PC_RXBUF	16
#define PC_TXBUF	16
#define PC_ACR0		16
#define PC_ACR1		17	
#define PC_ACR2		18
#define PC_ACR3		19	
#define PC_AMR0		20
#define PC_AMR1		21	
#define PC_AMR2		22
#define PC_AMR3		23
#define PC_RMC		29
#define PC_RBSA		30
#define PC_CDR		31

/* bus timing values for
- bit-rate : 100 kBit/s
- oscillator frequency : 20 MHz, 1,0%
 */
#define Presc_KB_20 6 /* baud rate prescaler : 7(6:100k,26:25k) */
#define SJW_KB_20 0xC0 /* SJW : 4 */
#define TSEG1_KB_20 0x09 /* TSEG1 : 10 */
#define TSEG2_KB_20 0x30 /* TSEG2 : 4 */

;**********************************************************************
;	宏定义
;**********************************************************************
WCAN:	MACRO
		MOVE.B	\1,CAN_ADD
		MOVE.B	\2,CAN_DATA
		ENDM
RCAN:	MACRO
		MOVE.B	\1,CAN_ADD
		MOVE.B	CAN_DATA,\2
		ENDM
QWCAN:	MACRO
		MOVE.B	\1,(A1)
		MOVE.B	\2,(A0)
		ENDM
QRCAN:	MACRO
		MOVE.B	\1,(A1)
		MOVE.B	(A0),\2
		ENDM
LCANADD MACRO ;将CAN控制器的地址装入A0和A1
		LEA	CAN_ADD,A1
		LEA CAN_DATA,A0
		ENDM


;**********************************************************************
;	全局标识符说明
;**********************************************************************
#ifndef IS_MMI_PROG
		XREF	_bQDB
		XREF	_dTCounter
#endif

;**********************************************************************
;	全局标识符说明
;**********************************************************************

	SECTION	code
;***********************
;	初始化can控制器程序
;***********************
	.FDEF	__CanInit,0
__CanInit:
	CLR.W	bCanEn		;清CAN打开标志
	
	BSR.L	ResetCan

	CLR.B	byCanHead
	CLR.B	byCanTail
	CLR.B	byRHead
	CLR.B	byRTail

	CLR.W	bCanError
	CLR.W	bCanSendBusy
	CLR.W	bCanReceiveBusy

	MOVE.W	#$ffff,bCanEn

	RTS

ResetCan:
	LCANADD			
._100
	QWCAN	#PC_MOD,#%00000001;置模式寄存器
	QRCAN	#PC_MOD,D0		 ;检查是否进入reset模式
	BTST	#0,D0
	BEQ		._100

	QWCAN	#PC_CDR,#%11001000;置Clock divide register

	QWCAN	#PC_BTR0,#SJW_KB_20|Presc_KB_20
	QWCAN	#PC_BTR1,#TSEG2_KB_20|TSEG1_KB_20

	QWCAN	#PC_ACR0,#%00000000
	QWCAN	#PC_ACR1,#%00000000
	QWCAN	#PC_ACR2,#%00000000
	QWCAN	#PC_ACR3,#%00000000
	QWCAN	#PC_AMR0,#%11111111
	QWCAN	#PC_AMR1,#%11111111
	QWCAN	#PC_AMR2,#%11111111
	QWCAN	#PC_AMR3,#%11111111
	
	QWCAN	#PC_OCR,#%00001010

	QWCAN	#PC_IER,#%00000000

	QWCAN	#PC_EWLR,#96
	QWCAN	#PC_RXERR,#0
	QWCAN	#PC_TXERR,#0

._200
	QWCAN	#PC_MOD,#%00000000	;置模式寄存器
	QRCAN	#PC_MOD,D0			;检查是否进入normal模式
	BTST	#0,D0
	BNE		._200

	RTS

;***********************
;	AD中断丢失时,调用该程序使__CanErrProess调用__CanProcess
;***********************
	.FDEF	__CanAdLoss,0
__CanAdLoss:
	ST	bAdLoss
	RTS

;***********************
;	can控制器错误处理程序,在主循环中调用
;***********************
	.FDEF	__CanErrProcess,0
__CanErrProcess:
	CLR.W	bCanEn		;清CAN打开标志

	TST.W	bCanError
	BEQ		._100
		
	BSR.L	ResetCan

	CLR.W	bCanError
._100
	MOVE.W	#$ffff,bCanEn
;*********************
;AD中断丢失时处理
#ifndef	IS_MMI_PROG
	TST.B	bAdLoss
	BEQ		._Exit
	ST		bErrCallProcess
	BSR		__CanProcess
	CLR.B	bErrCallProcess
._Exit
#endif
;*********************

	RTS

;*******************************
;	CAN定时处理,在采样中断中调用
;	void _CanProcess();
;*******************************
	.FDEF	__CanProcess,0
__CanProcess:
	MOVEM.L	A2,-(A7)

;*********************
;AD中断丢失时处理
#ifndef	IS_MMI_PROG
	TST.B	bAdLoss
	BEQ		._331
	TST.B	bErrCallProcess
	BEQ		._Exit
._331
#endif
;*********************

	ADDQ.W	#1,wCounter
	TST.B	bCanEn
	BEQ		._Exit

	LCANADD
	QRCAN	#PC_SR,D1

;*******需加入出错处理
	BTST	#6,D1	;Error Status
	BNE		._30
	BTST	#7,D1	;Bus off Status
	BEQ		._40
._30		;Error
	QWCAN	#PC_MOD,#%00000001;置模式寄存器
	MOVE.W	#$FFFF,bCanError
	BRA		._Exit

._40	
	BTST	#0,D1
	BEQ		._200
;接收到数据
	QRCAN	#PC_RXBUF+4,D0
	LSR.B	#4,D0
	CMP.B	#$0f,D0 ;广播报文地址0xF
	BEQ		._50
	CMP.B	_byCanAdd,D0
	BNE		._190
._50
	CLR.L	D0
	MOVE.B	byRHead,D0

;调整byRHead
	MOVE.B	D0,D1
	ADDQ.B	#1,D1
	MOVE.B	D1,byRHead
	CMP.B	byRTail,D1
	BNE		._55
	ADDQ.B	#1,byRTail

._55
	LSL.L	#4,D0
	MOVE.L	D0,A2
	LEA		(abyReceiveBuf,A2),A2

	MOVEQ	#PC_RXBUF,D0
	QRCAN	D0,(A2)+	
	ADDQ.B	#1,D0
	QRCAN	D0,(A2)+	
	ADDQ.B	#1,D0
	QRCAN	D0,(A2)+	
	ADDQ.B	#1,D0
	QRCAN	D0,(A2)+	

	ADDQ.B	#1,D0
	QRCAN	D0,(A2)+	
	ADDQ.B	#1,D0
	QRCAN	D0,(A2)+	
	ADDQ.B	#1,D0
	QRCAN	D0,(A2)+	
	ADDQ.B	#1,D0
	QRCAN	D0,(A2)+	

	ADDQ.B	#1,D0
	QRCAN	D0,(A2)+	
	ADDQ.B	#1,D0
	QRCAN	D0,(A2)+	
	ADDQ.B	#1,D0
	QRCAN	D0,(A2)+	
	ADDQ.B	#1,D0
	QRCAN	D0,(A2)+
		
	ADDQ.B	#1,D0
	QRCAN	D0,(A2)+
	
#ifndef IS_MMI_PROG
	ADDQ.L	#1,A2
	MOVE.W	_dTCounter+2,(A2)
#endif		
				
._180
	QWCAN	#PC_CMR,#%00000100
	BRA		._Exit

._190
	QWCAN	#PC_CMR,#%00000100
._200
	BTST	#2,D1
	BEQ		._Exit
;可以发送
	CLR.L	D0
	MOVE.B	byCanTail,D0
	CMP.B	byCanHead,D0
	BEQ		._Exit
;需发送
	ADDQ.B	#1,byCanTail
	LSL.L	#4,D0
	MOVE.L	D0,A2
	LEA		(abyCanBuf,A2),A2

	MOVEQ	#PC_TXBUF,D0
	QWCAN	D0,(A2)+
	ADDQ.B	#1,D0
	QWCAN	D0,(A2)+
	ADDQ.B	#1,D0
	QWCAN	D0,(A2)+
	ADDQ.B	#1,D0
	QWCAN	D0,(A2)+
	
	ADDQ.B	#1,D0
	QWCAN	D0,(A2)+
	ADDQ.B	#1,D0
	QWCAN	D0,(A2)+
	ADDQ.B	#1,D0
	QWCAN	D0,(A2)+
	ADDQ.B	#1,D0
	QWCAN	D0,(A2)+
	
	ADDQ.B	#1,D0
	QWCAN	D0,(A2)+
	ADDQ.B	#1,D0
	QWCAN	D0,(A2)+
	ADDQ.B	#1,D0
	QWCAN	D0,(A2)+
	ADDQ.B	#1,D0
	QWCAN	D0,(A2)+
		
	ADDQ.B	#1,D0
	QWCAN	D0,(A2)+
	
	QWCAN	#PC_CMR,#%00000001
._Exit
	MOVEM.L	(A7)+,A2
	RTS	
		
;*****************************
;	发送
;	bool _CanSend(BYTE byAdd,BYTE byLevel,BYTE* pBuf,BYTE byLen)
;*******************************
	.FDEF __CanSend,16
__CanSend:
	MOVEM.L	D2/D3/D4,-(A7)

#ifndef	IS_MMI_PROG
	;AD丢失时不再处理中断冲突问题
	TST.B	bAdLoss
	BNE		._30

	TST.W	_bQDB
	BEQ		._10
	;已启动
	TST.W	bCanSendBusy
	BNE		._ExitFail
	BRA		._40		
._10				;等待到中断刚返回
	MOVE.W	wCounter,D0
._20
	MOVE.W	wCounter,D1
	SUB.W	D0,D1
	BEQ		._20
	CMP.W	#1,D1	;确认未进故障处理程序
	BEQ		._30
	BRA		._10
._30

	MOVE.W	#$FFFF,bCanSendBusy
#endif
._40
	CLR.L	D4
	MOVE.B	(%+19,A7),D4 ;D4<-byLen
	TST.L	D4			 ;D4=0则返回
	BEQ		._ExitFail

	MOVE.B	(%+11,A7),D0 ;D0<-byLevel
	LSL.B	#5,D0
	MOVE.B	_byCanAdd,D3 ;D3<-byCanAdd(Source Add)
	AND.B	#$0f,D3
	OR.B	D0,D3		;D3<-TXBUF0,start fragment

	MOVE.B	(%+7,A7),D1	;D1<-byAdd(Destination Add)
	LSL.B	#4,D1		
	BSET	#3,D1		;Set no end flag		

	MOVE.L	(%+12,A7),A1 ;A1<-pBuf
	MOVE.B	byCanHead,D2 ;D2<-byCanHead
._50
	CLR.L	D0
	MOVE.B	D2,D0
	LSL.L	#4,D0
	MOVE.L	D0,A0
	LEA		(abyCanBuf,A0),A0

._100
	MOVE.B	D2,D0
	ADDQ.B	#1,D0
	CMP.B	byCanTail,D0
	BEQ		._ExitFail
	
	MOVE.B	#%10001000,(A0)+
	MOVE.B	D3,(A0)+	

	MOVE.B	(A1)+,(A0)+

	MOVE.B	(A1)+,(A0)+

	MOVE.B	D1,(A0)+

	MOVE.B	(A1)+,(A0)+
	MOVE.B	(A1)+,(A0)+
	MOVE.B	(A1)+,(A0)+
	MOVE.B	(A1)+,(A0)+
	MOVE.B	(A1)+,(A0)+
	MOVE.B	(A1)+,(A0)+
	MOVE.B	(A1)+,(A0)+
	MOVE.B	(A1)+,(A0)+
	
	ADDQ.B	#1,D2

	SUB.W	#10,D4
	BLE		._200

	BSET	#4,D3
	BRA		._50

._200
	BCLR	#3,(-9,A0)
	MOVE.B	D2,byCanHead
	
	MOVEQ	#$ff,D0
	BRA		._ExitSuccess	
._ExitFail
	CLR.L	D0

._ExitSuccess
	CLR.W	bCanSendBusy
	MOVEM.L	(A7)+,D2/D3/D4	
	RTD #16
;*****************************
;	接收,成功返回接收到字节数(包括末尾两字节dTCounter低字),失败返回false
;	bool _CanReceive(BYTE* pBuf)
;*******************************
	.FDEF __CanReceive,4
__CanReceive:
	MOVEM.L	D2-D7,-(A7)
	
	MOVE.L	(%+4,A7),A1
	CLR.L	D6
	MOVE.L	A7,D7

._50
	CLR.L	D1
	CLR.L	D0

	;关中断
#ifdef	IS_MMI_PROG
	MOVE.W	bCanEn,-(A7)
	CLR.W	bCanEn
#else
	MOVE	SR,-(A7)
	MOVE	#$2500,SR
#endif

	;比较byRHead和byRTail是否相等
	MOVE.B	byRTail,D0
	CMP.B	byRHead,D0
	BEQ		._100

	;有接收数据
	MOVEQ	#$FF,D1
	ADDQ.B	#1,byRTail

._100
	;开中断
#ifdef	IS_MMI_PROG
	MOVE.W	(A7)+,bCanEn
#else
	MOVE	(A7)+,SR
#endif

	TST.L	D1
	BEQ		._ExitFail
	;有接收数据
	
	MOVE.L	D0,D1
	LSL.L	#4,D1
	MOVE.L	D1,A0	
	LEA		(abyReceiveBuf,A0),A0	;计算帧地址

	BTST	#3,(4,A0)
	BNE		._50	;不是结束帧

;是结束帧
	MOVE.L	A0,-(A7)
	ADDQ.W	#1,D6

	BTST	#4,(1,A0)
	BEQ		._300	;是开始帧(单帧报文)

;查找开始帧

	MOVE.B	(1,A0),D4
	AND.B	#$0F,D4 ;读取结束帧CAN地址

	MOVE.W	#251,D3
	SUBQ.B	#1,D0

._200
	CMP.B	byRHead,D0
	BEQ		._ExitFail;找不到开始帧

	MOVE.L	D0,D1
	LSL.L	#4,D1
	MOVE.L	D1,A0	
	LEA		(abyReceiveBuf,A0),A0	;计算帧地址

	;比较CAN地址
	MOVE.B	(1,A0),D1
	AND.B	#$0F,D1
	CMP.B	D1,D4
	BNE		._270	;地址不匹配

	MOVE.L	A0,-(A7)
	ADDQ.W	#1,D6

	CMP.W	#26,D6
	BHI		._ExitFail	;找不到开始帧

	
	BTST	#3,(4,A0)
	BEQ		._ExitFail	;是结束帧

	BTST	#4,(1,A0)
	BEQ		._300	;是开始帧

._270
	SUBQ.B	#1,D0

	DBF		D3,._200
	BRA		._ExitFail;找不到开始帧

._300
	TST.W	D6
	BEQ		._ExitFail

	CLR.L	D0

	MOVE.W	D6,D0
	LSL.W	#3,D0
	ADD.W	D6,D0
	ADD.W	D6,D0	;D0=10*D6+2

	ADDQ.W	#2,D0

	MOVE.L	(A7),A0
	MOVE.B	(14,A0),D1
	MOVE.B	(15,A0),D2

	BRA		._350
._320
	MOVE.L	(A7)+,A0
	ADDQ.L	#2,A0
	MOVE.B	(A0)+,(A1)+
	MOVE.B	(A0)+,(A1)+
	ADDQ.L	#1,A0
	MOVE.B	(A0)+,(A1)+
	MOVE.B	(A0)+,(A1)+
	MOVE.B	(A0)+,(A1)+
	MOVE.B	(A0)+,(A1)+
	MOVE.B	(A0)+,(A1)+
	MOVE.B	(A0)+,(A1)+
	MOVE.B	(A0)+,(A1)+
	MOVE.B	(A0)+,(A1)+
._350
	DBF		D6,._320
	
	MOVE.B	D1,(A1)+
	MOVE.B	D2,(A1)

	BRA		._ExitSuccess	
._ExitFail
	CLR.L	D0

._ExitSuccess
	MOVE.L	D7,A7
	MOVEM.L	(A7)+,D2-D7
		
	RTD #4



;***********************************************************************
;	内存变量定义
;***********************************************************************
	SECTION	ram
abyReceiveBuf:DS.B	256*16

byRHead:	DS.B 1
byRTail:	DS.B 1

abyCanBuf:  DS.B 256*16
byCanHead:	DS.B 1
byCanTail:	DS.B 2

wCounter:	DS.W 1

	
	XDEF	_byCanAdd
_byCanAdd:  DS.B 1

;***********************************************************************
;	需初始化内存变量定义
;***********************************************************************
	SECTION data
bCanEn:			DC.W 0
bCanSendBusy:	DC.W 0
bCanReceiveBusy:	DC.W 0
bCanError:		DC.W 0
bAdLoss:		DC.B 0
bErrCallProcess: DC.B 0
	
	END

⌨️ 快捷键说明

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