How to use TIMR0 in PIC16F84A using assembly language PLZ I need help

Thread Starter

andrew132

Joined Feb 2, 2017
96
hello everyone i need help how to use timer0 in pic using assembly language if i need to make 2 sec delay how to make it when using internal clock 4Mhz

Moderators note : changed title from all capitals to regular text, all capitals are like shouting
 
Last edited by a moderator:

Thread Starter

andrew132

Joined Feb 2, 2017
96
can anyone write a program using assmebly to make the led on pin A0 flash every 2sec using pic16f84
 
Last edited:

MaxHeadRoom

Joined Jul 18, 2013
28,681
Pick the bones out of this one!
Max.
Code:
;******************************************************************************
; ZERO-ERROR ONE SECOND TIMER
; (Roman Black 2001, public domain, use it as you like)
;
; INTERRUPT VERSION
;
; for PIC 16F84 at 4 MHz (or most PICs)
; (this code has been assembled with MPLAB and hardware tested)
; (for best viewing set TABS=5 in MPLAB editor)
;
; Note! See text: www.RomanBlack.com/one_sec.htm
;
; Generates an event every second (or other period) from any PIC
; with any clock frequency.
;
; This version uses the timer0 overflow interrupt.
; Code can be adapted for different clock speeds, period lengths
; and accuracy levels.
;
;******************************************************************************


;==============================================================================
; processor defined ;
   include <p16f84.inc>

;==============================================================================
; MPLAB stuff here

   LIST b=5, n=97, t=ON, st=OFF
   ; absolute listing tabs=5, lines=97, trim long lines=ON, symbol table=OFF

   __CONFIG  _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
   ; config for 16F84; code protect OFF, watchdog OFF, powerup timer ON,
   ; oscillator is XT ready for 4 MHz crystal or resonator.

;==============================================================================
; Variables here

   CBLOCK 0x20       ; start of ram in 16F84

     bres_hi       ; hi byte of our 24bit variable
     bres_mid       ; mid byte
     bres_lo       ; lo byte
             ; (we only need 3 bytes for this system)

     status_temp     ; used for interrupt servicing
     w_temp       ; used for interrupt servicing

   ENDC


;==============================================================================
; Code here

   org 0x000        ; Set program memory base at reset vector 0x000
reset
   goto setup       ; set up ints and port stuff

   org 0x004         ; Interrupt vector, int handler code comes next.
;==============================================================================


;******************************************************************************
;  INTERRUPT HANDLER  (runs this code each timer0 interrupt)
;******************************************************************************
;
;------------------
int_handler         ;
;------------------

   ;-------------------------------------------------
             ; first we preserve w and status register

   movwf w_temp       ; save off current W register contents
   movf   STATUS,w     ; move status register into W register
   movwf status_temp     ; save off contents of STATUS register

   ;-------------------------------------------------
   ; Note! we get here every 256 instructions, we
   ; can now do our special one second timing system.     

   ; This consists of three main steps;
   ; * subtract 256 counts from our 24bit variable
   ; * test if we reached the setpoint
   ; * if so, add 1,000,000 counts to 24bit variable and generate event.
   ;-------------------------------------------------
             ; * optimised 24 bit subtract here
             ; This is done with the minimum instructions.
             ; We subtract 256 from the 24bit variable
             ; by just decrementing the mid byte.

   tstf bres_mid       ; first test for mid==0
   skpnz         ; nz = no underflow needed
   decf bres_hi,f       ; z, so is underflow, so dec the msb

   decfsz bres_mid,f     ; dec the mid byte (subtract 256)

             ; now the full 24bit optimised subtract is done!
             ; this is about 4 times faster than a "proper"
             ; 24bit subtract.

   goto int_exit       ; nz, so definitely not one second yet.
             ; in most cases the entire int takes
             ; only 16 instructions.
   ;------------------------
             ; * test if we have reached one second.
             ; only gets here when mid==0, it MAY be one second.
             ; only gets to here 1 in every 256 times.
             ; (this is our best optimised test)
             ; it gets here when bres_mid ==0.

   tstf bres_hi       ; test hi for zero too
   skpz           ; z = both hi and mid are zero, is one second!
   goto int_exit       ; nz, so not one second yet.

   ;-------------------------------------------------
   ; Only gets to here if we have reached one second.

   ; now we can generate our one second event, like add
   ; one second to our clock or whatever.
   ; (in this example we toggle a led)

   ; The other thing we need to do is add 1,000,000 counts
   ; to our 24bit variable and start all over again.
   ;-------------------------------------------------
             ; Add the 1,000,000 counts first.
             ; One second = 1,000,000 = 0F 42 40 (in hex)

             ; As we know hi==0 and mid==0 this makes it very fast.
             ; This is an optimised 24bit add, because we can
             ; just load the top two bytes and only need to do
             ; a real add on the bottom byte. This is much quicker
             ; than a "proper" 24bit add.

   movlw 0x0F       ; get msb value
   movwf bres_hi       ; load in msb

   movlw 0x42       ; get mid value
   movwf bres_mid       ; load in mid

   movlw 0x40       ; lsb value to add
   addwf bres_lo,f     ; add it to the remainder already in lsb
   skpnc         ; nc = no overflow, so mid is still ok

   incf bres_mid,f     ; c, so lsb overflowed, so inc mid
             ; this is optimised and relies on mid being known
             ; and that mid won't overflow from one inc.

             ; that's it! Our optimised 24bit add is done,
             ; this is roughly twice as quick as a "proper"
             ; 24bit add.
   ;-------------------------
             ; now we do the "event" that we do every one second.

             ; Note! for this example we toggle a led, which
             ; will give a flashing led which is on for a second
             ; and off for a second.
             ; Add your own code here for your one second event.

             ; Note! My led is on porta,3
             ; your led may be on a different pin.
   movlw b'00001000'     ; mask for bit 3
   xorwf PORTA,f       ; toggle PORTA,bit3 (toggle the led)
         
   ;-------------------------------------------------
   ; now our one second event is all done, we can exit the
   ; interrupt handler.
   ;-------------------------------------------------
             ; finally we restore w and status registers.
             ; also clears TMRO int flag now we are finished.
int_exit
   BCF INTCON,T0IF     ; reset the tmr0 interrupt flag

   movf status_temp,w     ; retrieve copy of STATUS register
   movwf STATUS     ; restore pre-isr STATUS register contents
   swapf w_temp,f
   swapf w_temp,w     ; restore pre-isr W register contents
   retfie         ; return from interrupt
;------------------------------------------------------------------------------



