• Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Creating a TMR0 delay for PIC16F84 for rotating sequence of 4 LED's

Not open for further replies.


New Member
Hi all, I am trying to create a very basic delay using a TMR0 (timer) function as part of a rotating sequence for 4 LED’s with the option to reverse direction. I know I’m almost there but I could do with a little guidance to be honest. I’m using PIC16F84 and datasheet can be downloaded from microchip website where full instruction set is on pg56 down. Full code is below with annotations:-

; U19A2T1-4.asm

; blinks LEDs on outputs in a rotating pattern, with input option to reverse direction

; Set microprocessor as 16F84


; Setup processor configuration


SETUP:ORG 0 ; The next instruction should go to address ‘0’ in the program memory (telling the assembler where to start)

BANKSEL TRISA ; Select register bank ‘TRISA’, which is the register that controls which pins in ‘PORTA’ are an input or an output

CLRF TRISA ; Clearing the ‘TRISA’ register sets all of ‘PORTA’ as outputs

BCF STATUS , RP0 ; Clearing the register bank select bit in the status register, and resets ‘RP0’ back to page ‘0’

BCF STATUS , RP1 ; Clearing the register bank select bit in the status register, and resets ‘RP1’ back to page ‘0’

MOVLW 0X01 ; Puts a literal binary value of ‘0001’ in to the working register

MOVWF PORTB ; Moves the binary value of ‘0001’ from the working register in to the ‘PORTB’ register

BCF STATUS,C ; Clear the carry flag or bit to prevent the arithmetic borrow or carry out of the most significant ALU bit position, i.e. rotating in a ’1’ value, and preventing unwanted bits from being introduced before a rotation

ROTATE:BTFSS PORTA,0 ; Bit test in file and execute next instruction if set at ‘0’, and skip next instruction if set at ‘1’

GOTO RR ; Jump or branch to a 'rotate right' file register

RLF PORTB,F ; Rotate data left stored in register ‘PORTB,F’ through the carry flag, in effect shifting all data one space to the left, and where the existing data in the carry flag will be shifted in to the right most bit. The ‘f’ stands for storing the answer back in ‘PORTB'

GOTO DELAY ; Go to the DELAY register address; repeat loop if delay is not ‘0’

RR:RRF PORTB,F ; This instruction is almost exactly the same as ‘RLF PORTB,F’ above, except that the data moves in the opposite way, i.e. the right most bit will shift in to the carry flag and then back in at the left most bit


BANKSEL OPTION_REG ; Select register bank ‘OPTION_REG’

MOVLW 0X07 ; Configure timer0 with a prescaler of ‘0000111’

MOVWF OPTION_REG ; Set maximum prescaler increment at 256


BANKSEL TMR0 ; Select register bank ‘TMR0’

CLRF TMR0 ; Clear the timer register

CHECK:BTFSS INTCON,T0IF ; Check timer flag and wait until TMR0 count rolls over. If '0' execute next instruction, if '1' then skip next instruction

GOTO CHECK ; Loop until T0IF flag is set

BCF INTCON,T0IF ; T0IF flag must be cleared ready for next count

DIRECTION:MOVLW 0X02 ; Move the hexadecimal code value (0X02) and binary equivalent in to the working file register

XORWF PORTA,0 ; Performs ‘XOR’ logic with contents of the working register and contents of the ‘PORTA’ file register address. Answers from both are put back in to the ‘PORTA’ register, toggle bit ‘0’. This overwrites the original data and possibly changes the LED direction

GOTO ROTATE ; Branch back to rotate program instructions as part of the main loop

END ; End of program

Ian Rogers

User Extraordinaire
Forum Supporter
Most Helpful Member
I did a timer tutorial on the pic... If you want a delay the maximum delay with timer 0 is 65535 * TOSC..

so a 4Mhz crystal will yield a 1us TOSC... so 65.535 mS delay maximum. To increase this use another byte to increment to 15 and the delay will be 0.98 Seconds..

a workable solution..

load w with 15
store in count
load timer with 0​
timer flag isn't set
goto while
decrease count
return if count = 0
load timer with 0
goto while
1 second ish… preloading the timer with different values will get more precision


Well-Known Member
Most Helpful Member
Ian, shouldn't the second "load timer with zero" be "clear timer flag"?

Not open for further replies.

Latest threads

EE World Online Articles