Step 9 of 11
Full ISR: toggle LED and reload Timer0
Goal
Complete the ISR: reload TMR0H/L, toggle LED on RB0, and see blinking in Proteus.
Between saving and restoring context:
1. Pause timer (BCF T0CON, TMR0ON)
2. Clear TMR0IF and reload TMR0H/L with same values from step 4
3. Restart timer (BSF T0CON, TMR0ON)
4. Toggle LED with BTFSC LATB,0 / BSF or BCF
Main loop stays at GOTO bucle — shows no polling needed.
Follow these steps
- Complete
isr_altawith the final file below (or add toggle + reload to step 7 skeleton). - Build, generate
.HEX, load in Proteus (LED on RB0, 20 MHz). - Press Play and wait ~2 s: LED must toggle on/off.
- If no blink: check GIE, TMR0IE, vector 0x0008, and TMR0IF cleared.
Your file so far
LIST P=18F4550
#include <P18F4550.INC>
CONFIG FOSC = HS
CONFIG WDT = OFF
CONFIG LVP = OFF
CONFIG PBADEN = OFF
ORG 0x0000
GOTO inicio
ORG 0x0008 ; alta prioridad (08H)
GOTO isr_alta
ORG 0x0018 ; baja prioridad (18H)
GOTO isr_baja
CBLOCK 0x20
temp_w
temp_status
ENDC
init_gpio:
BCF TRISB, 0 ; RB0 salida (LED)
BCF LATB, 0
RETURN
init_timer0:
MOVLW B'00000111' ; 16 bit, interno, PS 1:256
MOVWF T0CON
MOVLW B'01100111'
MOVWF TMR0H
MOVLW B'01101010'
MOVWF TMR0L
RETURN
isr_alta:
BTFSS INTCON, TMR0IF
GOTO fin_isr
; guardar contexto minimo
MOVWF temp_w
SWAPF STATUS, W
MOVWF temp_status
BCF T0CON, TMR0ON
BCF INTCON, TMR0IF
MOVLW B'01100111' ; recarga Timer0 (~2 s)
MOVWF TMR0H
MOVLW B'01101010'
MOVWF TMR0L
BSF T0CON, TMR0ON
; toggle LED en RB0
BTFSC LATB, 0
GOTO apagar_led
BSF LATB, 0
GOTO restaurar
apagar_led:
BCF LATB, 0
restaurar:
SWAPF temp_status, W
MOVWF STATUS
MOVF temp_w, W
fin_isr:
RETFIE
isr_baja:
RETFIE
inicio:
CALL init_gpio
CALL init_timer0
BCF INTCON, TMR0IF
BSF INTCON, TMR0IE
BSF INTCON, GIE
BSF T0CON, TMR0ON
bucle:
GOTO bucle
END
Try it
Optional: change TMR0H/L for faster blink and calculate the new time with the [Timer 0](/en/timers/timer0/) formula.
Checklist before you continue
- ISR reloads Timer0 and toggles the LED.
- **I saw the LED blink** in Proteus or hardware (~2 s per change).
- Main loop does not read TMR0IF — confirms interrupt, not polling.