📄 test3.asm
字号:
$INCLUDE (SJA_BCANCONF.ASM) ;导入硬件定义文件
;;;;;;;;;;;;;;;;定义错误字
;
;使用前变量定义
RCV_GOOD BIT 0FH ;成功的接收一帧标志
SEC_FLAG BIT 010H ;一秒到标志
ERR_FLAG BIT 011H ;监测到错误标志
OVER_FLAG BIT 012H ;超载标志
DS_END_FLAG BIT 013H ;SJA1000发送完成标志
WUI_FLAG BIT 014H ;唤醒SJA1000标志
TOIR BIT 015H ;定时器T0标志
;;;;;;;;;;;;;;;显示闪烁标志区;;;;;;;;;;;;;;;;;;;;
FLIGHDISP DATA 02FH
FLIGHBIT0 BIT 07FH
FLIGHBIT1 BIT 07EH
FLIGHBIT2 BIT 07DH
FLIGHBIT3 BIT 07CH
FLIGHBIT4 BIT 07BH
FLIGHSYNC BIT 07AH
;;;;;;;;;;;;;;显示位选选择;;;;;;;;;;;;;;;;;;
EN_DISPBIT0 BIT P1.7
EN_DISPBIT1 BIT P1.6
EN_DISPBIT2 BIT P1.5
EN_DISPBIT3 BIT P1.4
EN_DISPBIT4 BIT P1.3
;;;;;;;;;;;;;;;显示闪烁频率计数;;;;;;;;;;;;;;;;;;;;
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 ;串口初始化
LCALL T0_INIT
SETB EA
MOV ErrorCount, #020H ;32次,报错
SJA1000_INIT0:
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 ErrorCount, #020H ;32次,报错
SJA1000_INIT11:
MOV R7, #012
LCALL BCAN_SET_BANDRATE ;设置波特率为100k
AJMP SJA1000_INIT2
;JNB F0, SJA1000_INIT2 ;判断设置是否成功
DJNZ ErrorCount , SJA1000_INIT11 ;接口不正常,再检测
MOV ERROR_STATUS,#SJA_INITBTR_ERR
LJMP ERROR_HANDLE
SJA1000_INIT2:
MOV ErrorCount, #020H ;32次,报错
SJA1000_INIT21:
;设置接收报文ID
MOV R7, #00
MOV R6, #0FFH
LCALL BCAN_SET_OBJECT
AJMP SJA1000_INIT3
JNB F0, SJA1000_INIT3 ;判断设置是否成功
DJNZ ErrorCount , SJA1000_INIT21
MOV ERROR_STATUS,#SJA_INITOBJ_ERR
LJMP ERROR_HANDLE
SJA1000_INIT3:
MOV ErrorCount, #020H ;32次,报错
SJA1000_INIT31:
;设置输出控制、时钟分频
MOV R7, #0AAH ;正常输出模式
MOV R6, #048H ;使能内部比较器、禁止CLKOUT
LCALL BCAN_SET_OUTCLK ;
AJMP SJA1000_INIT4
JNB F0, SJA1000_INIT4 ;判断设置是否成功
DJNZ ErrorCount , SJA1000_INIT31
MOV ERROR_STATUS,#SJA_INITOCLK_ERR
LJMP ERROR_HANDLE
SJA1000_INIT4:
MOV ErrorCount, #020H ;32次,报错
SJA1000_INIT41:
LCALL BCAN_QUIT_RETMODEL ;退出复位状态
AJMP SJA1000_INIT5
JNB F0, SJA1000_INIT5 ;判断设置是否成功
DJNZ ErrorCount , SJA1000_INIT41
MOV ERROR_STATUS,#0FEH;#SJA_INIT_ERR
LJMP ERROR_HANDLE
SJA1000_INIT5:
MOV DPTR,#REG_CONTROL ;开放SJA1000内部功能中断
MOV A,#0FEH ;中断开放
MOVX @DPTR,A
; 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
LCALL DELAY
LCALL DELAY
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
;延时程序
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
USING 3 ;应用寄存器第3组
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
USING 2
MOV TH0,#0FCH ;设置定时周期1MS
MOV TL0,#066H
SETB TOIR
LCALL DSEG_CONTRL
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 SEC_COUNT_L ;单位时间计数器
MOV A,SEC_COUNT_L
CJNE A,#200,T0_QUIT ;判断1/5秒时间是否到
MOV SEC_COUNT_L,#00 ;重新计数
INC SEC_COUNT_H ;单位时间计数器
MOV A,SEC_COUNT_H
CJNE A,#6,T0_QUIT ;判断1秒时间是否到
MOV SEC_COUNT_H,#00 ;重新计数
SETB SEC_FLAG ;置位1秒到标志
INC TEST_DATA ;测试发送的数据,每1秒加1
T0_QUIT:
POP ACC
POP PSW
POP DPL
POP DPH
RETI
;;;;;;;LED 送显处理程序;;;;;;;;;;
;;;;;;;LED 送显处理程序;;;;;;;;;;
DISPLAY_PRG:
MOV A,#0FFH
MOV P1,A
LCALL DISP
;;;;;;;UP IS DISABLE DISPLAY;;;;;;;;;;
MOV A,#DISPLAYBUF0
ADD A,DISP_POINT
MOV R0,A
MOV A,@R0
MOV DPTR,#DISPSEG_TAB
MOVC A,@A+DPTR
LCALL DISP
;;;;;;;;UP IS SEND SEG;;;;;
MOV P1,#0FFH
MOV A,DISP_POINT
RL A
MOV DPTR,#DISPBIT_TAB
JMP @A+DPTR
;LED段码译码
DISPSEG_TAB:
DB 0C0H,0F9H,0A4H,0B0H,099H,092H,082H,0F8H ; //0X00--0X07
DB 080H,090H,088H,083H,0c6H,0a1H,086H,08eH ; //0X08--0X0f
DB 0c8H,08cH,0bfH ; //n, p, -
DISP:
MOV R3,#08H
DUP: RLC A
MOV P1.0,C
CLR P1.1
SETB P1.1
DJNZ R3,DUP
RET
;LED位跳转
DISPBIT_TAB:
JMP DISP_LED0
JMP DISP_LED1
JMP DISP_LED2
JMP DISP_LED3
JMP DISP_LED4
DISP_LED0:
CLR EN_DISPBIT0
JNB FLIGHBIT0,DISP_QUIT
JNB FLIGHSYNC,DISP_QUIT
SETB EN_DISPBIT0
AJMP DISP_QUIT
DISP_LED1:
CLR EN_DISPBIT1
JNB FLIGHBIT1,DISP_QUIT
JNB FLIGHSYNC,DISP_QUIT
SETB EN_DISPBIT1
AJMP DISP_QUIT
DISP_LED2:
CLR EN_DISPBIT2
JNB FLIGHBIT2,DISP_QUIT
JNB FLIGHSYNC,DISP_QUIT
SETB EN_DISPBIT2
AJMP DISP_QUIT
DISP_LED3:
CLR EN_DISPBIT3
JNB FLIGHBIT3,DISP_QUIT
JNB FLIGHSYNC,DISP_QUIT
SETB EN_DISPBIT3
AJMP DISP_QUIT
DISP_LED4:
CLR EN_DISPBIT4
JNB FLIGHBIT4,DISP_QUIT
JNB FLIGHSYNC,DISP_QUIT
SETB EN_DISPBIT4
DISP_QUIT:
RET
;;;;;;;;;;系统出错时显示
DISP_ERROR:
MOV R0,#DISPLAYBUF0
INC R0
MOV @R0,#0EH
INC R0
MOV @R0,#12H
INC R0
MOV A,ERROR_STATUS
ANL A,#0F0H
SWAP A
MOV @R0,A
INC R0
MOV A,ERROR_STATUS
ANL A,#0FH
MOV @R0,A
MOV FLIGHDISP,#01FH
RET
;;;;;;;;;;CAN通讯正常时显示
DISP_OK:
CLR A
MOV FLIGHDISP,A
MOV ERROR_STATUS,A
MOV R0,#DISPLAYBUF0+1
MOV @R0,#0
INC R0
MOV @R0,#12H
INC R0
MOV A,RCV_DATA_BUF3
ANL A,#0F0H
SWAP A
MOV @R0,A
INC R0
MOV A,RCV_DATA_BUF3
ANL A,#0FH
MOV @R0,A
RET
DSEG_CONTRL:
CLR C
INC DISP_POINT
MOV A,DISP_POINT
CJNE A,#05,MOVEDISP
DSEG_CONTRL1:
MOV DISP_POINT,#00
RET
MOVEDISP:
JNC DSEG_CONTRL1
RET
$INCLUDE (SJA_BCANFunc.ASM) ;导入子程序文件
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -