PIC16F877 Ext. Interrupt & ADC
R. Theagarajan. ME., MSc., PhD Rtd. Professor in Engineering email: rtheagarajan@yahoo.com rtrajan59@gmail.com
External Interrupt
• • • • •
Option_Reg INTCON Register TRISB TRISC Incremented output in PortC
Option_Reg register - 81h, 181h D7
D6
D5
D4
D3
D2
D1
D0
RBPU
INTEDG
T0CS
T0SE
PSA
PS2
PS1
PS0
Bit value 000 001 010 011 100 101 110 111
= = = = = = = =
TMR0 rate 1:2 1:4 1:8 1 : 16 1 : 32 1 : 64 1 : 128 1 : 256
Option_Reg register - 81h, 181h D7
D6
D5
D4
D3
D2
D1
D0
RBPU
INTEDG
T0CS
T0SE
PSA
PS2
PS1
PS0
Bit value 000 001 010 011 100 101 110 111
Pre-scaler assignment 0 = Timer0 1 = WDT
= = = = = = = =
TMR0 rate 1:2 1:4 1:8 1 : 16 1 : 32 1 : 64 1 : 128 1 : 256
Option_Reg register - 81h, 181h D7
D6
D5
D4
D3
D2
D1
D0
RBPU
INTEDG
T0CS
T0SE
PSA
PS2
PS1
PS0
Bit value 000 001 010 011 100 101 110 111
TMR0 source 0 = internal clock 1 = on RA4
Pre-scaler assignment 0 = Timer0 1 = WDT
TMR0 source edge 0 = Low to high 1 = High to low
= = = = = = = =
TMR0 rate 1:2 1:4 1:8 1 : 16 1 : 32 1 : 64 1 : 128 1 : 256
Option_Reg register - 81h, 181h D7
D6
D5
D4
D3
D2
D1
D0
RBPU
INTEDG
T0CS
T0SE
PSA
PS2
PS1
PS0
Bit value 000 001 010 011 100 101 110 111
Interrupt Edge 0 = Falling 1 = Rising TMR0 source 0 = internal clock 1 = on RA4
Pre-scaler assignment 0 = Timer0 1 = WDT
TMR0 source edge 0 = Low to high 1 = High to low
= = = = = = = =
TMR0 rate 1:2 1:4 1:8 1 : 16 1 : 32 1 : 64 1 : 128 1 : 256
Option_Reg register - 81h, 181h D7
D6
D5
D4
D3
D2
D1
D0
RBPU
INTEDG
T0CS
T0SE
PSA
PS2
PS1
PS0
Bit value 000 001 010 011 100 101 110 111
Port-B pull-up 0 = Enable 1 = Disable
Interrupt Edge 0 = Falling 1 = Rising TMR0 source 0 = internal clock 1 = on RA4
Pre-scaler assignment 0 = Timer0 1 = WDT
TMR0 source edge 0 = Low to high 1 = High to low
= = = = = = = =
TMR0 rate 1:2 1:4 1:8 1 : 16 1 : 32 1 : 64 1 : 128 1 : 256
INTCON register - 0Bh, 8Bh, 10Bh, 18Bh D7
D6
GIE
PEIE
D5 TMR0IE
D4
D3
D2
D1
INTE
RBIE
TMR0IF
INTF
D0 RBIF
Port change Int. Flag RB7:RB4 pins 1 = pins changed 0 = no pins changed RB port change interrupt enable bit 1 = Enables 0 = Disables
INTCON register - 0Bh, 8Bh, 10Bh, 18Bh D7
D6
GIE
PEIE
D5 TMR0IE
D4
D3
D2
D1
INTE
RBIE
TMR0IF
INTF
D0 RBIF
Port change Int. Flag RB7:RB4 pins 1 = pins changed 0 = no pins changed RB port change interrupt enable bit 1 = Enables 0 = Disables Ext. Interrupt 1 = Enables 0 = Disables
External Int. Flag 1 = Int. occurred 0 = did not occur
INTCON register - 0Bh, 8Bh, 10Bh, 18Bh D7
D6
D5
GIE
PEIE
TMR0IE
D4
D3
D2
D1
INTE
RBIE
TMR0IF
INTF
D0 RBIF
Timer0 Int. Flag 1 = Overflow 0 = did not overflow
Port change Int. Flag RB7:RB4 pins 1 = pins changed 0 = no pins changed TMR0 Int. Enable 1 = Enables 0 = Disables
RB port change interrupt enable bit 1 = Enables 0 = Disables
Ext. Interrupt 1 = Enables 0 = Disables
External Int. Flag 1 = Int. occurred 0 = did not occur
INTCON register - 0Bh, 8Bh, 10Bh, 18Bh D7
D6
D5
GIE
PEIE
TMR0IE
D4
D3
D2
D1
INTE
RBIE
TMR0IF
INTF
D0 RBIF
Timer0 Int. Flag 1 = Overflow 0 = did not overflow
Peripheral Int. Enable 1 = Enables 0 = Disables
Port change Int. Flag RB7:RB4 pins 1 = pins changed 0 = no pins changed
TMR0 Int. Enable 1 = Enables 0 = Disables
RB port change interrupt enable bit 1 = Enables 0 = Disables
Ext. Interrupt 1 = Enables 0 = Disables
External Int. Flag 1 = Int. occurred 0 = did not occur
INTCON register - 0Bh, 8Bh, 10Bh, 18Bh D7
D6
D5
GIE
PEIE
TMR0IE
D4
D3
D2
D1
INTE
RBIE
TMR0IF
INTF
Global Int. Enable 1 = Enable 0 = Disable
D0 RBIF
Timer0 Int. Flag 1 = Overflow 0 = did not overflow
Peripheral Int. Enable 1 = Enables 0 = Disables
Port change Int. Flag RB7:RB4 pins 1 = pins changed 0 = no pins changed
TMR0 Int. Enable 1 = Enables 0 = Disables
RB port change interrupt enable bit 1 = Enables 0 = Disables
Ext. Interrupt 1 = Enables 0 = Disables
External Int. Flag 1 = Int. occurred 0 = did not occur
; External interrupt at RB0, PortC is incremented for every interrupt : INCLUDE “P16F877A.INC� org 0000h goto Main org 0004 goto int_sr org 0050h
Main:
; goto label Main
; External interrupt at RB0, PortC is incremented for every interrupt : INCLUDE “P16F877A.INC” org 0000h goto Main
; goto label Main
org 0004 goto int_sr org 0050h
Main:
banksel TRISC
; select the bank1 where TRISC is available
clrf
; PortC is configured as output
TRISC
movlw
B’11111111’
movwf
OPTION_REG
: make weak pull-up for portB
; External interrupt at RB0, PortC is incremented for every interrupt : INCLUDE “P16F877A.INC” org 0000h goto Main
; goto label Main
org 0004 goto int_sr org 0050h
Main:
banksel TRISC
; select the bank1 where TRISC is available
clrf
; PortC is configured as output
TRISC
movlw
B’11111111’
movwf
OPTION_REG
movlw
B’00000001’
: make weak pull-up for portB
; make RB0 as input
movwf TRISB
;
clrf TRISC
; portC is defined as output
; External interrupt at RB0, PortC is incremented for every interrupt : INCLUDE “P16F877A.INC” org 0000h goto Main
; goto label Main
org 0004 goto int_sr org 0050h
Main:
banksel TRISC
; select the bank1 where TRISC is available
clrf
; PortC is configured as output
TRISC
movlw
B’11111111’
movwf
OPTION_REG
movlw
B’00000001’
: make weak pull-up for portB
; make RB0 as input
movwf TRISB
;
clrf TRISC
; portC is defined as output
banksel PORTC
; select the bank0 where PortC is available
clrf
; PortC is initialised with 00
PORTC
; External interrupt at RB0, PortC is incremented for every interrupt : INCLUDE “P16F877A.INC” org 0000h goto Main
; goto label Main
org 0004 goto int_sr org 0050h
Main:
repeat:
banksel TRISC
; select the bank1 where TRISC is available
clrf
; PortC is configured as output
TRISC
movlw
B’11111111’
movwf
OPTION_REG
movlw
B’00000001’
: make weak pull-up for portB
; make RB0 as input
movwf TRISB
;
clrf TRISC
; portC is defined as output
banksel PORTC
; select the bank0 where PortC is available
clrf
; PortC is initialised with 00
PORTC
movlw B’10010000’
; set GIE and INTE to enable the interrupt
movwf INTCON
;
goto repeat
; stop execution / Halt
; External interrupt at RB0, PortC is incremented for every interrupt : INCLUDE “P16F877A.INC” org 0000h goto Main
; goto label Main
org 0004 goto int_sr org 0050h
Main:
banksel TRISC
; select the bank1 where TRISC is available
clrf
; PortC is configured as output
TRISC
movlw
B’11111111’
movwf
OPTION_REG
movlw
B’00000001’
: make weak pull-up for portB
; make RB0 as input
movwf TRISB
;
clrf TRISC
; portC defined as output
banksel PORTC
; select the bank0 where PortC is available
clrf
; PortC is initialised with 00
PORTC
movlw B’10010000’
; set GIE and INTE to enable the interrupt
movwf INTCON
;
repeat:
goto repeat
; stop execution / Halt
Int_sr:
bcf
; clear external int. flag
INTCON, INTF
incf PORTC
; increment PortC
retfie
; return from this int. routine
end
; assembler directives
Analog to Digital Converter • • • • • •
ADCON0 register ADCON1 register Option_Register PIR1 register Timer0 with pre-scaler Result in PortD
steps to be followed for A/D conversion • • • • •
• • • • •
Configure analog pins / digital I/O in ADCON1 Select analog input channel in ADCON0 Select A/D conversion clock ADCON0 Turn-on AD module in ADCON0 Configure A/D interrupt pins if required Clear ADIF bit, Set ADIE bit Set PEIE bit, Set GIE bit Wait for the required acquisition time Set Go bit in ADCON0 Wait for AD conversion time Read AD result from ADRESH:ADRESL Repeat the steps for next conversion
ADC block diagram
Option_Reg register - 81h, 181h D7
D6
D5
D4
D3
D2
D1
D0
RBPU
INTEDG
T0CS
T0SE
PSA
PS2
PS1
PS0
Bit value 000 001 010 011 100 101 110 111
= = = = = = = =
TMR0 rate 1:2 1:4 1:8 1 : 16 1 : 32 1 : 64 1 : 128 1 : 256
Option_Reg register - 81h, 181h D7
D6
D5
D4
D3
D2
D1
D0
RBPU
INTEDG
T0CS
T0SE
PSA
PS2
PS1
PS0
Bit value 000 001 010 011 100 101 110 111
Pre-scaler assignment 0 = Timer0 1 = WDT
= = = = = = = =
TMR0 rate 1:2 1:4 1:8 1 : 16 1 : 32 1 : 64 1 : 128 1 : 256
Option_Reg register - 81h, 181h D7
D6
D5
D4
D3
D2
D1
D0
RBPU
INTEDG
T0CS
T0SE
PSA
PS2
PS1
PS0
Bit value 000 001 010 011 100 101 110 111
TMR0 source 0 = internal clock 1 = on RA4
Pre-scaler assignment 0 = Timer0 1 = WDT
TMR0 source edge 0 = Low to high 1 = High to low
= = = = = = = =
TMR0 rate 1:2 1:4 1:8 1 : 16 1 : 32 1 : 64 1 : 128 1 : 256
Option_Reg register - 81h, 181h D7
D6
D5
D4
D3
D2
D1
D0
RBPU
INTEDG
T0CS
T0SE
PSA
PS2
PS1
PS0
Bit value 000 001 010 011 100 101 110 111
Interrupt Edge 0 = Falling 1 = Rising TMR0 source 0 = internal clock 1 = on RA4
Pre-scaler assignment 0 = Timer0 1 = WDT
TMR0 source edge 0 = Low to high 1 = High to low
= = = = = = = =
TMR0 rate 1:2 1:4 1:8 1 : 16 1 : 32 1 : 64 1 : 128 1 : 256
Option_Reg register - 81h, 181h D7
D6
D5
D4
D3
D2
D1
D0
RBPU
INTEDG
T0CS
T0SE
PSA
PS2
PS1
PS0
Bit value 000 001 010 011 100 101 110 111
Port-B pull-up 0 = Enable 1 = Disable
Interrupt Edge 0 = Falling 1 = Rising TMR0 source 0 = internal clock 1 = on RA4
Pre-scaler assignment 0 = Timer0 1 = WDT
TMR0 source edge 0 = Low to high 1 = High to low
= = = = = = = =
TMR0 rate 1:2 1:4 1:8 1 : 16 1 : 32 1 : 64 1 : 128 1 : 256
A/D port configuration control bits
ADCON1 register - 9Fh D7
D6
ADFM
ADCS2
D5
D4
D3
D2
PCFG3
PCFG2
D1
D0
PCFG1
PCFG0
Port configuration bits 0 0 0 0 = all are analog channels 0 0 1 0 = AN0 to AN4 analog channels 1 0 0 1 = AN0 to AN5 analog channels
ADCON1 register - 9Fh D7
D6
ADFM
ADCS2
D5
Conversion clock select bit With ADCON0
D4
D3
D2
PCFG3
PCFG2
D1
D0
PCFG1
PCFG0
Port configuration bits 0 0 0 0 = all are analog channels 0 0 1 0 = AN0 to AN4 analog channels 1 0 0 1 = AN0 to AN5 analog channels
ADCON1 register - 9Fh D7
D6
ADFM
ADCS2
D5
Conversion clock select bit With ADCON0
ADC result format 0 = Left justified 1 = Right justified
D4
D3
D2
PCFG3
PCFG2
D1
D0
PCFG1
PCFG0
Port configuration bits 0 0 0 0 = all are analog channels 0 0 1 0 = AN0 to AN4 analog channels 1 0 0 1 = AN0 to AN5 analog channels
ADCON0 register - 1Fh D7 ADCS1
D6
D5
D4
D3
ADCS0
CHS2
CHS1
CHS0
Analog Channel Select bits
D2 GO
D1
D0 ADON
ADCON0 register - 1Fh D7 ADCS1
D6
D5
D4
D3
ADCS0
CHS2
CHS1
CHS0
Analog Channel Select bits
S2 0 0 0 0 1 1 1 1
S1 0 0 1 1 0 0 1 1
S0 0 = 1 = 0 = 1 = 0 = 1 = 0 = 1 =
Fosc / 2 Fosc / 8 Fosc / 32 Clock from internal Osc Fosc / 4 Fosc / 16 Fosc / 64 Clock from internal Osc
D2 GO
D1
D0 ADON
ADCON0 register - 1Fh D7 ADCS1
D6
D5
D4
D3
ADCS0
CHS2
CHS1
CHS0
Analog Channel Select bits
S2 0 0 0 0 1 1 1 1
S1 0 0 1 1 0 0 1 1
S0 0 = 1 = 0 = 1 = 0 = 1 = 0 = 1 =
Fosc / 2 Fosc / 8 Fosc / 32 Clock from internal Osc Fosc / 4 Fosc / 16 Fosc / 64 Clock from internal Osc
D2 GO
D1
D0 ADON
1 = AD module powered ON 0 = AD module is shut Off
ADCON0 register - 1Fh D7 ADCS1
D6
D5
D4
D3
ADCS0
CHS2
CHS1
CHS0
Analog Channel Select bits
S2 0 0 0 0 1 1 1 1
S1 0 0 1 1 0 0 1 1
S0 0 = 1 = 0 = 1 = 0 = 1 = 0 = 1 =
Fosc / 2 Fosc / 8 Fosc / 32 Clock from internal Osc Fosc / 4 Fosc / 16 Fosc / 64 Clock from internal Osc
D2
D1
GO
D0 ADON
1 = AD module powered ON 0 = AD module is shut Off
Setting this bit starts convertion, automatically cleared by hardware when convertion is over
; adc using channel-2 in RA2, display higher 8 bits in Port-D INCLUDE “P16F877A.INC” org 0000h banksel TRISD clrf
TRISD
; Port-D defined as output
movlw B’10000111’
;
movwf OPTION_REG
; Prescaler 1:256 for Timer0
; adc using channel-2 in RA2, display higher 8 bits in Port-D INCLUDE “P16F877A.INC” org 0000h banksel TRISD clrf
TRISD
; Port-D defined as output
movlw B’10000111’
;
movwf OPTION_REG
; Prescaler 1:256 for Timer0
movlw B’00000010’ movwf ADCON1
; Left justify, channel-2 as analog
; adc using channel-2 in RA2, display higher 8 bits in Port-D INCLUDE “P16F877A.INC” org 0000h banksel TRISD clrf
TRISD
; Port-D defined as output
movlw B’10000111’
;
movwf OPTION_REG
; Prescaler 1:256 for Timer0
movlw B’00000010’ movwf ADCON1
; Left justify, channel-2 as analog
banksel PORTD clrf
PORTD
; Port-D initialised with 00
movlw 0x91 movwf ADCON0
; ADC channel-2 is enabled
; adc using channel-2 in RA2, display higher 8 bits in Port-D INCLUDE “P16F877A.INC” org 0000h banksel TRISD clrf
TRISD
; Port-D defined as output
movlw B’10000111’
;
movwf OPTION_REG
; Prescaler 1:256 for Timer0
movlw B’00000010’ movwf ADCON1
; Left justify, channel-2 as analog
banksel PORTD clrf
PORTD
; Port-D initialised with 00
movlw 0x91 movwf ADCON0
; ADC channel-2 is enabled
Main:
bcf INCTON, T0IF
Loop1:
btfss INTCON, T0IF
; Check for the timer0 int. flag
goto Loop1
; If time is not over, goto Loop1
; adc using channel-2 in RA2, display higher 8 bits in Port-D INCLUDE “P16F877A.INC” org 0000h banksel TRISD clrf
TRISD
; Port-D defined as output
movlw B’10000111’
;
movwf OPTION_REG
; Prescaler 1:256 for Timer0
movlw B’00000010’ movwf ADCON1
; Left justify, channel-2 as analog
banksel PORTD clrf
PORTD
; Port-D initialised with 00
movlw 0x91 movwf ADCON0
; ADC channel-2 is enabled
Main:
bcf INCTON, T0IF
Loop1:
btfss INTCON, T0IF
; Check for the timer0 int. flag
goto Loop1
; If time is not over, goto Loop1
bsf
; Start a2d convertion
Wait:
ADCON0, GO
btfss PIR1, ADIF
; wait for adc convertion to complete
goto wait
; Goto wait
; adc using channel-2 in RA2, display higher 8 bits in Port-D INCLUDE “P16F877A.INC” org 0000h banksel TRISD clrf
TRISD
; Port-D defined as output
movlw B’10000111’
;
movwf OPTION_REG
; Prescaler 1:256 for Timer0
movlw B’00000010’ movwf ADCON1
; Left justify, channel-2 as analog
banksel PORTD clrf
PORTD
; Port-D initialised with 00
movlw 0x91 movwf ADCON0
; ADC channel-2 is enabled
Main:
bcf INCTON, T0IF
Loop1:
btfss INTCON, T0IF
; Check for the timer0 int. flag
goto Loop1
; If time is not over, goto Loop1
bsf
; Start a2d convertion
Wait:
ADCON0, GO
btfss PIR1, ADIF
; wait for adc convertion to complete
goto wait
; Goto wait
movf ADRESH, W
;
; adc using channel-2 in RA2, display higher 8 bits in Port-D INCLUDE “P16F877A.INC” org 0000h banksel TRISD clrf
TRISD
; Port-D defined as output
movlw B’10000111’
;
movwf OPTION_REG
; Prescaler 1:256 for Timer0
movlw B’00000010’ movwf ADCON1
; Left justify, channel-2 as analog
banksel PORTD clrf
PORTD
; Port-D initialised with 00
movlw 0x91 movwf ADCON0
; ADC channel-2 is enabled
Main:
bcf INCTON, T0IF
Loop1:
btfss INTCON, T0IF
; Check for the timer0 int. flag
goto Loop1
; If time is not over, goto Loop1
bsf
; Start a2d convertion
Wait:
ADCON0, GO
btfss PIR1, ADIF
; wait for adc convertion to complete
goto wait
; Goto wait
movf ADRESH, W
;
movwf PORTD
; transfer the result into Port-D
; adc using channel-2 in RA2, display higher 8 bits in Port-D INCLUDE “P16F877A.INC” org 0000h banksel TRISD clrf
TRISD
; Port-D defined as output
movlw B’10000111’
;
movwf OPTION_REG
; Prescaler 1:256 for Timer0
movlw B’00000010’ movwf ADCON1
; Left justify, channel-2 as analog
banksel PORTD clrf
PORTD
; Port-D initialised with 00
movlw 0x91 movwf ADCON0
; ADC channel-2 is enabled
Main:
bcf INCTON, T0IF
Loop1:
btfss INTCON, T0IF
; Check for the timer0 int. flag
goto Loop1
; If time is not over, goto Loop1
bsf
; Start a2d convertion
Wait:
ADCON0, GO
btfss PIR1, ADIF
; wait for adc convertion to complete
goto wait
; Goto wait
movf ADRESH, W
;
movwf PORTD
; transfer the result into Port-D
bcf PIR1, ADIF
; clear the ad int. flag
goto Main
;
end
Avoid Plastics Plant a Tree Let us take care of our earth for future generation