Continue to Site

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.

  • 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.

16F690, TMR0, Internal timer

Status
Not open for further replies.

ibwev

Member
I am trying to complete a project that lights an led on one second and then off for one second and on the fifth second lights a separate led. I am using a PIC16F690 and the code line "btfss STATUS,2" apparently never goes to 0 because the program never skips the next instruction. Please help.

list p=16F690 ; list directive to define processor
#include <p16F690.inc> ; processor specific variable definitions

errorlevel -302 ; suppress message 302 from list file

__CONFIG _CP_OFF & _CPD_OFF & _BOR_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _FCMEN_OFF & _IESO_OFF

;declarations

INT_VAR UDATA_SHR
Marker125 res 1
Post125 res 1
fivSEC res 1

RESET_VECTOR CODE 0x0000 ; processor reset vector
goto start ; go to beginning of program

INT_VECTOR CODE 0x0004 ; interrupt vector location

Init
;initialize PORTA example 4-1 in datasheet
BCF STATUS,RP1
CLRF PORTA
BSF STATUS,RP1
CLRF ANSEL
BSF STATUS,RP0
BCF STATUS,RP1
MOVLW 0Ch ;set RA<5:4,1:0>;as outputs
MOVWF TRISA
BCF STATUS,RP0

;8 Mhz internal timer oscillates 2,000,000 times a second
;2,000,000/256(prescaler)=15,625 cycles to 1 second after prescaler
;125(Marker)x125(Post)=15,625

movlw b'00000000' ;disable TMR0 interrupt
movwf INTCON

movlw b'00000110' ;internal instruction cycle,prescaler assigned to TMR0
movwf OPTION_REG ;Prescaler 1:128 for even numbers on "Mark125" and "Post125"

movlw d'125' ;move decimal 125 in GPF called Marker125
movwf Marker125

movlw d'125' ;move decimal 125 in GPF called Post125
movwf Post125

movlw d'5' ;move decimal 5 in GPF called fivSEC
movwf fivSEC

TimeLoop
movfw Marker125 ;move number from Marker125 into working register
subwf TMR0,0 ;As TMR0 counts up, the decimal in Marker125 will
;subtract and store the number in the w register
;this leaves the number in TMR0 unchanged
btfss STATUS,2 ;When the above number reaches 0 the next
;instructions will be skipped
goto TimeLoop ;loop until Marker125 - TMR0 = 0

movlw d'125' ;add 125 to Marker125 and store in Marker125
addwf Marker125,1

decfsz Post125,1 ;Decrement the postscaler and store in Post125
goto TimeLoop ;this line is skipped once Post125 = 0

;when the Timeloop reaches this point 1 second has passed

movlw d'125' ;add 125 to Post125 and store in Post125
movwf Post125

retlw 0


MAIN_PROG CODE

start
call Init

Main

decfsz fivSEC,1 ;decrements fivSEZ by 1 and stores contents in fivSEC
;register
goto toggle ; skips of 0
bsf PORTA,4 ;sets high bit 4 of PORTA once fivSEC reaches 0

movlw d'5' ;move number 5 into fivSEC register
movwf fivSEC

goto TimeLoop ;repeat timeloop

toggle
bcf PORTA,4 ;turn bit 4 off

movlw b'100000' ;toggles RA5 and stores contents in w register
xorwf PORTA,0

goto TimeLoop ;repeat timeloop

END ; directive 'end of program'
 
hi,
I have reformatted your listing, use the '#' on the menu when you post code, it keeps the formatting, makes easier for us to see and help.
Code:
    list    p=16F690    ; list directive to define processor
#include <p16F690.inc>         ; processor specific variable definitions

    errorlevel -302        ; suppress message 302 from list file

    __config _CP_OFF & _CPD_OFF & _BOR_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _FCMEN_OFF & _IESO_OFF

;declarations 

INT_VAR    udata_shr 
Marker125 res    1
Post125    res    1
fivSEC    res    1

RESET_VECTOR code 0x0000    ; processor reset vector
    goto    start        ; go to beginning of program

INT_VECTOR code    0x0004        ; interrupt vector location

Init
;initialize PORTA example 4-1 in datasheet  
    bcf    STATUS,RP1
    clrf    PORTA
    bsf    STATUS,RP1
    clrf    ANSEL
    bsf    STATUS,RP0
    bcf    STATUS,RP1
    movlw    0Ch        ;set RA<5:4,1:0>;as outputs
    movwf    TRISA
    bcf    STATUS,RP0

;8 Mhz internal timer oscillates 2,000,000 times a second  
;2,000,000/256(prescaler)=15,625 cycles to 1 second after prescaler  
;125(Marker)x125(Post)=15,625  

    movlw    b'00000000'    ;disable TMR0 interrupt
    movwf    INTCON

    movlw    b'00000110'    ;internal instruction cycle,prescaler assigned to TMR0
    movwf    OPTION_REG    ;Prescaler 1:128 for even numbers on "Mark125" and "Post125"

    movlw    d'125'        ;move decimal 125 in GPF called Marker125
    movwf    Marker125

    movlw    d'125'        ;move decimal 125 in GPF called Post125
    movwf    Post125

    movlw    d'5'        ;move decimal 5 in GPF called fivSEC
    movwf    fivSEC

TimeLoop 
    movfw    Marker125    ;move number from Marker125 into working register
    subwf    TMR0,0        ;As TMR0 counts up, the decimal in Marker125 will
;subtract and store the number in the w register  
;this leaves the number in TMR0 unchanged  
    btfss    STATUS,2    ;When the above number reaches 0 the next
;instructions will be skipped  
    goto    TimeLoop    ;loop until Marker125 - TMR0 = 0

    movlw    d'125'        ;add 125 to Marker125 and store in Marker125
    addwf    Marker125,1

    decfsz    Post125,1    ;Decrement the postscaler and store in Post125
    goto    TimeLoop    ;this line is skipped once Post125 = 0

;when the Timeloop reaches this point 1 second has passed  

    movlw    d'125'        ;add 125 to Post125 and store in Post125
    movwf    Post125

    retlw    0


MAIN_PROG code

start
    call    Init

Main

    decfsz    fivSEC,1    ;decrements fivSEZ by 1 and stores contents in fivSEC
;register 
    goto    toggle        ; skips of 0
    bsf    PORTA,4        ;sets high bit 4 of PORTA once fivSEC reaches 0

    movlw    d'5'        ;move number 5 into fivSEC register
    movwf    fivSEC

    goto    TimeLoop    ;repeat timeloop

toggle
    bcf    PORTA,4        ;turn bit 4 off

    movlw    b'100000'    ;toggles RA5 and stores contents in w register
    xorwf    PORTA,0

    goto    TimeLoop    ;repeat timeloop

    end            ; directive 'end of program'
 
I don't think you ever actually turned on Timer0.

I don't know why you aren't making this interrupt driven. IMO, what you are doing is fairly uncoventional.

Also, I never use MOVFW. I've seen it before, but I always use "MOVF FILENAME,W"
 
Try this build as absolute code
Code:
   #include <p16F690.inc>
     __config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF)

     cblock     0x20
Display
     endc

     org 0
     bsf       STATUS,RP0
     movlw     b'00000111'    ; configure Timer0.  Sourced from the Processor clock;
     movwf     OPTION_REG     ; Maximum Prescaler
     clrf      TRISC          ; Make PortC all output
     clrf      Display
     bcf       STATUS,RP0
     
ForeverLoop:
     btfss     INTCON,T0IF    ; wait here until Timer0 rolls over
     goto      ForeverLoop
     bcf       INTCON,T0IF    ; flag must be cleared in software
     incf      Display,f      ; increment display variable
     movf      Display,w      ; send to the LEDs
     movwf     PORTC
     goto      ForeverLoop
     
     
     end
 
Last edited:
I don't think you ever actually turned on Timer0.

I don't know why you aren't making this interrupt driven. IMO, what you are doing is fairly uncoventional.

Also, I never use MOVFW. I've seen it before, but I always use "MOVF FILENAME,W"

How do I turn on Timer0?
How do I make the code interrupt driven?
 
There you a little better code to play with
Code:
#include <p16F690.inc>
     __config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF)

     cblock     0x20
count
flags
     endc

     org 0
     banksel   OPTION_REG
     movlw     b'00000111'    ; configure Timer0.  Sourced from the Processor clock;
     movwf     OPTION_REG     ; Maximum Prescaler
     banksel   ANSEL
     clrf      ANSEL
     banksel   TRISC
     clrf      TRISC          ; Make PortC all output
     banksel   PORTC
     clrf      PORTC
     clrf      count
     clrf      flags
	
start
	movlw     D'250'    ;preload count higher faster toggle time
	movwf	   count    ;lower longer toggle time 
     
ForeverLoop: 
     btfss     INTCON,T0IF    ; wait here until Timer0 rolls over
     goto      ForeverLoop
     bcf       INTCON,T0IF    ; flag must be cleared in software
     incfsz    count      ; increment count variable
     goto      ForeverLoop 
	 call      toggle
	 goto      start
toggle:
	movlw 	   0x01  ;sets the port pin    
	xorwf      PORTC,f ; set the port
	return	
     
     end
 
Last edited:
Try this build as absolute code
Code:
   #include <p16F690.inc>
     __config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF)

     cblock     0x20
Display
     endc

     org 0
     bsf       STATUS,RP0
     movlw     b'00000111'    ; configure Timer0.  Sourced from the Processor clock;
     movwf     OPTION_REG     ; Maximum Prescaler
     clrf      TRISC          ; Make PortC all output
     clrf      Display
     bcf       STATUS,RP0
     
ForeverLoop:
     btfss     INTCON,T0IF    ; wait here until Timer0 rolls over
     goto      ForeverLoop
     bcf       INTCON,T0IF    ; flag must be cleared in software
     incf      Display,f      ; increment display variable
     movf      Display,w      ; send to the LEDs
     movwf     PORTC
     goto      ForeverLoop
     
     
     end

I am new at programming. What is the purpose of "bsf STATUS,RP0"? Does this direct the code to Bank 1 and allow access to OPTION_REG and TRISC?
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top