Adding a 1 second delay on a 20 MHz(?) clock
assembly, pic
Solution
Assumption: The code at `LOOP0` is code you want to execute once per delay rather than as many times as possible during the delay. I also assume that you're setting `COUNT1` and `COUNT2` to 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 `LOOP0` `COUNT1` + `COUNT2` times. 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 `196392` cycles, 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:
COUNT1 EQU 20h
COUNT2 EQU 21h
LOOP0
;do some stuff here
...
;delay loop starts here:
;assume COUNT1=0 and COUNT2=0
Delay_0
decfsz COUNT1
goto Delay_0
decfsz COUNT2 ;COUNT1 = 0 so 0xff cycles have passed
goto Delay_0
goto LOOP0 ;both COUNT1 and COUNT2 = 0 - 196392 cycles have now passed
Branch instructions cost 1 cycle if they don't skip, and 2 if they do. `goto` always 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.
Problem
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?