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.

Timing is Everything

Status
Not open for further replies.

trennonix

New Member
Hello again,

I'm having some trouble writing timing code for the 12F675
I was trying to get an exact one sec delay to be then used for minutes and hours delays
I'm basically making a timer.
For one minute, my program gave me 50 sec, 10 sec short
So i used a code generator from the web, same thing, thus i'm assuming that my code is clean.
Off the WEB

DELAY_ONE_SECOND
;999990 cycles
MOVLW b'00000010'
XORWF GPIO, 1
movlw 0x07
movwf COUNTER1
movlw 0x2F
movwf COUNTER2
movlw 0x03
movwf COUNTER3
DELAY_ONE_SECOND_0
decfsz COUNTER1, f
goto $+2
decfsz COUNTER2, f
goto $+2
decfsz COUNTER3, f
goto DELAY_ONE_SECOND_0

;6 cycles
goto $+1
goto $+1

;4 cycles (including call)
return


My code

DELAY_ONE_SECOND1:
MOVLW b'00000010'
XORWF GPIO, 1
MOVLW D'100'
MOVWF COUNTER3
LABEL3
MOVLW D'13'
MOVWF COUNTER1
LABEL1
MOVLW D'255'
MOVWF COUNTER2
LABEL2
DECFSZ COUNTER2, 1
GOTO LABEL2
DECFSZ COUNTER1, 1
GOTO LABEL1
DECFSZ COUNTER3, 1
GOTO LABEL3
RETURN
However, i've set the micro to use the internal oscillator, and i read somewhere that this needs to be calibrated (no idea whatsoever about that OSCAL??? :confused:); could this be my problem? and how do i solve it?

Thanks

btw how do i get the code to have a clean look on the web, all TABS are gone when i posted this so might be a bit annoying to read, Sorry
 
Last edited:
adding extra hardware wouldn't be my first choice,
and the whole point of this timer is to acquire better programming skills
thanks anyways
 
Last edited:
Just a couple of notes:
1. is the 1% accuracy good enough? (It will also drift with temperature)
2. learn to use interrupts, inline delays and code will get padded by your own code.
 
Just a couple of notes:
1. is the 1% accuracy good enough? (It will also drift with temperature)
2. learn to use interrupts, inline delays and code will get padded by your own code.


1% is good enough

