Edit: PIC 16F684
Okay, I have a simple 3 LED binary clock that counts from 0-7, and want to add a delay of approx 1 second between each light turning on.
I’ve worked out that each light needs to be in a sort of loop, and I have to use a count to measure ticks, and rollover etc.
I think the clock is 4MHz, here’s a screenshot of the manual: https://i.stack.imgur.com/3A3sJ.png
Here’s the relevant extracts from my code:
COUNT1 EQU 20h ; Delay counter #1
COUNT2 EQU 21h ; Delay counter #2
…
LOOP0
MOVLW TRIS_D0_D1 ; Move value defined in Constants to TRISA, to switch on LED 0.
TRIS PORTA ;
CLRF PORTA ; Clear all outputs.
MOVLW D0 ; Set the accumulator to the value of D0.
MOVWF PORTA ; Move the accumulator to PORTA, to switch on LED 0.
; Using COUNTs to add a delay
decfsz COUNT1,1 ; Decrease COUNT1 by 1, and skip the next line if the result is 0.
goto LOOP0 ; If COUNT1 is 0, carry on. If not, go to LOOP0.
decfsz COUNT2,1 ; Decrease COUNT2 by 1, and skip the next line if the result is 0.
goto LOOP0 ; If COUNT1 is 0, carry on. If not, go to LOOP0.
However, I’m fairly sure I’m screwing up on the timing, could someone give me a hand?
Assumption: The code at
LOOP0is code you want to execute once per delay rather than as many times as possible during the delay. I also assume that you’re settingCOUNT1andCOUNT2to something – the code you posted declares two “variables” but doesn’t assign them.The code you have at the moment will repeatedly execute the code at
LOOP0COUNT1+COUNT2times. This is because each loop is separate. This gives you a maximum delay of 510 cycles. As other commenters have said, PIC16s execute roughly one instruction per cycle, so you need to delay 1,000,000 cycles to wait one second at 4MHz.If we consider a situation where we want to wait
196392cycles, we essentially need to implement a 16 bit counter. We do this by decrementing one counter in a loop. Each time that loop exits, we decrement another counter. When both counters are zero the loop returns. Here’s an example:Branch instructions cost 1 cycle if they don’t skip, and 2 if they do.
gotoalways takes 2 cycles, meaning the actual time taken to do one full count is 767 cycles (255 * 3 + 2). We can calculate the time taken for both as ((255 * 3 + 2) + 3) * 255 + 2.There’s an excellent explanation of delay routines over at Dos4Ever. This looks at how delay routines work and how to calculate the counter values and cost of a delay routine.
Finally, if you just want cut-and-paste delay routines, the Delay routine generator on PIClist is pretty much perfect.