;************************************************************************ ;* * ;* Device: PIC16F684 FILE: Interupt2-2 Date: 07.02.10 * ;* * ;* Activation of RA3 (SW1) Generates Interupt and turns on Led DS2 * ;* Ux greater than Ref_2 Resets DS2 and turns on Led DS1 * ;* * ;* GC * ;************************************************************************ ; H'' D'' B'' A'' ; Registers and constants are defined here: INDF equ H'00' ; Indirect Register (Uses content of FSR) PCL equ H'02' ; Program Counter Low byte address STATUS equ H'03' ; Status-register FSR equ H'04' ; Indirect Data Memory Address Pointer PORTA equ H'05' ; Input/output-register A TRISA equ H'05' ; Bank-1, input/output configuration A PORTC equ H'07' ; Input/output-register C TRISC equ H'07' ; Bank-1, input/output configuration C INTCON equ H'0B' ; Interupt Control register (Enable-bits/Flags) <<<<== Interupt IOCA equ H'16' ; Bank-1 (96h): Interupt On Change on Port A CMCON0 equ H'19' ; Comparator control register ANSEL equ H'11' ; Bank-1, Analog select register (A/D conversion Clock) ADRESH equ H'1E' ; A/D result ADRESL equ H'1E' ; Bank-1, A/D result ADCON0 equ H'1F' ; A/D Control register ADCON1 equ H'1F' ; Bank-1, A/D Control register ; RAM-registers used by routines: Ux equ H'20' ; Ux? (A/D Converter) Ref_1 equ H'21' ; Low_? Ref_2 equ H'22' ; High_? Dly_1 equ H'23' ; Delay1 Dly_2 equ H'24' ; Delay2 W_tmp equ H'25' ; W-register content is stored here Status_tmp equ H'26' ; STATUS-register content is stored here ; Definitions: #define Out_1 PORTC,0 ; DS1 #define Out_2 PORTC,1 ; DS2 list p=16F684 org H'00' ; Start of code goto Init ; Reset Vector (0x0000) nop ; nop ; nop ; goto Isr ; ISR Vector (0x0004) ;********************* Chip setup ************************* Init ; Start of chip setup ;Bank_1 bsf STATUS,5 ; Switch to Bank-1 bsf IOCA,3 ; Enable Interupt from SW1 on PICkit1 <<<<== Interupt movlw B'11001111' ; RA0 is ADC-input movwf TRISA ; RA5 and RA4 are digital outputs ; RA3, RA2 and RA1 are digital inputs (Tristate) clrf TRISC ; PORTC= Outputs (TRISC<5:0>= 000000) ; Bit5=RS, Bit4=Strobe, Bit<3:0>=Data (Nibble) movlw B'00000001' ; RA0: ADC-Input, All other pins = digital I/O movwf ANSEL ; movlw B'00010000' ; Bit<6:4> A/D Clock=Fosc/8 movwf ADCON1 ;Bank_0 bcf STATUS,5 ; Switch back to Bank-0 ;Coparators off movlw H'07' ; CM<2:0>=111 <= !!! IMPORTANT !!! movwf CMCON0 ; Disable comparators General purpos I/O ;ADC setup movlw B'00000000' ; Bit7=0: 0-------, Makes A/D Result Left justified (8 Bits used) ; Bit6=0: -0------, Vref for A/D =VDD movwf ADCON0 ; Bit<4:2> ---000--, Channel 0 selected: RA0/AN0= ADC-input ; Bit1: ------1-, A/D start and Busy test bit ; Bit0=1: -------1, Turns on A/D Converter ;References movlw D'85' ; Ref_1 : Low limit movwf Ref_1 ; (85/255: ca.33%) movlw D'170' ; Ref_2 : High limit movwf Ref_2 ; (170/255: ca.66%) ;Interupt control setup <<<<== Interupt bcf INTCON,0 ; Clear Interupt-flag for SW1 (Caused by pull-up resistor) bsf INTCON,3 ; Enable Interupt (RAIF) from SW1 on RA3 PORTA bsf INTCON,7 ; Enable global interupt-bit GIE ; Initial setting of ports clrf PORTA ; PORTA Outputs are cleared (LED's off) clrf PORTC ; PORTC Outputs are cleared goto Start ;******************* Subroutines ********************* ; Short delays used by: Ux?, Strobe, Dis_txt, Delay2 Delay1 movwf Dly_1 ; Store W in Dly_1 lp_d decfsz Dly_1,f ; goto lp_d ; return ; Long delays used by: Various Display-routines Delay2 movwf Dly_2 ; Store W in Dly_2 movlw H'00' lp_d2 call Delay1 ; decfsz Dly_2,f goto lp_d2 return ; Reads A/D Converter value Ux? bsf ADCON0,0 ; Turn on A/D Converter movlw D'4' ; W contains delay-value for Dly_1 (23h) call Delay1 ; Delay bsf ADCON0,1 ; GO, Start A/D conversion loop1 btfsc ADCON0,1 ; Done ? (Bit1: A/D Start and Busy test-bit) goto loop1 ; No, try again movf ADRESH,w ; Yes, movwf Ux ; store result in Ux bcf ADCON0,0 ; Turn off A/D Converter return ; Go back to Main program ; Checks if Ux exceeds Ref_2 value High_? movf Ref_2,w ; Get Ref_2 to W subwf Ux,w ; Subtract Ref2 from Ux btfss STATUS,0 ; Ux > Ref_2 ? (C-bit=1) return ; No, Go back to Main program clrf PORTC bsf Out_1 ; Yes, Switch on Led DS1 return ; Go back to Main program ;******************* Interupt-routine(s) ********************* Isr bcf INTCON,7 ; Disable further interupts ! Push movwf W_tmp ; Save W-content swapf STATUS,w ; Swap STATUS to be savwed into W clrf STATUS ; Bank 0, regardless of current bank, clears IRP, RP1, RP0 movwf Status_tmp ; Save STATUS in Status_temp register Isr_A movf PORTA,f ; Read PORTA for reference on next change clrf PORTC ; Turn off DS1. <<== Interupt caused by SW1 bsf Out_2 ; Turn on DS2 movlw H'FF' ; Test-Delay (Enables to see blink on DS2) call Delay2 bcf INTCON,0 ; Reset Interupt-flag for SW1 Pop swapf Status_tmp,w ; Swap Status_temp register into W ; (sets bank to original state) movwf STATUS ; Restore STATUS register content. swapf W_tmp,f ; swapf W_tmp,w ; Restore W-register content retfie ; GIE=1, ready for new interupts ;********************* Main program ********************* Start New call Ux? ; Read ADC! call High_? ; Ux > Ref_2 => Reset, Led DS1 = ON goto New ; New mesurement end ; Program ends here ;*********************************** Programming a Device ******************************* ; Select: ; ; 1.Configure Select Device... 16f684 ; 2.Configure Configuration Bits Clock: Internal-RC,- ; No Clock ; ; WatchDogTimer: Off ; Master Clear Enable: Internal ; Internal External Switch Over Mode: Disabled ; Monitor Clock Fail-safe: Disabled ; ; 3.Project Quickbuild *.asm ; 4.Programmer Select Programmer (PICkit 2) ; 5.Programmer Program Device (Or Yellow Icon)