i looked at the tutorial you posted earlier
when i added:
call 0x3FF
movwf OSCCAL
the whole thing just stopped working (i didn't run it in a sim, i simply burnt it on the chip)

for now code timing is sufficient since there isn't any code involved, it's just a simple timer


And Bryan, right now i don't have that crystal at home, and less parts is better, i could've put an external 4Mhz XT (which i already have) and it 'should' work just fine;
but this is more of an educational project
 
Last edited:
Did you add the bank switches?
Code:
bsf STATUS, RP0                 ; Bank 1
 call 0x3ff                 ; Get the cal value 
 movwf OSCCAL                 ; Calibrate
 bcf STATUS, RP0                 ; Bank 0
 
Last edited:
Did you add the bank switches?
Code:
bsf STATUS, RP0                 ; Bank 1
 call 0x3ff                 ; Get the cal value 
 movwf OSCCAL                 ; Calibrate
 bcf STATUS, RP0                 ; Bank 0


yes i did
i don't think this matters but i put
bsf STATUS, RP0
call 0x3ff
movwf OSCCAL
......some code (trisio and such)
bcf STATUS, RP0

would "some code" cause any problems??

EDIT:

In the simulator, it ended right after calling 0x3FF
the next instruction was ADD 0xFF
 
Last edited:
Well the DELAY_ONE_SECOND routine takes exactly one million cycles to run.

It probably comes down to your oscillator accuracy. What oscillator are you using.

The 12F675 has two timers, Timer0 and Timer1. You can set either of them to overflow at a known time.

You can use the overflow to interrupt the processor. The interrupt service routine adds to the timer registers.

Alternatively, you can have code the regularly checks the overflow flag.

Either way, a 4 MHz oscillator, isn't brilliant for a 12F675 and a 1 minute timer.
With a 4 MHz oscillator, it executes 1 million cycles per second. You can use either timer to overflow every 256 cycles, and when you have counted 234375 overflows, that is 1 minute.

If you use a slightly different frequency oscillator, you can set the timer to divide by a bigger number, and then you have to count fewer overflows.

A 13.1072 MHz crystal will give a cycle frequency of 3.2768 MHz. If one of the timers is set to divide by 65536, then that overflows 50 times a second, so you have to count 3000 of those to get to minute.

Other PICs have a timers that can be made to overflow at times that are not powers of 2, so can be more useful with 4 MHz oscillators.
 
Code:
COUNTER1    EQU 20H
COUNTER2    EQU 21H
COUNTER3    EQU 22H
COUNTER4    EQU 23H
COUNTER5    EQU 24H
COUNTER6    EQU 25H
COUNTER7    EQU 26H

    list	p=12F675
	#include "p12f675.inc"
    __CONFIG  _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _CPD_OFF

    BSF     STATUS, RP0
    CALL    0x3FF
    MOVWF   OSCCAL
    CLRF    TRISIO
    MOVLW   0x07
    MOVWF   CMCON
    CLRF    ANSEL
    BCF     STATUS, RP0
    CLRF    GPIO 
    MOVLW   0x07
    MOVWF   CMCON
    CLRF    ANSEL
    
    CALL    DELAY_ONE_MINUTE
    BSF     GPIO,   0
    BSF     GPIO,   1
endlessloop
    GOTO    endlessloop        
      
         
FRIDGE_CYCLE
    
    GOTO    FRIDGE_CYCLE
    
    
DELAY_ONE_SECOND
			;999990 cycles
	MOVLW   b'00000010'
    XORWF   GPIO,   1
	movlw	0x07
	movwf	COUNTER1
	movlw	0x2F
	movwf	COUNTER2
	movlw	0x03
	movwf	COUNTER3
DELAY_ONE_SECOND_0
	decfsz	COUNTER1, f
	goto	$+2
	decfsz	COUNTER2, f
	goto	$+2
	decfsz	COUNTER3, f
	goto	DELAY_ONE_SECOND_0

			;6 cycles
	goto	$+1
	goto	$+1

			;4 cycles (including call)
	return


DELAY_ONE_SECOND1:
    MOVLW   b'00000010'
    XORWF   GPIO,   1
    MOVLW   D'100'
    MOVWF   COUNTER3
LABEL3
    MOVLW   D'13'
    MOVWF   COUNTER1
LABEL1
    MOVLW   D'255'
    MOVWF   COUNTER2
LABEL2
    DECFSZ  COUNTER2,   1
    GOTO    LABEL2
    DECFSZ  COUNTER1,   1
    GOTO    LABEL1
    DECFSZ  COUNTER3,   1
    GOTO    LABEL3
    RETURN
    
DELAY_ONE_MINUTE:
    MOVLW   D'60'
    MOVWF   COUNTER4
LABEL4
    CALL    DELAY_ONE_SECOND
    DECFSZ  COUNTER4,   1
    GOTO    LABEL4
    RETURN
    
DELAY_ONE_HOUR:
    MOVLW   D'60'
    MOVWF   COUNTER5
LABEL5
    CALL    DELAY_ONE_MINUTE
    DECFSZ  COUNTER5,   1
    GOTO    LABEL5
    RETURN
    
DELAY_SIX_HOURS:
    MOVLW   D'6'
    MOVWF   COUNTER6
LABEL6
    CALL    DELAY_ONE_HOUR
    DECFSZ  COUNTER6,   1
    GOTO    LABEL6
    RETURN
    
DELAY_TWENTYFIVE_MINUTES:
    MOVLW   D'25'
    MOVWF   COUNTER7
LABEL7
    CALL    DELAY_ONE_MINUTE
    DECFSZ  COUNTER7,   1
    GOTO    LABEL7
    RETURN
    
    END
 
Your programmer may have erased the OSCCON value at 0x3FF. Read the programmed PIC into memory and check there is something there.

You only need to disable the comparator module once. It's in BANK0
 
Last edited:
i don't know what and where OSCCON is ----> 0x3FF in memory is set to zero
but i got OSCCAL and it says: Invalid value 0000
(i'm using the PicKit 2)
 
Last edited:
the value is now 3424 and the program is running, i just have chrono it and check the timing
maybe tomorrow... now i need to get some sleep
Thanks alot for your time and expertise :)


just tried it, timing was great, thanks again
 
Last edited:
still using 12F675,
Now the programmer won't calibrate, it says: Regeneration failed! Calibration out of range

what's the deal?
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top