;******************************************************************************
;  SETUP  (runs this only once at startup)
;******************************************************************************
;
;------------------
setup           ; goto label
;------------------

   ;-------------------------------------------------
   ; Note! 16F84 version.
   ; Note! here we set up peripherals and port directions.
   ; this will need to be changed for different PICs.
   ;-------------------------------------------------
             ; OPTION setup
   movlw b'10001000'     ;
     ;  x-------     ; 7, 0=enable, 1=disable, portb pullups
     ;  -x------     ; 6, 1=/, int edge select bit
     ;  --x-----     ; 5, timer0 source, 0=internal clock, 1=ext pin.
     ;  ---x----     ; 4, timer0 ext edge, 1=\
     ;  ----x---     ; 3, prescaler assign, 1=wdt, 0=timer0
     ;  -----x--     ; 2,1,0, timer0 prescaler rate select
     ;  ------x-     ;  000=2, 001=4, 010=8, 011=16, etc.
     ;  -------x     ;
             ; Note! We set the prescaler to the wdt, so timer0
             ; has NO prescaler and will overflow every 256
             ; instructions and make an interrupt.
             ;
   banksel OPTION_REG     ; go proper reg bank
   movwf OPTION_REG     ; load data into OPTION_REG
   banksel 0         ; back to normal bank 0
   ;-------------------------------------------------
             ; PORTB pins direction setup
             ; 1=input, 0=output
   clrf PORTB       ;
             ;
   movlw b'00000000'     ; all 8 portb are outputs
             ;
   banksel TRISB       ; go proper reg bank
   movwf TRISB       ; send mask to portb
   banksel 0         ; back to normal reg bank
   ;-------------------------------------------------
             ; PORTA pins direction setup
             ; 1=input, 0=output
   clrf PORTA       ;
             ;
   movlw b'00000000'     ; all 5 porta are outputs,
             ; (with 16F84 porta only has lower 5 bits)
             ;
   banksel TRISB       ; go proper reg bank
   movwf TRISA       ; send mask to porta
   banksel 0         ; back to normal reg bank
   ;-------------------------------------------------
             ; INTCON setup
             ;
             ; for this code example, we enable the timer0
             ; overflow interrupt.
             ;
             ; enable interrupts last
             ; interrupt setup
   movlw b'10100000'     ; GIE=on TOIE=on (timer0 overflow int)
   movwf INTCON       ; set up.

   ;-------------------------------------------------
   ; Note! Now the hardware is set up we need to load the
   ; first count for one second into our 24bit bres variable.
   ;-------------------------------------------------
             ; Note! This example uses 4 MHz clock, which is
             ; 1,000,000 counts per second.
             ;
             ; We require a 1 second period, so we must load
             ; 1,000,000 counts each time.
             ; 1,000,000 = 0F 42 40 (in hex)
             ;
             ; We also need to add 256 counts for the first time,
             ; so we just add 1 to the mid byte.
             ; Check mid overflow if needed.

             ; here we load the 24bit variable.
   movlw 0x0F       ; get msb value
   movwf bres_hi       ; put in hi

   movlw 0x42 +1       ; get mid value (note we added 1 to it)
   movwf bres_mid       ; put in mid

   movlw 0x40       ; get lsb value
   movwf bres_lo       ; put in mid

             ; now setup is complete, we can start execution.
   ;-------------------------------------------------
   goto main         ; start main program

;------------------------------------------------------------------------------



;******************************************************************************
;  MAIN  (main program loop)
;******************************************************************************
;
;------------------
main             ; goto label
;------------------

   ;-------------------------------------------------
   ; Note! This example uses the timer0 overflow interrupt.
   ; This will interrupt our main program every 256 instructions
   ; and do the one second timer system.
   ;-------------------------------------------------
main_loop           ;
             ; Note! here you have your main program code,
             ; or calls to the main program pieces.
             ; The interrupt does all the one second timer stuff.
   ; stuff
   ; stuff
   ; stuff
   ; stuff

   ;-------------------------------------------------
   goto main_loop       ; keep running the main code.

;------------------------------------------------------------------------------


;==============================================================================
   end           ; no code after this point.
;================
[/CODE=ASM]
 

Thread Starter

andrew132

Joined Feb 2, 2017
96
Pick the bones out of this one!
Max.
Code:
;******************************************************************************
; ZERO-ERROR ONE SECOND TIMER
; (Roman Black 2001, public domain, use it as you like)
;
; INTERRUPT VERSION
;
; for PIC 16F84 at 4 MHz (or most PICs)
; (this code has been assembled with MPLAB and hardware tested)
; (for best viewing set TABS=5 in MPLAB editor)
;
; Note! See text: www.RomanBlack.com/one_sec.htm
;
; Generates an event every second (or other period) from any PIC
; with any clock frequency.
;
; This version uses the timer0 overflow interrupt.
; Code can be adapted for different clock speeds, period lengths
; and accuracy levels.
;
;******************************************************************************


;==============================================================================
; processor defined ;
   include <p16f84.inc>

;==============================================================================
; MPLAB stuff here

   LIST b=5, n=97, t=ON, st=OFF
   ; absolute listing tabs=5, lines=97, trim long lines=ON, symbol table=OFF

   __CONFIG  _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
   ; config for 16F84; code protect OFF, watchdog OFF, powerup timer ON,
   ; oscillator is XT ready for 4 MHz crystal or resonator.

;==============================================================================
; Variables here

   CBLOCK 0x20       ; start of ram in 16F84

     bres_hi       ; hi byte of our 24bit variable
     bres_mid       ; mid byte
     bres_lo       ; lo byte
             ; (we only need 3 bytes for this system)

     status_temp     ; used for interrupt servicing
     w_temp       ; used for interrupt servicing

   ENDC


;==============================================================================
; Code here

   org 0x000        ; Set program memory base at reset vector 0x000
reset
   goto setup       ; set up ints and port stuff

   org 0x004         ; Interrupt vector, int handler code comes next.
;==============================================================================


;******************************************************************************
;  INTERRUPT HANDLER  (runs this code each timer0 interrupt)
;******************************************************************************
;
;------------------
int_handler         ;
;------------------

   ;-------------------------------------------------
             ; first we preserve w and status register

   movwf w_temp       ; save off current W register contents
   movf   STATUS,w     ; move status register into W register
   movwf status_temp     ; save off contents of STATUS register

   ;-------------------------------------------------
   ; Note! we get here every 256 instructions, we
   ; can now do our special one second timing system.    

   ; This consists of three main steps;
   ; * subtract 256 counts from our 24bit variable
   ; * test if we reached the setpoint
   ; * if so, add 1,000,000 counts to 24bit variable and generate event.
   ;-------------------------------------------------
             ; * optimised 24 bit subtract here
             ; This is done with the minimum instructions.
             ; We subtract 256 from the 24bit variable
             ; by just decrementing the mid byte.

   tstf bres_mid       ; first test for mid==0
   skpnz         ; nz = no underflow needed
   decf bres_hi,f       ; z, so is underflow, so dec the msb

   decfsz bres_mid,f     ; dec the mid byte (subtract 256)

             ; now the full 24bit optimised subtract is done!
             ; this is about 4 times faster than a "proper"
             ; 24bit subtract.

   goto int_exit       ; nz, so definitely not one second yet.
             ; in most cases the entire int takes
             ; only 16 instructions.
   ;------------------------
             ; * test if we have reached one second.
             ; only gets here when mid==0, it MAY be one second.
             ; only gets to here 1 in every 256 times.
             ; (this is our best optimised test)
             ; it gets here when bres_mid ==0.

   tstf bres_hi       ; test hi for zero too
   skpz           ; z = both hi and mid are zero, is one second!
   goto int_exit       ; nz, so not one second yet.

   ;-------------------------------------------------
   ; Only gets to here if we have reached one second.

   ; now we can generate our one second event, like add
   ; one second to our clock or whatever.
   ; (in this example we toggle a led)

   ; The other thing we need to do is add 1,000,000 counts
   ; to our 24bit variable and start all over again.
   ;-------------------------------------------------
             ; Add the 1,000,000 counts first.
             ; One second = 1,000,000 = 0F 42 40 (in hex)

             ; As we know hi==0 and mid==0 this makes it very fast.
             ; This is an optimised 24bit add, because we can
             ; just load the top two bytes and only need to do
             ; a real add on the bottom byte. This is much quicker
             ; than a "proper" 24bit add.

   movlw 0x0F       ; get msb value
   movwf bres_hi       ; load in msb

   movlw 0x42       ; get mid value
   movwf bres_mid       ; load in mid

   movlw 0x40       ; lsb value to add
   addwf bres_lo,f     ; add it to the remainder already in lsb
   skpnc         ; nc = no overflow, so mid is still ok

   incf bres_mid,f     ; c, so lsb overflowed, so inc mid
             ; this is optimised and relies on mid being known
             ; and that mid won't overflow from one inc.

             ; that's it! Our optimised 24bit add is done,
             ; this is roughly twice as quick as a "proper"
             ; 24bit add.
   ;-------------------------
             ; now we do the "event" that we do every one second.

             ; Note! for this example we toggle a led, which
             ; will give a flashing led which is on for a second
             ; and off for a second.
             ; Add your own code here for your one second event.

             ; Note! My led is on porta,3
             ; your led may be on a different pin.
   movlw b'00001000'     ; mask for bit 3
   xorwf PORTA,f       ; toggle PORTA,bit3 (toggle the led)
        
   ;-------------------------------------------------
   ; now our one second event is all done, we can exit the
   ; interrupt handler.
   ;-------------------------------------------------
             ; finally we restore w and status registers.
             ; also clears TMRO int flag now we are finished.
