📄 ad.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 + -