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

📄 adcon.asm

📁 虚拟光驱的程序设计
💻 ASM
字号:
;ADuC812晶振为11.0592MHz
$MOD812                         ; Use 8052&ADuC812 predefined symbols

;CAN控制器SJA1000的片选地址为08000H
CR	  EQU	  8000H	  ;控制寄存器地址
CMR	  EQU  	8001H 	;命令寄存器地址
SR	  EQU  	8002H 	;状态寄存器地址
IR  	EQU  	8003H   ;中断寄存器地址
ACR   EQU   8004H	  ;验收代码寄存器地址
AMR   EQU  	8005H	  ;验收屏蔽寄存器地址
BTR0  EQU  	8006H	  ;总线定时寄存器0
BTR1  EQU  	8007H	  ;总线定时寄存器1
OCR   EQU  	8008H	  ;输出控制寄存器


;************************************************************************
;*发送缓冲区(内部地址0AH--13H)                                          *
;************************************************************************
TXB   EQU   800AH           ;发送缓冲区首址

;************************************************************************
;*接收缓冲区(内部地址014H--01DH)                                        *
;************************************************************************
RXB   EQU   8014H          ;接收缓冲区首址

;************************************************************************
;*内部地址 01EH 备用                                                    *
;************************************************************************

;************************************************************************
;*时钟分频寄存器(内部地址01FH)                                          *
;************************************************************************
CDR   EQU   801FH          ;时钟分频寄存器

;************************************************************************
;*SJA1000的命令字                                                       *
;************************************************************************
TR_CMD          EQU   01h          ;//发送请求命令
AT_CMD          EQU   02h          ;//夭折发送命令
RRB_CMD         EQU   04h          ;//释放接收缓冲区
CDO_CMD         EQU   08h          ;//清除数据溢出
GTS_CMD         EQU   010h         ;//进入睡眠状态命令  

;************************************************************************
;*SJA1000操作的错误                                                       *
;************************************************************************
SJA_INTFACE_ERR EQU   0FFH
SJA_INIT_ERR    EQU   0FEH       
SJA_RCV_ERR     EQU   0FDH
SJA_SEND_ERR    EQU   0FCH

SJA_INITOBJ_ERR   EQU  0FBH
SJA_INITBTR_ERR   EQU  0FAH
SJA_INITOCLK_ERR  EQU  0F9H

CSEG

CHAN    EQU     0               ; convert this ADC input channel..
                                ; ..chan values can be 0 thru 8
CHANNUM	EQU	    8

IP1	EQU	192
IP2	EQU	168	
IP3	EQU	1
IP4	EQU	47


	
;使用前变量定义
RCV_GOOD	    BIT	  00H	  ;成功的接收一帧标志
SEC_FLAG	    BIT	  01H	;一秒到标志
ERR_FLAG	    BIT	  02H	;监测到错误标志
OVER_FLAG	    BIT	  03H	;超载标志
DS_END_FLAG	  BIT	  04H	;SJA1000发送完成标志
WUI_FLAG	    BIT 	05H	;唤醒SJA1000标志 
T0IR          BIT 	06H	;定时器T0标志
SEND_DLM      BIT   07H ;发送次序标志(区分一轮采样(16字节)的两次发送)

SEC_COUNT_L	    EQU	  30H	;秒定时计数器
SEC_COUNT_H    	EQU   31H
SAVE_INT_INFO   EQU  	32H	;保存SJA1000中断寄存器的内容
ERRORCOUNT      EQU   33H  ;错误计数
DISPLAYBUF0     EQU   34H  ;显示缓冲区34H--38H

ERROR_STATUS    DATA  7CH	  ;错误状态表示
TEST_DATA       DATA	7FH    ;测试发送数据

SEND_DATA_BUF   EQU 	40H	;CPU发送缓冲区首址
REC_DATA_BUF    EQU	  50H	;CPU接收缓冲区首址

COUNTER_L		    DATA	80H    ;采样次数高位字节
COUNTER_H       DATA  08H    ;采样次数低位字节
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

          ORG 	  0000H
          LJMP    MAIN
;T0中断入口
          ORG     000BH     
          LJMP    LOOP1
;主程序开始
          ORG   	004BH			
MAIN:	    MOV	 SP,#7FH	
	        MOV  R0,#7FH
	        CLR  A             ;清零片内RAM
CLRIR:    MOV  @R0,A
          DJNZ R0,CLRIR
          ;MOV  P2,#0FFH
	        LCALL	SJA1000_INIT  ;SJA1000初始化        
	        ;SETB EA             ;开中断

;主程序监控流程
MLOOP:	  LCALL CANREC
          MOV   R0,#REC_DATA_BUF+2
          MOV   A,@R0
          CJNE   A,#03H,MLOOP   ;不是测试A/D采样命令,则一直查询直到接收到测试A/D采样命令
          LCALL  ADCONV
          LCALL  SENDDATA_PRG
          LCALL  SENDDATA_PRG
LOOP:     LCALL  CANREC
          MOV    R0,#REC_DATA_BUF+2
          MOV   A,@R0
          CJNE  A,#01H,LOOP
          MOV   R3,COUNTER_H	        
LOOP1:    MOV   R6,COUNTER_L                             
LOOP2:    ;MOV   TMOD,#01H     ;A/D采样命令,同时设置T0为方式1开始定时
          ;MOV   TL0,#33H      ;设置定时初值,定时3mS
          ;MOV   TH0,#0F5H
          ;SETB  ET0            ;允许T0中断
          ;SETB  TR0            ;启动T0定时
          LCALL	ADCONV         ;开始一轮采样
	        LCALL	SENDDATA_PRG   ;采完一轮后发送(CPU数据区的前4个通道的转换结果)	        
	        LCALL SENDDATA_PRG    ;继续发送后4个通道的转换结果
	        AJMP  $	        	          	        	        
      	  DJNZ  R6,LOOP2	        
	        DJNZ  R3,LOOP1
	        CLR   ET0             ;关闭T0中断
	        ;SJMP  MLOOP
          ;LCALL DELAY	 
          LCALL  FINISH


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	

ADCONV:	PUSH  3              ;将R3压入堆栈
	      MOV	R2,	#CHANNUM	;设置A/D采样的通道数(8通道)
	      MOV	R3,	#CHAN		;设置A/D采样的初始通道号
	      MOV	R0,	#SEND_DATA_BUF	;设置发送缓冲区首址,A/D转换结果存放地址
	      MOV	ADCCON1,#060H   	;设置A/D转换于正常工作状态
	
AGAIN:  
        MOV ADCCON2,R3   		;本次A/D转换的通道号
	      SETB SCONV          ;启动单步A/D转换
	      JB  SCONV,$ 	  		
     	  MOV	A,	ADCDATAH
      	MOV	@R0,	A		;将转换数据放入发送缓冲区
	      INC	R0	
	      MOV	A,	ADCDATAL
	      MOV	@R0,	A			
	      INC	R0  
     	  INC	R3
     	  DJNZ	R2,AGAIN		;通道没采完,则继续下一个通道
     	  POP   3        	     ;将R3弹出堆栈
	      RET




;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
             
SENDDATA_PRG:  PUSH  6                  ;将R6压入堆栈
               MOV  DPTR, #SR            ;状态寄存器
 							 MOVX A, @DPTR             ;从SJA1000读入状态寄存器值
 							 JB   ACC.4,SENDDATA_PRG   ;判断是否正在接受,正在接受则等待
TS0:           MOVX A,@DPTR
               JNB  ACC.3, TS0           ;判断上次发送是否完成,
                                         ;未完成则等待发送完成
TS1:           MOVX A, @DPTR
               JNB  ACC.2, TS1           ;判断发送缓冲器是否锁定,锁定则等待
TS2:           CLR  EA                  ;发送过程中关中断,以免干扰发送
               MOV  DPTR,  #TXB         ;SJA1000发送缓冲器首址
  	           MOV	A,	#01H             ;设置识别码为01H(即为1号节点)
      	       MOVX	@DPTR,	A	      
    	         INC 	DPTR			
  	           MOV	A,	#08H              ;数据场长度为8个字节
               MOVX	@DPTR,	A
               MOV  R6, A
               JB   SEND_DLM, SEND_SEQ2
SEND_SEQ1:     MOV  R0, #SEND_DATA_BUF    ;单片机片内RAM发送数据区地址,
    	                                    ;数据内容为A/D采样值
    	         SJMP MTBF1                           
SEND_SEQ2:     
               MOV  R0, #SEND_DATA_BUF+8 
               SJMP MTBF2 	                                        	
MTBF1:         MOV  A, @R0
               INC  DPTR
               MOVX @DPTR, A
               INC  R0
               DJNZ R6,  MTBF1             ;向发送缓冲器写8个字节
               SETB  SEND_DLM
               SJMP SEND_END
MTBF2:         MOV  A, @R0
               INC  DPTR
               MOVX @DPTR, A
               INC  R0
               DJNZ R6,  MTBF2             ;向发送缓冲器写8个字节
               CLR  SEND_DLM
SEND_END:    	 MOV  DPTR, #CMR            ;命令寄存器地址
    	         MOV  A, #01H  
    	         MOVX @DPTR, A              ;启动SJA1000发送
SENDLOOP1: 	   MOV	DPTR,   #SR  		;读取状态寄存器
      				 MOVX	A,      @DPTR        		;判断上次发送是否完成
      				 JB	ACC.5,  SENDLOOP1		;若正在发送,则取消上次未完成的发送
      				 JNB	ACC.3,  SENDLOOP1
      	       ;CLR  P3.4
    	         ;LCALL DELAY1
    	         ;LCALL DELAY1
    	         ;SETB P3.4
    	         POP   6                   ;将R6弹出堆栈
    	         SETB  EA
    	         RET
    	       

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

CANREC:	  CLR EA               ;关闭所有中断,以免影响接受
	        MOV	DPTR,	#SR	       ;状态寄存器地址
	        MOVX	A,	@DPTR		
	        ANL	A,	#0C3H		     ;读取总线关闭、错误状态、接收溢出、有数据等位状态	
	        JNZ	PROC		         ;有上述状态,进入处理
	        RET
	
PROC:     
;JNB ACC.7, PROCI
;BUSERR:	  MOV DPTR,#IR          ;中断寄存器;出现总线关闭
;	        MOVX A,@DPTR               ;读取中断寄存器,清除中断位(CPU的任何读操作
;	                                    ;都会将中断寄存器的相应中断位清除)
;	        MOV DPTR,#CR
;	        MOV A,#01H
;	        MOVX @DPTR,A         ;将控制寄存器复位请求位清零
;	        RET
;	        NOP
;PROCI:    MOV DPTR,#IR           ;总线正常
;          MOVX A,@DPTR                 ;读取中断寄存器,清除中断位
;          JNB  ACC.3, OTHER
;OVER:     MOV DPTR,#CMR        ;数据溢出
;          MOV A,#0CH
;          MOVX @DPTR,A         ;在命令寄存器中清除数据溢出和释放接收缓冲器                  
;	        RET
;	        NOP
;OTHER:    JB ACC.0, RECE       ;接收缓冲器有数据,转入接收子程序
;          LJMP RECOUT          ;接收缓冲器无数据,退出接收
;          NOP
    
RECE:     MOV	DPTR,	#RXB          ;读取并保存接收缓冲器的数据
          MOV R1,#REC_DATA_BUF	   ;CPU片内接收缓冲器首址
          MOVX A,@DPTR
          MOV @R1,A
          INC	DPTR
          INC R1
	        MOVX	A,	@DPTR
	        MOV @R1,A
	        ANL	A,	#0FH		;截取低四位是数据长度
	        MOV	R6,	A
RDATA0:	  INC DPTR
	        INC R1
	        MOVX A,@DPTR
	        MOV @R1,A
	        DJNZ R6,RDATA0
	        MOV DPTR,#CMR
	        MOV A,#04H
	        MOVX @DPTR,A    ;释放CAN接收缓冲器
          ;CLR	P3.4       
	        ;LCALL	DELAY1
	        ;LCALL	DELAY1
	        ;LCALL	DELAY1
	        ;LCALL DELAY1
	        ;SETB	P3.4
RECOUT:		SETB EA         ;开中断
          RET


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;SJA1000初始化子程序

SJA1000_INIT:				
							MOV	DPTR,	#CR	;控制寄存器访问
      				MOV	A,01H    ;置位复位请求,对SJA1000进行初始化
      				MOVX @DPTR,A
      				MOVX	@DPTR,	A
      				MOV	DPTR,	#CDR	;设置时钟分频寄存器CDR
	            MOV	A, #046H
	            MOVX	@DPTR,	A
	            MOV	DPTR,	#ACR	;设置验收代码寄存器ACR,低半字节为节点号,暂定为0号
	            MOV	A,	#00H        
            	MOVX	@DPTR,	A
            	INC 	DPTR			;设置接收屏蔽寄存器AMR
	            MOV	A,	#0FCH
	            MOVX	@DPTR,	A
	            MOV	DPTR,	#BTR0	;分别设置寄存器BTR0和BTR1
	            MOV	A,	#05H		;将波特率定为500kbps
             	MOVX	@DPTR,	A
	            INC	DPTR
	            MOV	A,	#0A3H
	            MOVX	@DPTR,	A
            	MOV	DPTR,	#OCR	;设置输出寄存器OCR
             	MOV	A,	#0FAH
	            MOVX	@DPTR,	A
            	MOV	DPTR,	#CR	;控制寄存器访问
	            MOVX	A,	@DPTR
	            MOV	A,	#1AH		;清零复位请求,返回工作状态,同时开接收中断、溢出中断和错误告警中断
	            MOVX	@DPTR,	A
	            RET

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;延时子程序
DELAY:				PUSH    6
              MOV   	R7,	#10       ;10*500uS=5mS
DLY1:  	      MOV   	R6,	#229      ;229*2.17uS=500uS      
     	        DJNZ  	R6,	$           
     	        DJNZ   	R7,	DLY1       
	            POP     6
	            RET	          
              
DELAY1:       PUSH    6           ;眼时10×5mS=50mS(用于指示发送状态灯)
              MOV     R6,#10
DLY2:         LCALL   DELAY
              DJNZ    R6,DLY2
              POP     6
              RET    
              	
FINISH:       NOP
              END

⌨️ 快捷键说明

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