int_exit
   BCF INTCON,T0IF     ; reset the tmr0 interrupt flag

   movf status_temp,w     ; retrieve copy of STATUS register
   movwf STATUS     ; restore pre-isr STATUS register contents
   swapf w_temp,f
   swapf w_temp,w     ; restore pre-isr W register contents
   retfie         ; return from interrupt
;------------------------------------------------------------------------------



;******************************************************************************
;  SETUP  (runs this only once at startup)
;******************************************************************************
;
;------------------
setup           ; goto label
;------------------

   ;-------------------------------------------------
   ; Note! 16F84 version.
   ; Note! here we set up peripherals and port directions.
   ; this will need to be changed for different PICs.
   ;-------------------------------------------------
             ; OPTION setup
   movlw b'10001000'     ;
     ;  x-------     ; 7, 0=enable, 1=disable, portb pullups
     ;  -x------     ; 6, 1=/, int edge select bit
     ;  --x-----     ; 5, timer0 source, 0=internal clock, 1=ext pin.
     ;  ---x----     ; 4, timer0 ext edge, 1=\
     ;  ----x---     ; 3, prescaler assign, 1=wdt, 0=timer0
     ;  -----x--     ; 2,1,0, timer0 prescaler rate select
     ;  ------x-     ;  000=2, 001=4, 010=8, 011=16, etc.
     ;  -------x     ;
             ; Note! We set the prescaler to the wdt, so timer0
             ; has NO prescaler and will overflow every 256
             ; instructions and make an interrupt.
             ;
   banksel OPTION_REG     ; go proper reg bank
   movwf OPTION_REG     ; load data into OPTION_REG
   banksel 0         ; back to normal bank 0
   ;-------------------------------------------------
             ; PORTB pins direction setup
             ; 1=input, 0=output
   clrf PORTB       ;
             ;
   movlw b'00000000'     ; all 8 portb are outputs
             ;
   banksel TRISB       ; go proper reg bank
   movwf TRISB       ; send mask to portb
   banksel 0         ; back to normal reg bank
   ;-------------------------------------------------
             ; PORTA pins direction setup
             ; 1=input, 0=output
   clrf PORTA       ;
             ;
   movlw b'00000000'     ; all 5 porta are outputs,
             ; (with 16F84 porta only has lower 5 bits)
             ;
   banksel TRISB       ; go proper reg bank
   movwf TRISA       ; send mask to porta
   banksel 0         ; back to normal reg bank
   ;-------------------------------------------------
             ; INTCON setup
             ;
             ; for this code example, we enable the timer0
             ; overflow interrupt.
             ;
             ; enable interrupts last
             ; interrupt setup
   movlw b'10100000'     ; GIE=on TOIE=on (timer0 overflow int)
   movwf INTCON       ; set up.

   ;-------------------------------------------------
   ; Note! Now the hardware is set up we need to load the
   ; first count for one second into our 24bit bres variable.
   ;-------------------------------------------------
             ; Note! This example uses 4 MHz clock, which is
             ; 1,000,000 counts per second.
             ;
             ; We require a 1 second period, so we must load
             ; 1,000,000 counts each time.
             ; 1,000,000 = 0F 42 40 (in hex)
             ;
             ; We also need to add 256 counts for the first time,
             ; so we just add 1 to the mid byte.
             ; Check mid overflow if needed.

             ; here we load the 24bit variable.
   movlw 0x0F       ; get msb value
   movwf bres_hi       ; put in hi

   movlw 0x42 +1       ; get mid value (note we added 1 to it)
   movwf bres_mid       ; put in mid

   movlw 0x40       ; get lsb value
   movwf bres_lo       ; put in mid

             ; now setup is complete, we can start execution.
   ;-------------------------------------------------
   goto main         ; start main program

;------------------------------------------------------------------------------



;******************************************************************************
;  MAIN  (main program loop)
;******************************************************************************
;
;------------------
main             ; goto label
;------------------

   ;-------------------------------------------------
   ; Note! This example uses the timer0 overflow interrupt.
   ; This will interrupt our main program every 256 instructions
   ; and do the one second timer system.
   ;-------------------------------------------------
main_loop           ;
             ; Note! here you have your main program code,
             ; or calls to the main program pieces.
             ; The interrupt does all the one second timer stuff.
   ; stuff
   ; stuff
   ; stuff
   ; stuff

   ;-------------------------------------------------
   goto main_loop       ; keep running the main code.

;------------------------------------------------------------------------------


;==============================================================================
   end           ; no code after this point.
;================
[/CODE=ASM]
im new to Pic can u be more simple plz
 

MaxHeadRoom

Joined Jul 18, 2013
28,681
im new to Pic can u be more simple plz
It depends on whether you want to just blink a LED or learn Assembly, using a supplied program will not gain any learned knowledge.
The sample PGM from Roman is highly commented which in itself is a teaching tool.
Go through the instructions one at a time and you will learn what he has done in what is essentially a very simple program!
Max.
 

Thread Starter

andrew132

Joined Feb 2, 2017
96
It depends on whether you want to just blink a LED or learn Assembly, using a supplied program will not gain any learned knowledge.
The sample PGM from Roman is highly commented which in itself is a teaching tool.
Go through the instructions one at a time and you will learn what he has done in what is essentially a very simple program!
Max.
i want to know how to make delay using timer0 i want to use it in subroutine
 

OBW0549

Joined Mar 2, 2015
3,566
Google the phrase, "how to use TMR0 on pic16f84a" and lots of good stuff comes up, including a number of tutorials on how to use the timer with assembly language.

I strongly suggest you read the PIC16F84A data sheet, especially Section 5 (pages 19 and 20) on the timer module.
 

Thread Starter

andrew132

Joined Feb 2, 2017
96
Code:
BSF STATUS,RP0
BCF OPTION_REG,T0CS
BSF OPTION_REG,3
CLRF TRISB
BCF STATUS,RP0
BSF     INTCON, TMR0IE
BSF     INTCON, GIE
CLRF TMR0

BSF PORTB,1
CALL L
BCF PORTB,1
L:
BCF PORTB,0
MOVF TMR0,W
XORLW 0X255
BTFSS STATUS,Z
GOTO L
RETURN
 
Last edited by a moderator:

OBW0549

Joined Mar 2, 2015
3,566
is that correct ?
I have no idea, and I'm not going to take the time to check it for you. That's your job, not mine.

Figure it out for yourself: step through the program on paper, or in your head, or in MPLAB's simulator and see if it does what you intended.
 

Thread Starter

andrew132

Joined Feb 2, 2017
96
I have no idea, and I'm not going to take the time to check it for you. That's your job, not mine.

Figure it out for yourself: step through the program on paper, or in your head, or in MPLAB's simulator and see if it does what you intended.
bro im new to pic and i dont have a teacher to help me so plz help me i have exam after 2 days
 

Thread Starter

andrew132

Joined Feb 2, 2017
96
I have no idea, and I'm not going to take the time to check it for you. That's your job, not mine.

Figure it out for yourself: step through the program on paper, or in your head, or in MPLAB's simulator and see if it does what you intended.
and i didnt use timer0 from before so i dont have any idea how to use it
 

Thread Starter

andrew132

Joined Feb 2, 2017
96
So we get you through the exam, whats next?
There is a general rule here not to answer exam papers, guidance only . Not really doing you any favours.;)
Max.
if you gived me the solution in timer0 i will not take your job or your career or anything else im just a student who want help
 
Top