;************************************************************************
;*函数: BCAN_CMD_PRG *
;*应用资源: DPTR,ACC,R7,F0 *
;*参数说明: R7,存放命令字 *
;* 0x01 ;//发送请求命令 *
;* 0x02 ;//夭折发送命令 *
;* 0x04 ;//释放接收缓冲区 *
;* 0x08 ;//清除超载状态 *
;* 0x10 ;//进入睡眠状态命令 *
;* *
;*返回值: F0,存放返回值 *
;* 0 ; 执行命令成功 *
;* 1 ; 执行命令失败 *
;* *
;*说明:本子程序为SJA1000的命令执行程序 *
;************************************************************************
;*子程序调用示例: *
;* USER_CODE: ;;用户代码 *
;* ----- ----- *
;* MOV R7, #01H ;;发送请求命令 *
;* LCALL BCAN_CMD_PRG ;;调用子程序 *
;* JNB F0, USER_CODE1 ;;成功,继续用户代码 *
;* LJMP ERROR_PRG ;;失败,跳到错误处理 *
;* *
;* USER_CODE1: *
;* ----- ----- ;;用户代码 *
;************************************************************************
BCAN_CMD_PRG:
MOV A, R7
CJNE A, #01, BCAN_CMD1
;发送请求命令
MOV R0, #REG_COMMAND; 地址指向命令寄存器
MOVX @R0, A ;写入命令字
CLR F0
RET
BCAN_CMD1:
CJNE A, #02, BCAN_CMD2
;;//夭折发送命令
MOV R0, #REG_STATUS ;地址指向状态寄存器
MOVX A, @R0 ;判断是否有正在发送的状态
SETB F0
JB ACC.5, BCAN_CMD_QUIT
CLR F0
BCAN_CMD_QUIT:
RET
BCAN_CMD2:
CJNE A, #04, BCAN_CMD3
;释放接收缓冲区
MOV R0, #REG_COMMAND; 地址指向命令寄存器
MOVX @R0, A ;写入命令字
NOP
NOP
MOV R0, #REG_STATUS ;判断是否释放成功
MOVX A, @R0
SETB F0
JB ACC.0, BCAN_DB_QUIT ;不成功跳转
CLR F0
BCAN_DB_QUIT:
RET
BCAN_CMD3:
CJNE A, #08, BCAN_CMD4
;清除超载状态
MOV R0, #REG_COMMAND; 地址指向命令寄存器
MOVX @R0, A ;写入命令字
NOP
NOP
MOV R0, #REG_STATUS ;判断清除超载是否成功
MOVX A, @R0
SETB F0
JB ACC.1, BCAN_DOVER_QUIT ;不成功跳转
CLR F0
BCAN_DOVER_QUIT:
RET
BCAN_CMD4:
CJNE A, #10H, BCAN_CMD5
;进入睡眠状态命令
MOV R0, #REG_COMMAND; 地址指向命令寄存器
MOVX @R0, A ;写入命令字
CLR F0
BCAN_CMD5:
RET
;***************************************************************
;* 子程序: INIT_AT89S52 *
;* 应用资源: R0 R2 *
;* 参数说明: 无 *
;* 返回值: F0=0 ;函数执行成功 *
;* F0=1 ;函数执行失败 *
;* 说明: 完成和AT89S52相关的程序初始化工作,包括使用的RAM *
;* 清零、中断使能、中断优先级设置、 中断标志位初始化*
;* *
;***************************************************************
;*子程序调用示例: *
;* USER_CODE: ;;用户代码 *
;* ----- ----- *
;* CALL INIT_AT89S52 ;;调用子程序 *
;* JNB F0, USER_CODE1 ;;成功,继续用户代码 *
;* JMP ERROR_PRG ;;失败,跳到错误处理 *
;* *
;* USER_CODE1: *
;* ----- ----- ;;用户代码 *
;***************************************************************
INIT_AT89S52:
CLR F0
;//清零中断标志位
CLR EI_FLAG
CLR TI_FLAG
CLR RI_FLAG
CLR DOI_FLAG
;*****************************************************************************
;//串行口初始化
;//定时器1产生波特率,方式2
MOV TMOD , #00100000B ;方式2 可自动装载的8位计数器
;//串口方式1,8位数据位UART 1位起始位 1位停止位 无奇偶校验位
MOV SCON , #01000000B
;波特率设定
ANL PCON , #01111111B ;SMOD=0
MOV TL1 , #0FDH ;波特率9600
MOV TH1 , #0FDH ;自动装载值
;*****************************************************************************
;//中断系统初始化
;SETB EA ;开发总中断
;SETB EX0 ;外部中断0使能
;//函数返回
;SETB F0
RET
;***************************************************************
;* 子程序: HARD_RESET_SJA1000 *
;* 应用资源: A , R0 , R2 *
;* 参数说明: 无 *
;* 返回值: F0=0 ;函数执行成功 *
;* F0=1 ;函数执行失败 *
;* 说明: 通过单片机的P1.4口将SJA1000硬件复位 *
;* *
;***************************************************************
;*子程序调用示例: *
;* USER_CODE: ;;用户代码 *
;* ----- ----- *
;* CALL RESET_SJA1000 ;;调用子程序 *
;* JNB F0, USER_CODE1 ;;成功,继续用户代码 *
;* JMP ERROR_PRG ;;失败,跳到错误处理 *
;* *
;* USER_CODE1: *
;* ----- ----- ;;用户代码 *
;***************************************************************
HARD_RESET_SJA1000:
CLR SJA1000_RESET ;低电平复位
MOV R4,#60
CALL DELAYNMS ;延时60MS 1UF电容 50K电阻 RC="50ms"
SETB SJA1000_RESET
MOV R2,#50
HARD_RESET_SJA1000_LOOP1:
NOP
DJNZ R2 , HARD_RESET_SJA1000_LOOP1
;//检测SJA1000控制寄存器的CR.0位
MOV R0 , #REG_CONTROL
MOVX A , @R0
JB ACC.0 , RESET_OK
RESET_FAILURE:
CLR F0
RET
RESET_OK:
SETB F0
RET
;***************************************************************
;* 子程序: INIT_SJA1000 *
;* 应用资源: A , R0 , R2 *
;* 参数说明: 无 *
;* 返回值: F0=0 ;函数执行成功 *
;* F0=1 ;函数执行失败 *
;* 说明: 对SJA1000进行通信设置。包括: *
;* (1)测试SJA1000和AT89S52之间的通信端口测试 *
;* (2)设置验收滤波器和验收屏蔽寄存器 *
;* (3)设置总线时序寄存器0以决定波特率 *
;* (4)设置总线时序寄存器1以决定采样点 *
;* (5)设置时钟分频寄存器以确定SJA1000的工作模式、旁 *
;* 路和时钟输出端口关闭 *
;* (6)配置输出控制寄存器 *
;* 初始化完成后程序自动将SJA1000退出复位模式 *
;***************************************************************
;*子程序调用示例: *
;* USER_CODE: ;;用户代码 *
;* ----- ----- *
;* CALL INIT_SJA1000 ;;调用子程序 *
;* JNB F0, USER_CODE1 ;;成功,继续用户代码 *
;* JMP ERROR_PRG ;;失败,跳到错误处理 *
;* *
;* USER_CODE1: *
;* ----- ----- ;;用户代码 *
;***************************************************************
INIT_SJA1000:
;测试SJA1000接口是否正常
MOV ERRORCOUNT , #05H ;5次,报错
INIT_SJA1000_LOOP1:
CALL BCAN_CREATE_COMMUNATION ;调用SJA1000接口测试函数
JNB F0,INIT_SJA1000_FILTER ;接口正常,初始化SJA1000
DJNZ ERRORCOUNT , INIT_SJA1000_LOOP1 ;接口不正常,再检测
MOV ERROR_STATUS , #SJA_INTFACE_ERR
JMP SUB_ERROR_HANDLE ;错误处理
INIT_SJA1000_FILTER:
;设置验收滤波器和验收屏蔽寄存器
MOV ERRORCOUNT , #05H ;5次,报错
INIT_SJA1000_LOOP2:
MOV R7 , #0AAH ;;只允许接收ID号高8位为'10101010'
MOV R6 , #0FFH ;;都可接收
CALL BCAN_SET_OBJECT ;;调用子程序
JNB F0 , INIT_SJA1000_BAUD ;;成功,继续用户代码
DJNZ ERRORCOUNT , INIT_SJA1000_LOOP2 ;接口不正常,再检测
MOV ERROR_STATUS , SJA_INITFILTER_ERR
JMP SUB_ERROR_HANDLE ;;失败,跳到错误处理
INIT_SJA1000_BAUD:
;设置波特率
MOV ERRORCOUNT , #05H ;5次,报错
INIT_SJA1000_LOOP3:
MOV R7 , #4 ;12MHz 100K
CALL BCAN_SET_BANDRATE ;设置波特率为100k
JNB F0 , INIT_SJA1000_CLOCK ;判断设置是否成功
DJNZ ERRORCOUNT , INIT_SJA1000_LOOP3 ;接口不正常,再检测
MOV ERROR_STATUS , #SJA_INITBTR_ERR
JMP SUB_ERROR_HANDLE
INIT_SJA1000_CLOCK:
;设置输出控制、时钟分频
MOV ERRORCOUNT , #05H ;5次,报错
INIT_SJA1000_LOOP4:
MOV R7 , #0BAH ;正常输出模式 OCR 推挽 极性正常
;SJA1000的TX0 接到82C250的TXD
MOV R6 , #48H ;BASIC CAN,禁止内部比较器、禁止CLKOUT
CALL BCAN_SET_OUTCLK ;
JNB F0 , EXIT_RESET_MODE ;判断设置是否成功
DJNZ ERRORCOUNT , INIT_SJA1000_LOOP4
MOV ERROR_STATUS , #SJA_INITOCLK_ERR
JMP SUB_ERROR_HANDLE
EXIT_RESET_MODE:
;SJA1000退出复位模式,进入工作模式
MOV ERRORCOUNT , #005H ;5次,报错
INIT_SJA1000_LOOP5:
CALL BCAN_QUIT_RETMODEL ;退出复位状态
JNB F0 , SJA1000_INIT_END ;判断设置是否成功
DJNZ ERRORCOUNT , INIT_SJA1000_LOOP5
MOV ERROR_STATUS , #0FEH ;#SJA_INIT_ERR
JMP SUB_ERROR_HANDLE
SJA1000_INIT_END:
CLR F0
RET
SUB_ERROR_HANDLE:
SETB F0
RET
;**************************************************************
;**************************************************************
;功 能: *
; 串口数据发送子程序 *
;入口条件: *
; 将要发送的数据缓冲区首地址放入R0中 *
;**************************************************************
;串口发送子程序
UART_SEND:
CLR TI
MOV A,@R0
MOV SBUF,A
JNB TI,$
CLR TI
INC R0
DJNZ R7,UART_SEND
RET
;2004.12.19调通
;****************DELAYNMS.ASM***************************************
;程序功能:本程序实现延时Nms.
;入口参数:R4存放延时的毫秒数.
;出口参数:无.
;占用资源:R3
;占用堆栈:0字节.
;占用标号:DELAYNMS,DELAYNMS_LOOP.
;子程序调用:无.
;说明:1,本程序适用于晶振频率为12MHZ时,即单周期指令用时1us的模式,
; 时间计算公式为(249*4+1+1+2)*(R4)+2=1000*(R4)+2
; 2,未加上调用该子程序的指令执行的时间,如 LCALL DELAYNMS
; 3,使用该子程序前需定义符号DELAYMS_NUM,例DELAYMS_NUM DATA 55H
DELAYNMS: MOV R3,#0F9H ;1us
DELAYNMS_LOOP:
NOP
NOP
DJNZ R3,DELAYNMS_LOOP ;2us
NOP
DJNZ R4,DELAYNMS ;2us
RET
;2us
;*************************************************************
;结束