您的位置:控制工程论坛网论坛 » 现场总线 » Can总线收发实例 5

xilinxue

xilinxue   |   当前状态:在线

总积分:16186  2024年可用积分:0

注册时间: 2008-06-26

最后登录时间: 2020-03-22

空间 发短消息加为好友

Can总线收发实例 5

xilinxue  发表于 2008/9/23 13:05:33      908 查看 0 回复  [上一主题]  [下一主题]

手机阅读

;************************************************************************
;*函数:      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


;*************************************************************


;结束

1楼 0 0 回复