📄 canctrl.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 + -