⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 can485.asm

📁 CAN总线控制器sja1000及CAN收发器82C250的应用
💻 ASM
字号:

;程序功能:用于CAN总线与RS485总线之间的通讯转换
;修改日期:2004/04/08
;============================================================================
   ;定义伪指令
         INDICATOR    BIT         P3.3           ;测试信号输出位(用于工作指示)
         RT           BIT         P3.4           ;RS485允许接收/允许发送控制位
         ID           EQU         30H            ;本机识别码寄存器
         COMMAND      EQU         ID+1           ;命令寄存器
         SENT         BIT         00H            ;CAN总线发送标志位

         ORG          0000H
         SJMP         START                      ;主程序入口
         ORG          0003H
         LJMP         INT_0                      ;外部中断0入口
         ORG          000BH
         LJMP         INT_T0                     ;定时器0中断入口
;        ORG          0023H
;        LJMP         INT_S                      ;串口中断入口
START:
;============================================================================
   ;程序初始化
         MOV  SP,#60H
         SETB indicator                          ;灭工作指示灯
         SETB RT
         CLR  A
         MOV  ID,A
         MOV  COMMAND,A
         CLR  SENT
   ;初始化串行口,定时器
         MOV  TMOD,#21H                          ;T1工作于方式2,用作波特率发生器; T0工作于方式1
         MOV  TH1,#0FDH                          ;波特率设置为9600 bps
         MOV  TL1,#0FDH
         MOV  TH0,#00H                           ;定时器T0装入初值,定时时间为 65535us
         MOV  TL0,#00H
         MOV  PCON,#00H                          ;SMOD=0
         SETB TR1                                ;启动T1
         SETB TR0                                ;启动T0
         MOV  SCON,#50H                          ;串口工作方式1, SM2=0,REN=1允许接收
         SETB ET0                                ;允许T0中断
         SETB ES                                 ;允许串口中断
         SETB EA                                 ;CPU开中断
         LCALL SJAINI                            ;初始化SJA1000
         SJMP  $
;============================================================================
   ;外部中断0服务程序
INT_0:
            CLR EX0                              ;关外部中断0
	    PUSH ACC                             ;保护现场
	    PUSH DPL
	    PUSH DPH
	    PUSH PSW
	    MOV A,R0
	    PUSH ACC
	    MOV A,R2
	    PUSH ACC

	    MOV DPTR,#0FF03H                     ;指向中断寄存器
	    MOVX A,@DPTR                         ;读中断寄存器
	    ANL A,#04H                           ;检查接收错误 (00000100B)
	    JNZ ENDI                             ;ACC.2=1,错误中断

	    MOV DPTR,#0FF02H 	                 ;指向状态寄存器
	    MOVX A,@DPTR                         ;读状态寄存器
            JNB ACC.0,ENDI                       ;ACC.0=0,无可用信息;ACC.0=1,RXFIFO中有可用信息

	    MOV DPTR,#0FF14H                     ;
     	    MOVX A,@DPTR                         ;读取ID
     	    XRL A,ID                             ;
     	    JNZ ENDI                             ;不是本节点ID,退出

	    MOV DPTR,#0FF15H
	    MOVX A,@DPTR                         ;读取数据长度
	    MOV R2,A		                 ;数据长度暂存于R2

            MOV R0,#31H                          ;指向RAM存储单元首地址
DATALOP:    INC DPTR
	    MOVX A,@DPTR                         ;接收数据
            MOV @R0,A
            INC R0
	    DJNZ R2,DATALOP

            MOV DPTR,#0FF01H                     ;指向命令寄存器
	    MOV A,#04H                           ;将04H写入命令寄存器
	    MOVX @DPTR,A                         ;ACC.2=1,接收缓冲器中存放信息的内存空间被释放

            MOV A,#7dH                           ;
	    XRL A,COMMAND                        ;
            JNZ ENDI                             ;
            SETB SENT                            ;
ENDI:
            MOV DPTR,#0FF00H                     ;指向控制寄存器
            MOV A,#62H                           ;将62H (01100010B)写入控制寄存器
	    MOVX @DPTR,A
	    POP ACC
	    MOV R2,A
	    POP ACC
	    MOV R0,A
	    POP PSW
	    POP DPH
	    POP DPL
	    POP ACC
	    SETB EX0                             ;INT0开中断
            RETI                                 ;中断返回
;============================================================================
   ;初始化SJA1000子程序
SJAINI:
            MOV A,#0FFH                          ;从P1口读入拨码状态
	    MOV P1,A
	    MOV A,P1
	    ANL A,#0FFH
            MOV P1,#0FFH

            ADD A,#10H                           ;当前节点ID 为拨码状态+10H 即: 16(0#),17(1#)...
            MOV ID,A                             ;将拨码对应的节点号存入ID寄存器
	    SETB PX0                             ;设置INT0为最高优先级
	    CLR IT0			         ;
	    CLR EX0                              ;关INT0中断

LOOP0:      MOV DPTR,#0FF00H                     ;指向控制寄存器
            MOV A,#61H                           ;将61H (01100001B)写入控制寄存器
            MOVX @DPTR,A                         ;SJA1000检测到复位请求后,中止当前接收/发送的信息进入复位模式
            CLR  A
            MOVX A,@DPTR                         ;读控制寄存器
            NOP
            NOP
            ANL A,#01H                           ;取出控制寄存器的最低位
            JZ  LOOP0                            ;ACC.0=0,重新复位

            MOV  DPTR,#0FF1FH                    ;指向内部时钟分频器
            MOV  A, #40H
            MOVX @DPTR,A

            MOV  DPTR,#0FF06H		         ;指向总线定时寄存器0 Clkout=fosc/2
            MOV  A,#53H                          ;波特率为20Kbps,最大传输距离为3.3千米
            MOVX @DPTR,A

            MOV  DPTR,#0FF07H                    ;指向总线定时寄存器1
            MOV  A,#2FH          		 ;波特率为20Kbps
            MOVX @DPTR,A

            MOV  DPTR,#0FF08H		         ;指向输出控制寄存器
            MOV  A,#1AH
            MOVX @DPTR,A

	    MOV  A,ID		                 ;A<==ID
	    MOV  DPTR,#0FF04H                    ;指向验收代码寄存器
	    MOVX @DPTR,A                         ;ID写入验收代码寄存器

            MOV  DPTR,#0FF05H		         ;指向验收屏蔽寄存器
	    MOV  A,#0C0H
	    MOVX @DPTR,A

LOOP1:   MOV  DPTR,#0FF00H		         ;指向控制寄存器
         MOV  A,#6AH                             ;使SJA1000进入工作模式
         MOVX @DPTR,A
         CLR  A
         MOVX A,@DPTR
         NOP
         NOP
         ANL  A,#01H
         JNZ  LOOP1                               ;写入不正确,重写
         SETB EA                                  ;CPU开中断
         SETB EX0                                 ;开外部中断0
         RET
;============================================================================
   ;T0中断服务程序
INT_T0:  PUSH ACC
         PUSH PSW
         MOV  TH0,#00H
         MOV  TL0,#00H
         CPL  indicator
QUIT:    POP  PSW
         POP  ACC
         RETI

         END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -