www.pudn.com > can+sja1000.rar > basicMainH.asm
;2007.1.25调通
;于士友 2007.1.22
;can总线上位机接收端测试程序 调试用
;串口调通 2007.1.26
;下位机发送一帧数据 0AAH 08H 55H 55H 55H 55H 55H 55H 55H 55H
;加上ID等共10个字节(不连CRC)。上位机接收,并根据出错状态等改变相应
;的端口的状态。并把接收到的10个子节发送到串口,最后死循环。
;**************************************************************
;*************** BASIC CAN 测试程序 ***************************
;* 说明: *
;* 本程序测试硬件电路在BASIC CAN 模式下是否能够正常工作 *
;* 电路同样适用于PeliCan 模式。不包括串口发送程序 *
;**************************************************************
;* 测试电路说明: *
;* SJA1000 的AD.0 ~ AD.7 连接单片机的P0.0 ~ P0.7 *
;* SJA1000 的RST 通过单片机的P1.4口控制 *
;* 单片机型号: *
;* AT89S52 11.0592MHz *
;* CAN 控制器及收发器: *
;* SJA1000 PCA82C250 12MHz *
;**************************************************************
;* 程序开始编制日期 2007. 1. 10 *
;* 程序调试通过日期 *
;* 程序版本号 Ver 1.0 *
;**************************************************************
;**************************************************************
;//以下为电路中的资源定义
;硬件电路相关
SJA1000_RESET BIT P1.4
SJA1000_CS BIT P1.5
SJA1000_INT BIT INT0
;//包含周立功SJA1000内部资源定义头文件
$INCLUDE (SJA_BCANCONF.ASM)
;//RAM 资源分配
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 04AH ;接收缓冲区
RCV_DATA_BUF2 DATA 04BH
RCV_DATA_BUF3 DATA 04CH
RCV_DATA_BUF4 DATA 04DH
RCV_DATA_BUF5 DATA 04EH
RCV_DATA_BUF6 DATA 04FH
RCV_DATA_BUF7 DATA 050H
RCV_DATA_BUF8 DATA 051H
RCV_DATA_BUF9 DATA 052H
RCV_DATA_BUF10 DATA 053H
ERROR_STATUS DATA 030H ;错误状态表示
TEST_DATA DATA 031H ;测试发送数据
SAVE_INT_INFO DATA 032H ;保存SJA1000中断寄存器的内容
ERRORCOUNT DATA 033H ;错误计数
;//SJA1000中断位标志定义
EI_FLAG BIT 00H ;错误中断
DOI_FLAG BIT 01H ;数据溢出中断
TI_FLAG BIT 02H ;发送中断
RI_FLAG BIT 03H ;接收中断
;***************************************************************************
;//中断服务程序地址定义
ORG 0000H
JMP MAIN
ORG 0003H ;外部中断0
;JMP INT_RECEIVE
;***************************************************************************
;//主程序开始
ORG 0035H
MAIN:
NOP
NOP
NOP
MOV R7,#00H
DJNZ R7,$ ;延时
;内部RAM清零
MOV R0,#07fH
CLR A
MOV @R0,A
DJNZ R0,$-1
MOV @R0,A
CLR EA
MOV IE,#00H
MOV IP,#00H
MOV SP , #60H
MOV P0,#0FFH
MOV P1,#0FFH
MOV P2,#0FFH
MOV P3,#0FFH
CALL INIT_AT89S52 ;单片机初始化
SETB TR1 ;启动定时器1 产生波特率
;MOV P2,#00H ;调试用
CALL HARD_RESET_SJA1000 ;硬件复位SJA1000
CLR SJA1000_CS ;选通SJA1000
CALL INIT_SJA1000 ;初始化SJA1000
JNB F0,INIT_SJA1000_INT ;初始化成功则跳
CLR P1.1 ;调试用 初始化失败拉低 ;调试用
;;设置SJA1000中断使能
INIT_SJA1000_INT:
MOV R0,#REG_CONTROL
MOVX A,@R0 ;只允许接收中断
ANL A,#01H
ORL A,#02H
MOVX @R0,A
;SETB SJA1000_CS
;//进入主循环
MAIN_LOOP:
SETB SJA1000_INT ;置一以便输入
JB SJA1000_INT,MAIN_LOOP ;为1则继续检测
;接收到数据
CLR SJA1000_CS
MOV R0,#REG_INTERRUPT
MOVX A,@R0
JNB ACC.0,MAIN_LOOP
CLR P1.0 ;如果接收到数据 则拉低 ;调试用
MOV R4,#200
CALL DELAYNMS ;延时以等待数据接收完
;***************************************************************************
;调试处理部分
MOV R0,#REG_RxBuffer1 ;接收缓冲区的首地址
MOVX A,@R0
XRL A,#0AAH
JNZ RCVDATA_PRG ;ID不为0AAH则跳
INC R0
MOVX A,@R0
XRL A,#08H
JNZ RCVDATA_PRG
INC R0
MOV R7,#08
DEBUG_LOOP:
MOVX A,@R0
XRL A,#055H
JNZ RCVDATA_PRG
INC R0
DJNZ R7,DEBUG_LOOP
CLR P1.2 ;如果接收到的与设定发送的不相符则拉低 ;调试用
;***************************************************************************
;接收数据处理部分
RCVDATA_PRG:
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 ;微处理器接收首地址
CALL UART_SEND ;调用串口发送程序
;***************************************************************************
JMP $
JMP MAIN_LOOP
;**************************************************************
;*子程序定义 *
;* *
;* *
;* *
;**************************************************************
;$INCLUDE (SJA_BCANCONF.ASM)
;************************************************************************
;* 广州周立功单片机发展有限公司 http://www.zlgmcu.com *
;************************************************************************
;************************************************************************
;* *
;* CAN 控制器SJA1000基本CAN汇编子程序说明(BasicCAN 工作方式) *
;* *
;************************************************************************
;************************************************************************
;* *
;* 目的: 用户在应用SJA1000组成CAN网络中通过简单的参数设置和调用 *
;* 本文件提供函数便能使自己的CAN系统进行基本的调试和运行 *
;* *
;* 文件名: SJA_BCANFUNC.ASM *
;* *
;* 模块名: -- *
;* *
;* 目标系统: 任何基于任何兼容8051指令的微处理器同SJA1000组成的CAN *
;* 系统 *
;* *
;* 应用语言: Keil ASM-51 or Intel ASM-51 *
;* *
;************************************************************************
;* 版本 :V1.0 *
;* *
;************************************************************************
;* 广州周立功单片机发展有限公司 保留所有的版权 *
;************************************************************************
;//以下为函数定义
;************************************************************************
;*函数: BCAN_CREATE_COMMUNATION *
;*应用资源: R0,ACC,F0 *
;*参数说明: 无 *
;*返回值: F0,存放返回值 *
;* 0 ; 表示SJA1000接口正常 *
;* 1 ; 表示SJA1000与处理器接口不正常 *
;* *
;*说明:该函数用于检测CAN控制器的接口是否正常 *
;************************************************************************
;*子程序调用示例: *
;* USER_CODE: ;;用户代码 *
;* ----- ----- *
;* LCALL BCAN_CREATE_COMMUNATION ;;调用子程序 *
;* JNB F0, USER_CODE1 ;;继续用户代码 *
;* LJMP ERROR_PRG ;;接口不正常跳到错误处理 *
;* *
;* USER_CODE1: *
;* ----- ----- ;;用户代码 *
;************************************************************************
BCAN_CREATE_COMMUNATION:
MOV R0,#REG_TEST ;对测试寄存器进行读写测试
MOVX A,@R0
MOV A,#0AAH ;写入值0AAH
MOVX @R0,A
SETB F0
NOP
MOVX A,@R0 ;读出值
CJNE A,#0AAH,BCAN_CM_QUIT ;测试写入读出是否正确
MOV A,#055H ;再次测试
MOVX @R0,A ;写入055H
NOP
NOP
MOVX A,@R0
CJNE A,#055H,BCAN_CM_QUIT ;测试写入读出是否正确
CLR A ;清零测试寄存器
MOVX @R0,A
CLR F0 ;接口正确
BCAN_CM_QUIT:
RET
;************************************************************************
;*函数: BCAN_ENTER_RETMODEL *
;*应用资源: DPTR,ACC,F0 *
;*参数说明: 无 *
;*返回值: F0,存放返回值 *
;* 0 ; 表示成功进入复位工作模式 *
;* 1 ; 表示不能进入复位工作模式 *
;* *
;*说明:CAN控制器进入复位工作模式 *
;************************************************************************
;*子程序调用示例: *
;* USER_CODE: ;;用户代码 *
;* ----- ----- *
;* LCALL BCAN_ENTER_RETMODEL ;;调用子程序 *
;* JNB F0, USER_CODE1 ;;继续用户代码 *
;* LJMP ERROR_PRG ;;复位请求不成功跳到错误处理 *
;* *
;* USER_CODE1: *
;* ----- ----- ;;用户代码 *
;************************************************************************
BCAN_ENTER_RETMODEL:
MOV R0, #REG_CONTROL ;控制寄存器访问
MOVX A, @R0 ;
ORL A, #01H ;置位复位请求
MOVX @R0, A ;
CLR F0
MOVX A, @R0 ;验证复位是否写入
JB ACC.0, BCAN_ER_QUIT
SETB F0 ;复位不成功
BCAN_ER_QUIT:
RET
;************************************************************************
;*函数: BCAN_QUIT_RETMODEL *
;*应用资源: R0,ACC,F0 *
;*参数说明: 无 *
;*返回值: F0,存放返回值 *
;* 0 ; 表示成功退出复位工作模式 *
;* 1 ; 表示不能退出复位工作模式 *
;* *
;*说明:CAN控制器退出复位工作模式,进入工作模式 *
;************************************************************************
;*子程序调用示例: *
;* USER_CODE: ;;用户代码 *
;* ----- ----- *
;* LCALL BCAN_QUIT_RETMODEL ;;调用子程序 *
;* JNB F0, USER_CODE1 ;;继续用户代码 *
;* LJMP ERROR_PRG ;;不能退出复位模式跳到错误处理 *
;* *
;* USER_CODE1: *
;* ----- ----- ;;用户代码 *
;************************************************************************
BCAN_QUIT_RETMODEL:
MOV R0,#REG_CONTROL ; 控制寄存器访问
MOVX A,@R0 ;
ANL A,#0FEH ;清零复位请求,进入工作状态
NOP
MOVX @R0, A
CLR F0
MOVX A,@R0
JNB ACC.0, BCAN_QR_QUIT ;验证是否退出复位状态
SETB F0
BCAN_QR_QUIT:
RET
;************************************************************************
;*函数: BCAN_DATA_WRITE *
;*应用资源: DPTR,ACC,R0,R7 *
;*参数说明: *
;* R0:存放待发送特定帧各式的数据的首地址 *
;* *
;*返回值: F0,存放返回值 *
;* 0 ; 表示将数据成功的送至发送缓冲区 *
;* 1 ; 表示上一次的数据正在发送, *
;* ; 表示发送缓冲区被锁定,不能写入数据 *
;* ; 表示写入数据错误 *
;* *
;*说明: 将待发送特定帧各式的数据,送入SJA1000发送缓存区中,然后启动 *
;* SJA1000发送。 *
;* 特定帧格式为:开始的两个字节存放 '描述符' ,以后的为数据 *
;* 描述符包括11位长的ID(标志符)\1位RTR\4位描述数据长度的DLC共16位 *
;* *
;*注:本函数的返回值仅指示,将数据正确写入SJA1000发送缓存区中与否。 *
;* 不指示SJA1000将该数据正确发送到CAN总线上完毕与否,要向总线发送请在*
;* 本子程序后调用发送命令 *
;************************************************************************
;*子程序调用示例: *
;* USER_CODE: ;;用户代码 *
;* ----- ----- *
;* MOV R0, #DATA_BUF0 ;;装入微处理器要发送数据的首地址 *
;* LCALL BCAN_DATA_WRITE ;;调用子程序 *
;* JNB F0, USER_CODE1 ;;继续用户代码 *
;* LJMP ERROR_PRG ;;写入发送缓冲区错跳到错误处理 *
;* *
;* USER_CODE1: *
;* ----- ----- ;;用户代码 *
;************************************************************************
BCAN_DATA_WRITE:
MOV R0, #REG_STATUS ;读取状态寄存器
MOVX A, @R0 ;判断上次发送是否完成
SETB F0
JNB ACC.3, BCAN_DW_QUIT ;正在发送退出
CLR F0
MOVX A, @R0 ;判断发送缓冲区是否锁定,
SETB F0
JNB ACC.2, BCAN_DW_QUIT ;锁定则跳出
CLR F0
INC R1 ;
MOV A, @R1 ;ID号的低3位 \RTR位 \数据长度DLC
DEC R1 ;恢复指针指向发送数据的首地址
MOV R0, #REG_TxBuffer1;发送缓冲区首地址
JB ACC.4, BCAN_WYB ;远程帧
;数据帧
ANL A, #0FH ;计算发送数据的长度
ADD A, #02H
MOV R7, A
AJMP BCAN_WRTXBUF ;
BCAN_WYB:
MOV R7, #02 ;写入发送缓冲区数据长度为2
BCAN_WRTXBUF:
MOV A, @R1 ;开始写入
MOVX @R0, A
SETB F0
MOVX A, @R0 ;校验写入的是否正确
XRL A, @R1
JNZ BCAN_DW_QUIT ;写入错误退出
CLR F0 ;正确写入继续
INC R1
INC R0
DJNZ R7, BCAN_WRTXBUF ;没有写完继续
BCAN_DW_QUIT:
RET
;************************************************************************
;*函数: BCAN_DATA_RECEIVE *
;*应用资源: R0,ACC,R1,R7,F0 *
;*参数说明: R0,存放微处理器保存数据缓冲区的首地址 *
;*返回值: F0=0;接收成功 *
;* F0=1;接收失败 *
;*说明:CAN控制器接收数据,仅限于接收数据 *
;************************************************************************
;*子程序调用示例: *
;* USER_CODE: ;;用户代码 *
;* ----- ----- *
;* MOV R1, #DATA_BUF0 ;;装入微处理器要发送数据的首地址 *
;* LCALL BCAN_DATA_RECEIVE ;;调用子程序 *
;* JNB F0, USER_CODE1 ;;成功,继续用户代码 *
;* LJMP ERROR_PRG ;;失败,跳到错误处理 *
;* *
;* USER_CODE1: *
;* ----- ----- ;;用户代码 *
;************************************************************************
BCAN_DATA_RECEIVE:
MOV R1, #REG_STATUS
MOVX A, @R1
SETB F0
JNB ACC.0, BCAN_DR_QUIT ;判断报文是否有效
CLR F0
MOV R1, #REG_RxBuffer2 ;接收报文的ID号的低3位 \RTR位 \数据长度DLC
MOVX A, @R1
MOV R1, #REG_RxBuffer1 ;接收缓冲区的首地址
JB ACC.4, BCAN_RCVYB ;接收到的是远程帧
;//数据帧
ANL A, #0FH ;计算接收到的数据长度
ADD A, #02H ;计算报文的长度
MOV R7, A
AJMP BCAN_RCVDATA
BCAN_RCVYB:
MOV R7, #02 ;远程帧
BCAN_RCVDATA: ;开始读取数据
MOVX A, @R1
MOV @R0, A
INC R0
INC R1
DJNZ R7, BCAN_RCVDATA
BCAN_DR_QUIT:
RET
;************************************************************************
;*子程序: BCAN_SET_BANDRATE *
;*应用资源: DPTR,ACC,R5,R6,R7,F0 *
;*参数说明: R7 波特率(Kbit/s) BTR0 BTR1 *
;* 0 20 053H, 02FH *
;* 1 40 087H, 0FFH *
;* 2 50 047H, 02FH *
;* 3 80 083H, 0FFH *
;* 4 100 043H, 02fH *
;* 5 125 03H, 01cH *
;* 6 200 081H, 0faH *
;* 7 250 01H, 01cH *
;* 8 400 080H, 0faH *
;* 9 500 00H, 01cH *
;* 10 666 080H, 0b6H *
;* 11 800 00H, 016H *
;* 12 1000 00H, 014H *
;*返回值: F0,存放返回值 *
;* 0 ;波特率设置成功 *
;* 1 ;波特率设置失败 *
;* *
;*说明:设置CAN控制器SJA1000通讯波特率.SJA1000的晶振为必须为16MHZ, *
;* 其它晶体的频率的值的波特率,需自己计算 。该子程序只能用于 *
;* 复位模式 *
;************************************************************************
;*子程序调用示例: *
;* USER_CODE: ;;用户代码 *
;* ----- ----- *
;* MOV R7, #06 ;;设置波特率100KBPS *
;* LCALL BCAN_SET_BANDRATE ;;调用子程序 *
;* JNB F0, USER_CODE1 ;;成功,继续用户代码 *
;* LJMP ERROR_PRG ;;失败,跳到错误处理 *
;* *
;* USER_CODE1: *
;* ----- ----- ;;用户代码 *
;************************************************************************
BCAN_SET_BANDRATE:
MOV A,R7 ;判断波特率的值是否存在
CLR CY
SUBB A,#13 ;
SETB F0
JNC BCAN_SETBR_QUIT ;输入的值大于12则不正确
CLR F0
MOV A,R7
RL A
MOV DPTR,#BCAN_SETBR ;查表找出相应的预设第一个值
MOVC A,@A+DPTR
MOV R5,A ;将数据保存
MOV A,R7 ;找出第二个值
RL A
INC A
MOVC A,@A+DPTR
MOV R6,A ;保存值
MOV R0,#REG_BTR0 ;装入波特率预设值,同步跳转宽度
;位宽度
MOV A,R5
MOVX @R0,A
SETB F0
NOP
MOVX A,@R0
XRL A,R5 ;判断写入是否正确
JNZ BCAN_SETBR_QUIT ;不正确
CLR F0
INC R0
MOV A,R6
MOVX @R0,A
SETB F0
NOP
MOVX A,@R0
XRL A,R6 ;判断写入是否正确
JNZ BCAN_SETBR_QUIT
CLR F0
BCAN_SETBR_QUIT:
RET
BCAN_SETBR:
DB 053H, 02FH ;20KBPS的预设值
DB 087H, 0FFH ;40KBPS的预设值
DB 047H, 02FH ;50KBPS的预设值
DB 083H, 0FFH ;80KBPS的预设值
;DB 043H, 02fH ;100KBPS的预设值
DB 042H, 02FH ;100KBPS的预设值 12MHZ晶振
DB 03H, 01cH ;125KBPS的预设值
DB 081H, 0faH ;200KBPS的预设值
DB 01H, 01cH ;250KBPS的预设值
DB 080H, 0faH ;400KBPS的预设值
DB 00H, 01cH ;500KBPS的预设值
DB 080H, 0b6H ;666KBPS的预设值
DB 00H, 016H ;800KBPS的预设值
DB 00H, 014H ;1000KBPS的预设值
;************************************************************************
;*子程序: BCAN_SET_OBJECT *
;*应用资源: R0,ACC,R6,R7,F0 *
;* R7:存放验收代码寄存器(ACR)的参数设置 *
;* R6:存放接收屏蔽寄存器(AMR)的参数设置 *
;*返回值: F0,存放返回值 *
;* 0 ;通信对象设置成功 *
;* 1 ;通信对象设置失败 *
;* *
;*说明:设置CAN节点的通讯对象,允许接收的报文ID号的高8位(D10--D3) 。 *
;* 允许接收的报文,是由AMR和ACR共同决定的. *
;* 满足以下条件的ID号的报文才可以被接收 *
;*[(ID.10-ID.3)≡(AC.7-AC.0)]||(AM.7-AM.0)≡11111111 *
;* 该子程序只能用于复位模式 * *
;************************************************************************
;*子程序调用示例: *
;* USER_CODE: ;;用户代码 *
;* ----- ----- *
;* MOV R7, #0AAH ;;只允许接收ID号高8位为'10101010'*
;* MOV R6, #00H ;; *
;* LCALL BCAN_SET_OBJECT ;;调用子程序 *
;* JNB F0, USER_CODE1 ;;成功,继续用户代码 *
;* LJMP ERROR_PRG ;;失败,跳到错误处理 *
;* *
;* USER_CODE1: *
;* ----- ----- ;;用户代码 *
;************************************************************************
BCAN_SET_OBJECT:
MOV R0,#REG_ACR ;写ACR寄存器
MOV A,R7
MOVX @R0,A
NOP
NOP
MOVX A,@R0
SETB F0
XRL A,R7 ;检验写入是否正确
JNZ BCAN_SETO_QUIT
CLR F0
INC R0 ;写AMR寄存器
MOV A,R6
MOVX @R0,A
NOP
NOP
MOVX A,@R0
SETB F0
XRL A,R6 ;检验写入是否正确
JNZ BCAN_SETO_QUIT
CLR F0
BCAN_SETO_QUIT:
RET
;************************************************************************
;*子程序: BCAN_SET_OUTCLK *
;*应用资源: R0,ACC,R6,R7,F0,B *
;* R7:存放输出寄存器(OCR)的参数设置 *
;* R6:存放时钟分品寄存器(REG_CDR)的参数设置 *
;*返回值: F0,存放返回值 *
;* 0 ;设置成功 *
;* 1 ;设置失败 *
;* *
;*说明:设置SJA1000的输出模式和时钟分频 。该子程序只能用于复位模式 * *
;************************************************************************
;*子程序调用示例: *
;* USER_CODE: ;;用户代码 *
;* ----- ----- *
;* MOV R7, #0AAH ;;输出为正常模式 *
;* MOV R6, #048H ;;禁止CLKOUT,BasicCAN模式 *
;* LCALL BCAN_SET_OUTCLK ;;调用子程序 *
;* JNB F0, USER_CODE1 ;;成功,继续用户代码 *
;* LJMP ERROR_PRG ;;失败,跳到错误处理 *
;* *
;* USER_CODE1: *
;* ----- ----- ;;用户代码 *
;************************************************************************
BCAN_SET_OUTCLK:
MOV R0,#REG_OCR ;写OCR寄存器
MOV A,R7
MOVX @R0,A
MOV B,A
NOP
NOP
MOVX A,@R0
SETB F0
CJNE A,B,BCAN_SETOC_QUIT ;检验写入是否正确
CLR F0
MOV R0,#REG_CDR ;写CDR寄存器
MOV A,R6
MOVX @R0,A
MOV B,A
MOVX A,@R0
SETB F0
CJNE A,B,BCAN_SETOC_QUIT ;检验写入是否正确
CLR F0
BCAN_SETOC_QUIT:
RET
;************************************************************************
;*函数: 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
;*************************************************************
END