📄 can.asm
字号:
FLIGHCOUNT DATA 07EH
;;;;;;;;;;;;;;;显示位选计数;;;;;;;;;;;;;;;;;;;;
DISP_POINT DATA 07DH
SEC_COUNT_L DATA 030H ;秒定时计数器
SEC_COUNT_H DATA 031H
SAVE_INT_INFO DATA 032H ;保存SJA1000中断寄存器的内容
ERRORCOUNT DATA 033H ;错误计数
DISPLAYBUF0 DATA 034H ;显示缓冲区34H--38H
;
SEND_DATA_BUF1 DATA 040H ;发送缓冲区
SEND_DATA_BUF2 DATA 041H
SEND_DATA_BUF3 DATA 042H
SEND_DATA_BUF4 DATA 043H
SEND_DATA_BUF5 DATA 044H
SEND_DATA_BUF6 DATA 045H
SEND_DATA_BUF7 DATA 046H
SEND_DATA_BUF8 DATA 047H
SEND_DATA_BUF9 DATA 048H
SEND_DATA_BUF10 DATA 049H
RCV_DATA_BUF1 DATA 050H ;接收缓冲区
RCV_DATA_BUF2 DATA 051H
RCV_DATA_BUF3 DATA 052H
RCV_DATA_BUF4 DATA 053H
RCV_DATA_BUF5 DATA 054H
RCV_DATA_BUF6 DATA 055H
RCV_DATA_BUF7 DATA 056H
RCV_DATA_BUF8 DATA 057H
RCV_DATA_BUF9 DATA 058H
RCV_DATA_BUF10 DATA 059H
ERROR_STATUS DATA 07CH ;错误状态表示
TEST_DATA DATA 07FH ;测试发送数据
;************************************************************************
;程序开始
ORG 0000H
LJMP MAIN ;运行主程序
ORG 0003H
LJMP BCAN_INT0 ;中断方式访问SJA1000程序
ORG 000BH
LJMP T0_INTERRUPT ;定时器0中断
ORG 0100H ;程序开始
MAIN:
;内部RAM清零
MOV R0,#07fH
CLR A
MOV @R0,A
DJNZ R0,$-1
MOV @R0,A
MOV SP,#60H ;设置SP
LCALL DELAY ;延时
LCALL DELAY
; LCALL UART_INIT ;串口初始化
SJA1000_INIT0:
MOV ErrorCount, #020H ;32次,报错
LCALL BCAN_CREATE_COMMUNATION ;调用SJA1000接口测试函数
JNB F0, SJA1000_INIT1 ;接口正常,初始化SJA1000
DJNZ ErrorCount , SJA1000_INIT0 ;接口不正常,再检测
MOV ERROR_STATUS,#SJA_INTFACE_ERR
LJMP ERROR_HANDLE ;错误处理
SJA1000_INIT1:
;设置接收任何类型的标志符,波特率1000Kbps(16MHZ的晶体),关闭CLKOUT则,
;ACR=任何值,AMR=0FFH,BTR0=084H,BTR1=0A7H,OC==0aaH,CDR=048H
;首先设置参数
MOV R7, #012
MOV ErrorCount, #020H ;32次,报错
LCALL BCAN_SET_BANDRATE ;设置波特率为100k
JNB F0, SJA1000_INIT2 ;判断设置是否成功
DJNZ ErrorCount , SJA1000_INIT1 ;接口不正常,再检测
MOV ERROR_STATUS,#SJA_INITBTR_ERR
LJMP ERROR_HANDLE
SJA1000_INIT2:
;设置接收报文ID
MOV ErrorCount, #020H ;32次,报错
MOV R7, #00
MOV R6, #0FFH
LCALL BCAN_SET_OBJECT
JNB F0, SJA1000_INIT3 ;判断设置是否成功
DJNZ ErrorCount , SJA1000_INIT2
MOV ERROR_STATUS,#SJA_INITOBJ_ERR
LJMP ERROR_HANDLE
SJA1000_INIT3:
;设置输出控制、时钟分频
MOV ErrorCount, #020H ;32次,报错
MOV R7, #0AAH ;正常输出模式
MOV R6, #048H ;使能内部比较器、禁止CLKOUT
LCALL BCAN_SET_OUTCLK
JNB F0, SJA1000_INIT4 ;判断设置是否成功
DJNZ ErrorCount , SJA1000_INIT3
MOV ERROR_STATUS,#SJA_INITOCLK_ERR
LJMP ERROR_HANDLE
SJA1000_INIT4:
MOV ErrorCount, #020H ;32次,报错
LCALL BCAN_QUIT_RETMODEL ;退出复位状态
JNB F0, SJA1000_INIT5 ;判断设置是否成功
DJNZ ErrorCount , SJA1000_INIT4
MOV ERROR_STATUS,#0FEH ;#SJA_INIT_ERR
LJMP ERROR_HANDLE
SJA1000_INIT5:
MOV DPTR,#REG_CONTROL ;开放SJA1000内部功能中断
MOV A,#01EH ;中断开放
MOVX @DPTR,A
LCALL DISPLAY_INIT ;显示初始化
LCALL T0_INIT ;初始化定时器0
SETB PX0 ;设置外部中断0为最高优先级
SETB IT0 ;设置外部中断位边缘触发
MOV IE,#083H ;开放中断EXO,总中断位EA,ET0
LOOPER:
JBC TOIR,MS_DEALPRG
LOOPER1:
JBC RCV_GOOD,RCVDATA_PRG ;sja1000成功接收一帧,通知CPU处理
LOOPER2:
JBC SEC_FLAG,SENDDATA_PRG ;一秒时间到,每秒发送一次
LOOPER3:
JBC ERR_FLAG,ERR_PRG ;错误标志,错误处理
LOOPER4:
JBC OVER_FLAG,DOVER_PRG ;超载处理
LOOPER5:
JBC DS_END_FLAG,DSEND_PRG ;报文发送完成
LOOPER6:
JBC WUI_FLAG,WOKE_PRG ;唤醒处理
AJMP LOOPER
MS_DEALPRG:
; LCALL DISPLAY_PRG
AJMP LOOPER1
;发现错误处理
ERR_PRG:
LCALL BCAN_ENTER_RETMODEL ;进入复位模式
MOV ERROR_STATUS,#SJA_SEND_ERR
;错误信息处理
ERROR_HANDLE:
LCALL DISP_ERROR
LJMP SJA1000_INIT0 ;现错误,根据实际情况处理
;数据超载处理
DOVER_PRG:
MOV R7,#08H ;清除数据超载
LCALL BCAN_CMD_PRG ;
LJMP LOOPER5
;上一次发送的数据发送完毕处理
DSEND_PRG:
LCALL DISP_OK
LJMP LOOPER6
;唤醒中断处理
WOKE_PRG: ;唤醒处理
LJMP LOOPER
;接收数据处理部分
RCVDATA_PRG:
LCALL UART_INIT
MOV R0,#RCV_DATA_BUF1 ;微处理器接收首地址
LCALL BCAN_DATA_RECEIVE ;调用接收数据子程序
MOV R7,#04H ;释放接收缓冲区
LCALL BCAN_CMD_PRG ;
;将接收的数据发送至串口
MOV R0,#RCV_DATA_BUF2 ;计算接收数据长度判断远程帧、数据帧
MOV A,@R0
JB ACC.4,RD_PRG1 ;远程帧
;数据帧
ANL A,#0FH ;计算数据数目
ADD A,#02H ;计算帧的数据长度
MOV R7, A
AJMP RD_UARTSD
RD_PRG1:
MOV R7,#02H
RD_UARTSD:
MOV R0,#RCV_DATA_BUF1 ;微处理器接收首地址
LCALL UART_SEND ;调用串口发送程序
LCALL DISP_OK
LJMP LOOPER2
;控制SJA1000向CAN总线发送数据处理部分
SENDDATA_PRG:
MOV R0, #SEND_DATA_BUF1
MOV @R0, #0AAH
INC R0
MOV A, TEST_DATA
MOV R7, #08
MOV A, #08
MOV @R0, A
RB_DATA:
MOV A, TEST_DATA
INC R0
MOV @R0, A
DJNZ R7, RB_DATA ;将特定格式的帧存入发送缓冲区
MOV R0, #SEND_DATA_BUF1
LCALL BCAN_DATA_WRITE ;将要发送的数据送入发送缓冲区
MOV R7, #01
LCALL BCAN_CMD_PRG
LJMP LOOPER3
;定时器0初始化
T0_INIT:
MOV A,TMOD
ANL A,#0F0H
ORL A,#01H
MOV TMOD,A;T0工作在方式1
MOV TH0,#0FCH ;定时周期1MS
MOV TL0,#066H
SETB ET0
MOV TCON,#055H ;启动定时器
RET
;串口初始化
UART_INIT:
MOV SCON,#050H ;串口数据1个STOP,8个DATA,无校验
MOV A,TMOD
ANL A,#0FH
ORL A,#020H
MOV TMOD,A ;用定时器1做波特率发生器
MOV TH1,#0FDH ;波特率9600bps
MOV TL1,#0FDH
SETB TR1
clr ES
CLR TI
RET
DISPLAY_INIT:
MOV DPTR,#KEYLED_MODE
CLR A
MOVX @DPTR,A
RET
;延时程序
DELAY:
MOV R7,#0FFH
D1: MOV R6,#0ffh
DJNZ R6,$
DJNZ R7,D1
RET
;串口发送子程序
UART_SEND:
CLR TI
MOV A,@R0
MOV SBUF,A
JNB TI,$
CLR TI
INC R0
DJNZ R7,UART_SEND
RET
;外部中断0
BCAN_INT0:
push DPH
PUSH DPL
PUSH PSW ;PSW,ACC入栈
PUSH ACC
CPL P1.0
;USING 3 ;应用寄存器第3组
SETB PSW.3
SETB PSW.4
MOV DPTR,#REG_INTERRUPT ;读中断寄存器
MOVX A,@DPTR ;
MOV SAVE_INT_INFO,A ;保存中断寄存器的内容
JNB ACC.0,BCAN_INT1 ;接收中断
SETB RCV_GOOD ;置位接收标志
BCAN_INT1:
MOV A,SAVE_INT_INFO
JNB ACC.1,BCAN_INT2 ;发送中断
SETB DS_END_FLAG ;发送完成处理
BCAN_INT2:
MOV A,SAVE_INT_INFO
JNB ACC.2,BCAN_INT3 ;错误中断
SETB ERR_FLAG ;置位错误标志
BCAN_INT3:
MOV A,SAVE_INT_INFO
JNB ACC.3 ,BCAN_INT4 ;超载中断
SETB OVER_FLAG ;置位超载标志
BCAN_INT4:
MOV A,SAVE_INT_INFO
JNB ACC.4,BCAN_INT5 ;唤醒中断
SETB WUI_FLAG ;唤醒中断处理标志
BCAN_INT5:
POP ACC
POP PSW
POP DPL
POP DPH
RETI
;定时器0中断
T0_INTERRUPT:
push DPH
PUSH DPL
PUSH PSW ;PSW、ACC入栈
PUSH ACC
CPL P1.1
;USING 2
CLR PSW.3
SETB PSW.4
MOV TH0,#0FCH ;设置定时周期1MS
MOV TL0,#066H
SETB TOIR
LCALL DISPLAY_PRG
MOV A,FLIGHDISP
JZ NOFLIGH
INC FLIGHCOUNT
MOV A,FLIGHCOUNT
CJNE A,#200,NOFLIGH1
MOV FLIGHCOUNT,#00
CPL FLIGHSYNC
AJMP NOFLIGH1
NOFLIGH:
CLR FLIGHSYNC
NOFLIGH1:
INC DISP_POINT
MOV A,DISP_POINT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -