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

📄 ad.asm

📁 pic16F877A 与 max5101 生成 DA 转化
💻 ASM
字号:
 LIST   P=16F877A                      
   INCLUDE <P16F877A.INC>                
   __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF&_HS_OSC & _PWRTE_ON & _WRT_OFF & _LVP_Off & _CPD_OFF&_DEBUG_ON 
; VARIABLE DEFINITIONS
;---------------------------------------------------------------------
; MACROS
;---------------------------------------------------------------------
errorlevel-202
errorlevel-203
errorlevel-205
errorlevel-207
errorlevel-208
errorlevel-302
errorlevel-305
errorlevel-306
MEMSET	MACRO	BUF_ADDR,VALUE,LENGTH
	MOVLW	LENGTH	; THIS MACRO LOADS A RANGE OF DATA MEMORY
	MOVWF	TEMP	; WITH A SPECIFIED VALUE.  THE STARTING
	MOVLW	BUF_ADDR	; ADDRESS AND NUMBER OF BYTES ARE ALSO 
	MOVWF	FSR	; SPECIFIED.
SETNEXT	MOVLW	VALUE
	MOVWF	INDF
	INCF	FSR,F
	DECFSZ	TEMP,F
	GOTO	SETNEXT
	ENDM
LFSR	MACRO	ADDRESS,OFFSET	; THIS MACRO LOADS THE CORRECT VALUE
	MOVLW	ADDRESS		; INTO THE FSR GIVEN AN INITIAL DATA 
	MOVWF	FSR		; MEMORY ADDRESS AND OFFSET VALUE.
	MOVF	OFFSET,W
	ADDWF	FSR,F
	ENDM


BANK_SEL 	MACRO SEL
	IF SEL==0
		BCF 	STATUS,RP1
		BCF 	STATUS,RP0
	ENDIF
	IF SEL==1
		BCF 	STATUS,RP1
		BSF 	STATUS,RP0
	ENDIF
	IF SEL==2
		BSF 	STATUS,RP1
		BCF 	STATUS,RP0
	ENDIF
	IF SEL==3
		BSF 	STATUS,RP1
		BSF 	STATUS,RP0
	ENDIF
	ENDM
        
#DEFINE 	bank_sel 	BANK_SEL
#DEFINE	 RX_BUF_LEN	32	; LENGTH OF RECEIVE BUFFER
#DEFINE	 NODE_ADDR	0X02	; I2C ADDRESS OF THIS NODE
			; CHANGE THIS VALUE TO ADDRESS THAT
			; YOU WISH TO USE.			; YOU WISH TO USE.
w_temp	EQU	0x71	; variable used for context saving 
status_temp	EQU	0x72	; variable used for context saving
pclath_temp	EQU	0x73	; variable used for context saving
ad_data     equ         0x74		
T_5	equ         0x75
T_6	equ         0x76
T_7	equ         0x77
FSR_TEMP   equ          0x78
FSRSAVE	EQU	0x79
PCLATHSAVE	EQU	0x7a
INDEX	EQU	0x7b	; INDEX TO RECEIVE BUFFER
TEMP	EQU	0x7c	;
RXBUFFER	EQU	RX_BUF_LEN	; HOLDS REC'D BYTES FROM MASTER
			; DEVICE.
CBLOCK   0X20
AD_Flag
DA_flag
endc
;**********************************************************************
	ORG     0x000             ; processor reset vector

	nop		  ; nop required for icd
  	goto    start              ; go to beginning of program
            

   
org    	0x04        	  		; interrupt vector location


	MOVWF	w_temp
	SWAPF	STATUS,W
	CLRF	STATUS
	MOVWF	STATUS_TEMP
	MOVF	FSR,W
	MOVWF	FSR_TEMP
	bank_sel 	0
        

tmro_interrupt
 tmro_interrupt
      bcf status,rp1  ;((
      BCF     STATUS,RP0
      btfss   intcon,2
      goto    check_rb0_interrupt
      bcf     intcon,2
    
      bsf     status,rp0
      btfss   i2c_timer_flag,0
      goto    about_hpt  ;((
      incfsz  low_i2c_timer
      goto    about_hpt   ;((
      incf    high_i2c_timer

;(((((((((((((((((((((((((
about_hpt
      bcf status,rp0  ;((
      bsf status,rp1   ;((
      btfss hpc,1
      goto dora_200
      incf hpt

;((((((((((((((((((((((

dora_200
       bsf status,rp0  ;((
      bcf status,rp1   ;((
      BTFSS      SIZE_FILTER,0
      GOTO       SC00_0
      INCF       SIZE_FILTER_TIMER
SC00_0
      BTFSS     SIZE_FILTER,1
      GOTO      SCOO_400
      INCF      LOCK_OUT_TIMER
SCOO_400
      btfss     valid_edge_flag,0
      goto      dora_555
      incf     rb0_valid_edge_cnt
dora_555
      btfss     start_up_flag,2
      goto       dora_455
      incfsz    ok_to_shutdown_timer_0
      goto      dora_455
      incf      ok_to_shutdown_timer_1
dora_455
      btfss     blower_reset_flag,0
      goto      dora_305
      incfsz    blower_delay_timer
      goto      dora_305
      incf      blower_delay_timer_1
dora_305
      btfss     blower_reset_flag,2
      goto      dora_306
      incf      blower_reset_timer
      movlw     0x08
      subwf      blower_reset_timer,w
      btfss      status,c
      goto        dora_306
      clrf         blower_reset_timer
      bcf           blower_reset_flag,2
      bcf          status,rp0
      bcf          portc,0
dora_306
      
      bcf      status,rp0
      BTFSS   SBY_STATUS,1
      GOTO    MOE_60
      INCFSZ  LOW_1_SEC_TIMER
      GOTO    MOE_60
      INCF    HIGH_1_SEC_TIMER
MOE_60
      BSF     STATUS,RP1
      BTFSS   BULK_COUNT,0
       GOTO   MOE_116
       INCFSZ  BULK_400_MSEC_L
       GOTO    MOE_116
       INCF    BULK_400_MSEC_H
MOE_116
      BCF     STATUS,RP1
      btfsS   sby_status,2
      goto     moe_61
      incfsz   low_1_sec_timer_1
      goto     moe_61
      incf     high_1_sec_timer_1
moe_61
      BTFSC   SBY_STATUS,5
      INCF    TIMER_5MSEC
      BTFSS   MUX,7
      GOTO     NEXT_TMR_0
      INCFSZ   LOW_FAN_DELAY_TIMER
      GOTO     NEXT_TMR_0
      INCF     HIGH_FAN_DELAY_TIMER,F
      GOTO     NEXT_TMR_0   ;((



ex_int	BTFSS	INTCON,INTF
	GOTO	isr_1
	BCF	INTCON,INTF
	CALL	ROUTINE_WHEN_FP_OCCUR
;-------------3rev

isr_1				  		;i2c communication
	btfss  	PIR1,SSPIF	  	;(0)
	goto    	int_next;isr_2
            BCF     	PIR1,SSPIF
       	call	isr_i2c	
            GOTO        int_next
;___________________________________________
; isr_2 here is for the add the interrupt
;___________________________________________

int_next   

	MOVF	FSR_TEMP,W
	MOVWF	FSR
;3rev     
 retfie0
            swapf status_temp,w   ;
            movwf status          ;
            swapf w_temp,f        ;
            swapf w_temp,w       
            retfie  


delay
  	MOVLW   .1
            MOVWF   T_5		
LOP0   	MOVLW 	.200				
	MOVWF 	T_6			
LOP1	MOVLW 	.249				
	MOVWF 	T_7				
LOP2	DECFSZ 	T_7					
	GOTO 	LOP2			
	DECFSZ 	T_6					
	GOTO 	LOP1
            DECFSZ 	T_5					
	GOTO 	LOP0					
				
	RETURN 



                
START
   BANKSEL PORTD                         
   CLRF    PORTD                          
   MOVLW   B'110000001'                    ;
   MOVWF   ADCON0                          ;
   bcf     pir1,adif
   BANKSEL OPTION_REG                     ;
   MOVLW   B'10000000'                     ;TMR0
   MOVWF   OPTION_REG                    
   CLRF    TRISD                          ;PORTD(LED)
   MOVLW   B'00001110'                    ;left,只选1个A/DRA0/AN0
   MOVWF   ADCON1                         ;选择VDD和VSS作参考源
                            ;
;---------------------------------
;--Here is the ccpl initial_part------------------------
	intial  
	   bcf status,rp0
	   bcf status,rp1
              

	movlw   0x00
	movwf   ccpr1l;count duty
	movlw   0x0F
	movwf   ccp1con ;count
	clrf    intcon
	bsf     status,rp0
	bsf     PCON,NOT_POR
	bsf     PCON,NOT_BOR
	movlw   0xff
	movwf   pr2 ; for the pwm period
	   
	movlw   0x00
	movwf   trisc; portc set to output
            clrf    trisd; portc set to output
            bsf     TRISA,0;AD input pin
            movlw   0x00
            movwf   trisb; portb set to output
            movlw   0x36		; Setup SSP module for 7-bit 
	banksel SSPCON
	movwf   SSPCON		; address, slave mode
	movlw   NODE_ADDR
	banksel SSPADD
	movwf   SSPADD
	clrf    SSPSTAT
            BCF     INTCON,T0IF
            MOVLW    0E0H
            IORWF    INTCON,F  
            banksel portd
            movlw   0x04
           ; movwf   T2CON     ;open the timer2
              
MAIN
  
   BTFSS AD_Flag,0
   goto  loop1
  ;
   BSF   ADCON0,GO                      ;开启A/D转换过程
   bcf   portc,2
WAIT
   BTFSS   PIR1,ADIF                      ;检测ADC中断标志位
   GOTO    WAIT                           ;如果没有转换结束,则返回循环检测
   MOVF    ADRESH,W                       ;W
   bcf     pir1,adif
   bcf   portc,2
   nop
   bsf   portc,2
   nop
   bcf   portc,2
 
  movwf   portd                           ;LED 
  MOVWF   ccpr1l    ;1
 

  
   

        
LOOP1  
bcf status,rp0
bcf status,rp1
;------------------------------
   bSf 	PORTB,1;wr(1)
   ;call    delay      ;
   nop
   bCf 	PORTB,3; select the channel A
   nop
   bCf 	PORTB,2
   nop
   bcf     portb,1
   movlw    .55
   movwf    portd              
;   call    delay      ;
;   movlw   .25   
;   movwf    portd              
;   call    delay      ;
;   movlw    .50  
;   movwf    portd              
;   call    delay      ;
;   movlw    .75  
;   movwf    portd              
;   call    delay      ;
;   movlw    .100  
;   movwf    portd              
;   call    delay      ;
;      movlw   .100   
;   movwf    portd              
;   call    delay      ;
;   movlw    .75 
;   movwf    portd              
;   call    delay      ;
;   movlw    .50  
;   movwf    portd              
;   call    delay      ;
;   movlw    .25  
;   movwf    portd              
;   call    delay      ;
;   movlw    .00  
;   movwf    portd              
;   call    delay      ;
;   clrf   portd 
;-----------------------------
   bSf 	PORTB,1
   nop
   bcf 	PORTB,3; select the channel B
   nop
   bsf 	PORTB,2
   nop
   bcf     portb,1
   movlw    0Xaa
   movwf    portd              
 ; call    delay      ;
   movlw   .55   
  movwf    portd              
;   call    delay      ;
;   movlw    .40  
;   movwf    portd              
;   call    delay      ;
;   movlw    .60  
;   movwf    portd              
;   call    delay      ;
;   movlw    .80  
;   movwf    portd              
;   call    delay      ;
;      movlw   .100   
;   movwf    portd              
;   call    delay      ;
;   movlw    .80 
;   movwf    portd              
;   call    delay      ;
;   movlw    .60  
;   movwf    portd              
;   call    delay      ;
;   movlw    .40  
;   movwf    portd              
;   call    delay      ;
;   movlw    .20  
;   movwf    portd              
;   call    delay      ;


;-------------------------  
   bSf 	PORTB,1
   nop
   bsf 	PORTB,3; select the channel C
   nop
   bcf 	PORTB,2
   nop
   bcf     portb,1
   movlw    .00 
;   movwf    portd          
;   call    delay      ;
;    movlw    .170   
;   movwf    portd          
;   call    delay  
;   bsf     PORTB,1;
;   nop
;   bcf PORTB,1;
;   nop
;;-----------------------------
;   bSf 	PORTB,1
;   nop
;   bsf 	PORTB,3; select the no  channel  no
;   nop
;   bsf 	PORTB,2
;   nop
;   bcf      PORTB,1
;   ;call    delay 
;
;  
;
  
    GOTO  LOOP1
   
                            ;循环进行A/D转换
;---------------------------------
ROUTINE_WHEN_FP_OCCUR


return

isr_i2c
;---------------------------------------------------------------------

;---------------------------------------------------------------------
;	THE I2C CODE BELOW CHECKS FOR 5 STATES:
;---------------------------------------------------------------------
;	STATE 1:  	I2C WRITE OPERATION, LAST BYTE WAS AN ADDRESS BYTE.
;
;	SSPSTAT BITS:  	S = 1, D_A = 0, R_W = 0, BF = 1
;
;	STATE 2:	  I2C WRITE OPERATION, LAST BYTE WAS A DATA BYTE.
;
;	SSPSTAT BITS:	  S = 1, D_A = 1, R_W = 0, BF = 1
;
;	STATE 3:	  I2C READ OPERATION, LAST BYTE WAS AN ADDRESS BYTE.
;
;	SSPSTAT BITS:	  S = 1, D_A = 0, R_W = 1, BF = 0
;
;	STATE 4:	  I2C READ OPERATION, LAST BYTE WAS A DATA BYTE.
;
;	SSPSTAT BITS:	  S = 1, D_A = 1, R_W = 1, BF = 0
;
;	STATE 5:  SLAVE I2C LOGIC RESET BY NACK FROM MASTER.
;	
;	SSPSTAT BITS:  S = 1, D_A = 1, R_W = 0, BF = 0
;
; FOR CONVENIENCE, WRITEI2C AND READI2C FUNCTIONS HAVE BEEN USED.
;----------------------------------------------------------------------

	BANKSEL	SSPSTAT
	MOVF	SSPSTAT,W	; GET THE VALUE OF SSPSTAT
	ANDLW	B'00101101'	; MASK OUT UNIMPORTANT BITS IN SSPSTAT.
	BANKSEL	TEMP	; PUT MASKED VALUE IN TEMP
	MOVWF	TEMP	; FOR COMPARISION CHECKING.

STATE1:				; WRITE OPERATION, LAST BYTE WAS AN
	MOVLW	B'00001001'	; ADDRESS, BUFFER IS FULL.
	XORWF	TEMP,W		; 
	BTFSS	STATUS,Z	; ARE WE IN STATE1?
	GOTO	STATE2		; NO, CHECK FOR NEXT STATE.....
	
	MEMSET	RXBUFFER,0,RX_BUF_LEN	; CLEAR THE RECEIVE BUFFER.
	CLRF	INDEX		; CLEAR THE BUFFER INDEX.
	CALL	READI2C		; DO A DUMMY READ OF THE SSPBUF.
	RETURN
	
STATE2:				; WRITE OPERATION, LAST BYTE WAS DATA,
	MOVLW	B'00101001'	; BUFFER IS FULL.
	XORWF	TEMP,W
	BTFSS	STATUS,Z	; ARE WE IN STATE2?
	GOTO	STATE3		; NO, CHECK FOR NEXT STATE.....
		
	LFSR	RXBUFFER,INDEX	; POINT TO THE BUFFER.
	CALL	READI2C		; GET THE BYTE FROM THE SSP.
	MOVWF	INDF		; PUT IT IN THE BUFFER.
	INCF	INDEX,F		; INCREMENT THE BUFFER POINTER.
	MOVF	INDEX,W		; GET THE CURRENT BUFFER INDEX.
	SUBLW	RX_BUF_LEN	; SUBTRACT THE BUFFER LENGTH.
	BTFSC	STATUS,Z	; HAS THE INDEX EXCEEDED THE BUFFER LENGTH?
	CLRF	INDEX		; YES, CLEAR THE BUFFER INDEX.
	RETURN
	
STATE3:				; READ OPERATION, LAST BYTE WAS AN
	MOVLW	B'00001100'	; ADDRESS, BUFFER IS EMPTY.
	XORWF	TEMP,W
	BTFSS	STATUS,Z	; ARE WE IN STATE3?
	GOTO	STATE4		; NO, CHECK FOR NEXT STATE.....
	
	CLRF	INDEX		; CLEAR THE BUFFER INDEX.
	LFSR	RXBUFFER,INDEX	; POINT TO THE BUFFER
	MOVF	INDF,W		; GET THE BYTE FROM BUFFER.
	CALL	WRITEI2C	; WRITE THE BYTE TO SSPBUF
	INCF	INDEX,F		; INCREMENT THE BUFFER INDEX.
	RETURN
	
STATE4:				; READ OPERATION, LAST BYTE WAS DATA,
	MOVLW	B'00101100'	; BUFFER IS EMPTY.
	XORWF	TEMP,W
	BTFSS	STATUS,Z	; ARE WE IN STATE4?
	GOTO	STATE5		; NO, CHECK FOR NEXT STATE....
	
	MOVF	INDEX,W		; GET THE CURRENT BUFFER INDEX.
	SUBLW	RX_BUF_LEN	; SUBTRACT THE BUFFER LENGTH.
	BTFSC	STATUS,Z	; HAS THE INDEX EXCEEDED THE BUFFER LENGTH?
	CLRF	INDEX		; YES, CLEAR THE BUFFER INDEX.
	LFSR	RXBUFFER,INDEX	; POINT TO THE BUFFER
	MOVF	INDF,W		; GET THE BYTE
	CALL	WRITEI2C	; WRITE TO SSPBUF
	INCF	INDEX,F		; INCREMENT THE BUFFER INDEX.
	RETURN

STATE5:
	MOVLW	B'00101000'	; A NACK WAS RECEIVED WHEN TRANSMITTING
	XORWF	TEMP,W		; DATA BACK FROM THE MASTER.  SLAVE LOGIC
	BTFSS	STATUS,Z	; IS RESET IN THIS CASE.  R_W = 0, D_A = 1
	GOTO	I2CERR		; AND BF = 0
	RETURN			; IF WE AREN? IN STATE5, THEN SOMETHING IS 
				; WRONG.

I2CERR	NOP
	BANKSEL	PORTB		; SOMETHING WENT WRONG!  SET LED
	BSF	PORTB,7		; AND LOOP FOREVER.  WDT WILL RESET
	GOTO	$		; DEVICE, IF ENABLED.
	RETURN

   return
;---------------------------------
;---------------------------------------------------------------------
; WRITEI2C
;---------------------------------------------------------------------

WRITEI2C
	BANKSEL	SSPSTAT
	BTFSC	SSPSTAT,BF	; IS THE BUFFER FULL?
	GOTO	WRITEI2C	; YES, KEEP WAITING.
	BANKSEL	SSPCON		; NO, CONTINUE.
DOI2CWRITE
	BCF	SSPCON,WCOL	; CLEAR THE WCOL FLAG.
	MOVWF	SSPBUF	; WRITE THE BYTE IN WREG
	BTFSC	SSPCON,WCOL	; WAS THERE A WRITE COLLISION?
	GOTO	DOI2CWRITE
	BSF	SSPCON,CKP	; RELEASE THE CLOCK.
	RETURN

;---------------------------------------------------------------------
READI2C
;---------------------------------------------------------------------
	
	BANKSEL	SSPBUF
	MOVF	SSPBUF,W	; GET THE BYTE AND PUT IN WREG
	RETURN



   END                                    ;源程序结束

⌨️ 快捷键说明

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