long variable time delay with 8bit PIC

Thread Starter

blackmamba

Joined Dec 4, 2009
16
Thanks you all for your help.

Is it possible to create a function that allows me to do variable time delay of up to 8333us using just an 8bit PIC (12f683)?

I need that much precision and I am not sure how to go about doing this. I am programming in C. Assembly implementations would also work since I can use asm.... to indicate assembly code to compiler.

I hope it isnt too obvious:). I cant quite figure it out.
 
Last edited:

retched

Joined Dec 5, 2009
5,207
you can do a "if then loop" of NOPs. What kind of clock are you running? Crystal or onboard? and what is the speed?

You can figure the number of instructions per second then the number of instructions for your delay. I believe there is also a command: sleep(.08333) that will help. (depending on your compiler) you may need stdio.h
 

Tahmid

Joined Jul 2, 2008
343
Hi,
Yup you can do it, using assembly, like the code Sgt Wookie provided.
You can also use the TMR1 module as it can count upto 65536 us. Load TMR1 with 57203 and wait for it to overflow from 0xFFFF to 0.
You can also use TMR0 by using prescaler. If you have prescaler of 32, TMR0 will count upto 0xFF (255) from 0 and overflow to 0 every 8192 microseconds.
Or, if you set prescaler to 64, and load 124 to TMR0, it will count from 124 to 256 and overflow to 0 every 8384 microseconds. After overflow you need to reload TMR0.
Or simply use an assembly language delay routine:
Rich (BB code):
; Delay 8 333 machine cycles
; Duration of the delay 8333 microsecond
; Frequency of the pulsing oscillator 4 MHZ

            movlw       .209
            movwf       Reg_1
            movlw       .11
            movwf       Reg_2
            decfsz      Reg_1,F
            goto        $-1
            decfsz      Reg_2,F
            goto        $-3
            nop
Code generated from software: PIC_Delay v1.7
 

Thread Starter

blackmamba

Joined Dec 4, 2009
16
Thank you all for the help. Really appreciate it.
However, what if the delay value is a variable determined by the program?
Basically what I am needing is a program that can delay in int multiples of a variable number.
So say :
Rich (BB code):
int time_us;  //time_us is generated by the program
           multiple=10;  //for total delay of (10*time_us)
How can I use your solutions which are pretty much similar to do this?
 
Last edited:

chat_eur

Joined Dec 30, 2009
7
[SIZE=-1]if assembly is ok for you, use something on below. Before calling delay1s routine, use
movlw x
instruction to multiply the overall delay with x. This will load x to the first counter. You can find this detailed on the bottom of this page : http://www.microautomate.com/PIC/pic-timing-delay-loops.php

delay1s:
MOVWF CNT1 ;Load counter with W
LOOP1 ;From above example we know that part will be 195,075us
[/SIZE][SIZE=-1].
.[/SIZE]
 

Thread Starter

blackmamba

Joined Dec 4, 2009
16
/@ chat. is your solution possible if I dont know what the int time_us is before program starts running?
 
Last edited:

Thread Starter

blackmamba

Joined Dec 4, 2009
16
I found this code which is supposed to delay for a variable d us. can someone tell me if it works for them or if the logic is right. I have tried compiling it in mickroC using the asm{} tags, and it wont work. Compiler is complaining about "_count2_delay_us not being found"

Rich (BB code):
/* delay for d microseconds on a 4Mhz clock
 */
void delay_us(char d) {
  char count;    
  char count2;

   count = d;

_dmsouter:
asm	movlw D'20'
asm	movwf _count2_delay_us

_dmsinner:
asm        NOP
asm        NOP
asm	decfsz _count2_delay_us, f
asm	goto $-3
asm	decfsz _count_delay_us,f
asm	goto $-7
}
 

THE_RB

Joined Feb 11, 2008
5,438
Your PIC 12F683 has a 16bit TMR1 and a hardware CCP (capture/compare) module.

Read the PIC datasheet for how to use TMR1 and the CCP, it will explain exactly how to load a value in TMR1 and generate a period from that.
 

chat_eur

Joined Dec 30, 2009
7
[SIZE=-1]
[/SIZE][SIZE=-1]
CNT1 EQU h'20' ;General register for delay
CNT2 EQU h'21' ;General register for delay
CNT3 EQU h'22' ;General register for delay

ORG 0x00 ;Start vector
GOTO main

main:
BSF STATUS,RP0 ;Switch BANK1
CLRF TRISB ;Set all pins of PORTB as output
BCF STATUS,RP0 ;Switch BANK0

MAIN_LOOP:
BSF PORTB,0 ;Turn on LED
MOVLW D'10' ;WAIT FOR 10 TIMES OF DELAY ROUTINE
CALL delay
BCF PORTB,0 ;Turn off LED
MOVLW D'150' ;WAIT FOR 150 TIMES OF DELAY ROUTINE
CALL delay ;Wait one second
GOTO MAIN_LOOP ;Repeat

;ACCUMULATOR (W) WILL BE MOVED TO FIRST COUNTER OF DELAY (CNT1) ROUTINE
;CONTENT OF THE ACCUMULATOR DOESN'T MATTER, DELAY WILL BE SIMPLY
;MULTIPLIED BY THIS VALUE
;------Delay Routine-------------
delay:
MOVWF CNT1
LOOP1:
MOVLW d'255'
MOVWF CNT2
LOOP2:
MOVLW d'255'
[/SIZE][SIZE=-1]MOVWF CNT3
LOOP3:
DECFSZ CNT3,F
GOTO LOOP3
DECFSZ CNT2,F
GOTO LOOP2
DECFSZ CNT1,F
GOTO LOOP1

RETURN

END[/SIZE]
 
Top