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.

timer circuit

Status
Not open for further replies.

alamy

New Member
Hi...

I build timer circuit (long time delay)...

i'm using PIC16F84A...that have 3 outputs represent the range of time delay...(short,med,long)..

short 5 minute, med 15 minutes, long 30 minutes...i found 4060 can provided this time delay...

the thing is how do i connect this two ic so that my switch, will switch at the right time delay...

or there any idea how to make the time delay circuit?..

:(
 
meaning that , i can have time delay up to 30 minutes just using PIC..how many loop should i put in my code?...


what is the maximum time delay....taht PIc can do?...

how do i implement these loops (long range time delay)...

thanks
 
alamy said:
meaning that , i can have time delay up to 30 minutes just using PIC..how many loop should i put in my code?...

You use nested loops for a simple delay, you could also use an internal timer to generate interrupts for a clock, but it's a little more complicated.

what is the maximum time delay....taht PIc can do?...

As long as you want - years?, centuries? - you simply use more registers!.

how do i implement these loops (long range time delay)...

Try looking at the PICList at which has a delay code generator. Using this generator gave this code for a 5 minute delay - you could simply add a RETURN at the end of it and call it as a subroutine.

Code:
; Delay = 300 seconds
; Clock frequency = 4 MHz

; Actual delay = 300 seconds = 300000000 cycles
; Error = 0 %

	cblock
	d1
	d2
	d3
	d4
	endc

			;299999995 cycles
	movlw	0x54
	movwf	d1
	movlw	0xA1
	movwf	d2
	movlw	0xFD
	movwf	d3
	movlw	0x02
	movwf	d4
Delay_0
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	$+2
	decfsz	d3, f
	goto	$+2
	decfsz	d4, f
	goto	Delay_0

			;5 cycles
	goto	$+1
	goto	$+1
	nop

Call it once for a 5 minute delay, three times for your 15 minute delay, and six times for your 30 minute delay. You could also use a minute delay, and call that 5, 15, or 30 times - but for your limited three delays, 5 minutes is probably the easiest.
 
thanks a lot Nigel...

ok...

for the time delay...can i use RETLW to call my subroutine?

which is

retlw 5minutes
retlw 15minutes
retlw 30minutes....
and so on...

actually i do develop lookup table which have 64 values (size)i.e. 6 bits inputs...

i want my PIC have a time delay for the given inputs (6 bits)...
instead of using retlw (if can)...is there any alternative way to put my pic working as using retlw...

thank you..
 
alamy said:
thanks a lot Nigel...

ok...

for the time delay...can i use RETLW to call my subroutine?

which is

retlw 5minutes
retlw 15minutes
retlw 30minutes....
and so on...

No, you use 'call'

call 5minutes
call 15 minutes
etc.

RETLW is used at the end of the subroutine to return from where it came, you can use either RETURN or RETLW (only RETLW on 12 bit cores), RETLW returns a value in the W register.

actually i do develop lookup table which have 64 values (size)i.e. 6 bits inputs...

i want my PIC have a time delay for the given inputs (6 bits)...
instead of using retlw (if can)...is there any alternative way to put my pic working as using retlw...

thank you..

With a table you can either have a table of RETLW, which returns a corresponding value (lookup table), or a table of GOTO, which is a jump table. You can't use a table of CALL, because it will RETURN to the section of the table it came from, and execute all subroutines below in the table.

For your purpose I would suggest a lookup table, use the returned value in a loop which calls a short delay the required number of times. If you look in my tutorials most of them have a looped delay routine like this, just not using a lookup table.
 
thanks nigel..

ok...

looks like i can't use the retlw to call my subroutine..

With a table you can either have a table of RETLW, which returns a corresponding value (lookup table), or a table of GOTO, which is a jump table. You can't use a table of CALL, because it will RETURN to the section of the table it came from, and execute all subroutines below in the table

for a give code below...can i just simply switch RETLW to the GOTO? that was original code, planned to use with external timer...

Code:
;***** VARIABLE DEFINITIONS 
STATUS      EQU     03h      ; variable used for context saving 
TRISA      EQU      85h        ; variable used for context saving 
PORTA      EQU      05H 
TRISB      EQU      86h 
PORTB      EQU      06h 

;********************************************************************** 
      ORG     0x000             ; processor reset vector 
        goto    main              ; go to beginning of program 


      ORG     0x004             ; interrupt vector location 
main  bsf      STATUS,5         ; bank 0 -----> bank 1 
      movlw   b'00000000'       ; set the port a as outputs 
      movwf   TRISA             ; 
      movlw   b'00111111'       ; set the port b as inputs 
      movwf   TRISB    
      bcf      STATUS,5         ; bank 1 -----> bank 0 
read  movf   PORTB,w 			; read input from port B
      andlw   b'00111111' 		; mask of bits 
      call   table 				; refer to table, compare with inputs
      movwf   PORTA 			; write to outputs
	  goto	read				; re-read the status of inputs
table addwf    PCL,f      ; inputs   outputs 
      retlw   b'0001'      ; 0 off         
      retlw   b'0001'      ; 1 off
      retlw   b'0001'      ; 2 off
      retlw   b'0001'      ; 3 off   
      retlw   b'0001'      ; 4 off
      retlw   b'0001'      ; 5 off
      retlw   b'0001'      ; 6 off
      retlw   b'0001'      ; 7 off
      retlw   b'0001'      ; 8 off
      retlw   b'0001'      ; 9 off
      retlw   b'0001'      ; 10 off
      retlw   b'0001'      ; 11 off
      retlw   b'0001'      ; 12 off
      retlw   b'0001'      ; 13 off
      retlw   b'0001'      ; 14 off
      retlw   b'0001'      ; 15 off
      retlw   b'0001'      ; 16 off
      retlw   b'0001'      ; 17 off
      retlw   b'0001'      ; 18 off
      retlw   b'0001'      ; 19 off
      retlw   b'0010'      ; 20 low
      retlw   b'0010'      ; 21 low
      retlw   b'0010'      ; 22 low
      retlw   b'0010'      ; 23 low
      retlw   b'0001'      ; 24 off
      retlw   b'0001'      ; 25 off
      retlw   b'0001'      ; 26 off
      retlw   b'0001'      ; 27 off
      retlw   b'0100'      ; 28 med
      retlw   b'0100'      ; 26 med
      retlw   b'0100'      ; 30 med
      retlw   b'0100'      ; 31 med
      retlw   b'0100'      ; 32 med
      retlw   b'0100'      ; 33 med
      retlw   b'0100'      ; 34 med
      retlw   b'1000'      ; 35 high
      retlw   b'1000'      ; 36 high
      retlw   b'1000'      ; 37 high
      retlw   b'1000'      ; 38 high
      retlw   b'1000'      ; 39 high
      retlw   b'0100'      ; 40 med
      retlw   b'0100'      ; 41 med
      retlw   b'0100'      ; 42 med
      retlw   b'0100'      ; 43 med
      retlw   b'0100'      ; 44 med
      retlw   b'1000'      ; 45 high
      retlw   b'1000'      ; 46 high
      retlw   b'1000'      ; 47 high
      retlw   b'0100'      ; 48 med
      retlw   b'0100'      ; 49 med
      retlw   b'0100'      ; 50 med
      retlw   b'1000'      ; 51 high
      retlw   b'1000'      ; 52 high
      retlw   b'1000'      ; 53 high
      retlw   b'1000'      ; 54 high
      retlw   b'1000'      ; 55 high
      retlw   b'0100'      ; 56 med   
      retlw   b'0100'      ; 57 med
      retlw   b'0100'      ; 58 med
      retlw   b'1000'      ; 59 high
      retlw   b'1000'      ; 60 high
      retlw   b'1000'      ; 61 high
      retlw   b'1000'      ; 62 high
      retlw   b'1000'      ; 63 high
    

      END                     ; directive 'end of program'

for the purpose of using single ic(pic), can i replace the
Code:
retlw b'0001'      ; 0 off

with

Code:
goto ShortDel

for short delay(1 minutes)...

off - short delay
low - 5 minutes delay
med - 15 minutes delay
high - 30 minutes delay

if possible, i'll have an array (table) of GOTO intruction as RETLW in my previous code...am i right?..

if not...how do i handle this thing since my PIC have 64 possibilities inputs? to give approriate outputs...(time range delay, 5,15,30 minutes)

thanks
 
You simply need to call a routine which delays a certain time, multiplied by the value of W. So if the delay time is 1 second, calling it with 1 in W delays 1 second, calling it with 64 would delay 64 seconds.

You can modify your routine like this.

Code:
read  movf   PORTB,w          ; read input from port B 
      andlw   b'00111111'       ; mask of bits 
      call   table             ; refer to table, compare with inputs 
      call   DelayW         ; delay W number of times
      movwf   PORTA          ; write to outputs 
     goto   read            ; re-read the status of inputs

Obviously you also need to rewrite the table, so it gives the time delay values you require. This is the DelayW routine from my tutorials, it delays 1mS for every 1 in W - you simply need to make the inside loop as long as your timer resolution. You can generate that code with the PIClist generator, the 1mS delay here came from that!.

Code:
DelayW		movwf	count1
d1		movlw	0xC7			;delay 1mS
		movwf	counta
		movlw	0x01
		movwf	countb
Delay_0
		decfsz	counta, f
		goto	$+2
		decfsz	countb, f
		goto	Delay_0

		decfsz	count1	,f
		goto	d1
		retlw	0x00
 
You simply need to call a routine which delays a certain time, multiplied by the value of W. So if the delay time is 1 second, calling it with 1 in W delays 1 second, calling it with 64 would delay 64 seconds.

You can modify your routine like this.

Code:

read movf PORTB,w ; read input from port B
andlw b'00111111' ; mask of bits
call table ; refer to table, compare with inputs
call DelayW ; delay W number of times
movwf PORTA ; write to outputs
goto read ; re-read the status of inputs

i'm sorry nigel... i don't understand how to implement the delay for the different delay by modified my code..

if i'm going to put delay 5,15,30 minutes...

Code:
read  movf   PORTB,w          ; read input from port B 
      andlw   b'00111111'       ; mask of bits 
      call   table             ; refer to table, compare with inputs 
      call   Delay5        ; 5 minutes delay 
      movwf   PORTA          ; write to outputs 
     goto   read            ; re-read the status of inputs

so, how will my pic know to delay 5, 10 or 30 minutes..i'm sory ...eally hard for me to understand... :( ..
need more expalination..

Obviously you also need to rewrite the table, so it gives the time delay values you require

how do i modify my table..can i just simply write like this

Code:
table addwf    PCL,f      ; inputs   outputs 
      retlw   Delay5                
      retlw   Delay10      
      retlw   Delay5    
        :            :
        :            :
      retlw   Delay30      
      retlw   Delay5     
      retlw   Delay5

i do generate 5 minutes delay using code generator at piclist as suggested...
Code:
; Delay = 300 seconds
; Clock frequency = 4 MHz

; Actual delay = 300 seconds = 300000000 cycles
; Error = 0 %

	cblock
	d1
	d2
	d3
	d4
	endc

			;299999995 cycles
	movlw	0x54
	movwf	d1
	movlw	0xA1
	movwf	d2
	movlw	0xFD
	movwf	d3
	movlw	0x02
	movwf	d4
Delay_0
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	$+2
	decfsz	d3, f
	goto	$+2
	decfsz	d4, f
	goto	Delay_0

			;5 cycles
	goto	$+1
	goto	$+1
	nop

pls help me..

thanks[/quote]
 
If all you need is three preset delays you could always use three totally seperate delay routines, or (like I suggested above) a single routine which you call multiple times. Here's a modified version of my DelayW routine from above using your 300 second delay routine:

Code:
; Delay = 300 seconds 
; Clock frequency = 4 MHz 

; Actual delay = 300 seconds = 300000000 cycles 
; Error = 0 % 

   cblock 
   d1 
   d2 
   d3 
   d4 
   count1
   endc 

DelayW      movwf   count1 

Delay5
         ;299999995 cycles 
   movlw   0x54 
   movwf   d1 
   movlw   0xA1 
   movwf   d2 
   movlw   0xFD 
   movwf   d3 
   movlw   0x02 
   movwf   d4 
Delay_0 
   decfsz   d1, f 
   goto   $+2 
   decfsz   d2, f 
   goto   $+2 
   decfsz   d3, f 
   goto   $+2 
   decfsz   d4, f 
   goto   Delay_0 

         ;5 cycles 
   goto   $+1 
   goto   $+1 
   nop 

      decfsz   count1   ,f 
      goto   Delay5 
      retlw   0x00

If you 'call DelayW' with 1 in W, it will delay 5 minutes, if you call it with 2 in W it will delay 10 minutes, and so on. You 64 word long table just needs to return the required value in W.

It's simply a loop encapsulating the delay routine, W is transferred to count1, this is decremented after the 5 minute delay and the delay routine repeated, once it reaches zero the routine returns.

Because the delay is 5 minutes, that's your resolution, if you made the delay 1 minute you would have 1 minute resolution, and a maximum delay time of 255 minutes.
 
If you 'call DelayW' with 1 in W, it will delay 5 minutes, if you call it with 2 in W it will delay 10 minutes, and so on. You 64 word long table just needs to return the required value in W.

meaning that i just put 'multiply' value in my table?...to give appropriate delay to my output...

about the table...i still do not understand how it will work for this time delay..how do i put value in my table?...how about this..

Code:
table addwf    PCL,f      
      retlw   1          ; 5 minutes delay    
      retlw   2          ; 10 minutes delay    
      retlw   3          ; 30 minutes delay    
        :       : 
        :       : 
      retlw   3     
      retlw   3     
      retlw   1

for the another version...
if i'm going to have 3 preset delay...which mean i'll have three subroutine for 5, 15, & 30 minutes, how does my table will looks like..?

it's possible to do like this?..


Code:
table addwf    PCL,f      
      retlw   Delay5                
      retlw   Delay10      
      retlw   Delay5    
        :            : 
        :            : 
      retlw   Delay30      
      retlw   Delay5      
      retlw   Delay5

thanks...
 
Yes, the 'RETLW 1' is the correct way to do it, the other way wouldn't work, RETLW can only return a number between 0 and 255.

You could do it with a jump table, using 'GOTO' instead of 'RETLW'.
 
thanks a lot Nigel...you help me alot...

i do understand to implement 'variable' time delay...by using 1 subroutine i can have up to 255 time delay (for my case), just modify my 'multiply' valeu in my table...

let say...for the given input, my pic will ON for 5 minutes, and for another inputs, my pic will OFF for 15 minutes...how do i modified my table...using modified code given?..

maybe i can have 2 preset delay ...1 for on ...1 for off...what do you think?..

thanks
 
alamy said:
i do understand to implement 'variable' time delay...by using 1 subroutine i can have up to 255 time delay (for my case), just modify my 'multiply' valeu in my table...

let say...for the given input, my pic will ON for 5 minutes, and for another inputs, my pic will OFF for 15 minutes...how do i modified my table...using modified code given?..

maybe i can have 2 preset delay ...1 for on ...1 for off...what do you think?..

You don't need to modify the table at all, just the code in the main loop, it really depends on how you get the settings - for this example I'll manually insert it into W using MOVLW.

Code:
call      TurnON
movlw  1          ;set 5 minute delay
call       table
call       DelayW
call       TurnOFF
movlw   3          ;set 15 minute delay
call       DelayW
goto      Main      ;loop back to main loop

The two subroutines TurnON and TurnOFF perform the action you want taking during the two timed periods.
 
My system have 6 inputs and 1 output (on-off) …variable time delays.

My pic have the 64 possibilities input value which produce 6 or more type of output that is time delay for ON (5,15,30 minutes) and also time delay for OFF (5,15,30 minutes). For input range (possibilities value) 0-32 …my pic will OFF with certain period (5,15,30 minutes) and 33-63 it will ON (5,15,30 minutes) .

My program flow will be like this:--


then for the read routine :
Code:
read  movf   PORTB,w          ; read input from port B       
andlw   b'00111111'             ; mask of bits      
call   table                          ; refer to table, compare with inputs       
call   DelayW                      ; delay W number of times

For the lookup table which contains 64 values
Code:
table addwf    PCL,f      
      retlw   1          ; 5 minutes delay,  off  
      retlw   2          ; 10 minutes delay, off
      retlw   3          ; 15 minutes delay,   
        :     : 
        :     : 
      retlw   6          ; ON for 30 minutes  
      retlw   3     ; ON for 15 minutes  
      retlw   1	  ; ON for 5 minutes

but …the thing is how to differentiate (in table or else) between ON and OFF delay so that my pic will act as requested or I should have routine for the TurnON also TurnOFF

For the time delay…
Code:
; Delay = 300 seconds 
; Clock frequency = 4 MHz 
; Actual delay = 300 seconds = 300000000 cycles 
; Error = 0 %    
cblock    
d1    
d2    
d3    
d4    
count1    
endc 
DelayW      
movwf   count1 
Delay5          ;299999995 cycles    
movlw   0x54    
movwf   d1    
movlw   0xA1    
movwf   d2    
movlw   0xFD    
movwf   d3    
movlw   0x02    
movwf   d4 
Delay_0    
decfsz   d1, f    
goto   $+2    
decfsz   d2, f    
goto   $+2    
decfsz   d3, f    
goto   $+2    
decfsz   d4, f    
goto   Delay_0          ;5 cycles    
goto   $+1    
goto   $+1    
nop       
decfsz   count1   ,f       
goto   Delay5       
retlw   0x00

pls advice...
 

Attachments

  • flow.gif
    flow.gif
    4 KB · Views: 581
alamy said:
My system have 6 inputs and 1 output (on-off) …variable time delays.

My pic have the 64 possibilities input value which produce 6 or more type of output that is time delay for ON (5,15,30 minutes) and also time delay for OFF (5,15,30 minutes). For input range (possibilities value) 0-32 …my pic will OFF with certain period (5,15,30 minutes) and 33-63 it will ON (5,15,30 minutes) .

My program flow will be like this:--


then for the read routine :
Code:
read  movf   PORTB,w          ; read input from port B       
andlw   b'00111111'             ; mask of bits      
call   table                          ; refer to table, compare with inputs       
call   DelayW                      ; delay W number of times

After you've read the port and applied 'ANDLW' you have a 6 bit number in W - I would suggest you store it in a temporary register.

Code:
movwf Temp

You can then check bit 5 to see if it's '1' or not, and the program can branch accordingly - to routines to either turn ON or turn OFF then delay the amount of time set.

You then only need a 32 byte table (because bit 5 isn't part of the table), so you should 'ANDLW b'00011111' before calling the table.

Another way of doing it, would be to use the full 64 byte table, but for the second half of the table have bit 7 set in the entries, then after reading the table test bit 7, and turn On or OFF accordingly - remembering to mask off bit 7 before calling the delay.

The first way would be shorter, because you half the size of the table.
 
alamy Can you use two ' ORG ' statements like that..??
how is the assembler going to handle two ORG statements?
this is the code...i have never tried it though..


Code:
;***** VARIABLE DEFINITIONS 
STATUS      EQU     03h      ; variable used for context saving 
TRISA      EQU      85h        ; variable used for context saving 
PORTA      EQU      05H 
TRISB      EQU      86h 
PORTB      EQU      06h 

;********************************************************************** 
      ORG     0x000             ; processor reset vector 
        goto    main              ; go to beginning of program 


      ORG     0x004             ; interrupt vector location 
main  bsf      STATUS,5         ; bank 0 -----> bank 1 
      movlw   b'00000000'       ; set the port a as outputs 
      movwf   TRISA             ; 
      movlw   b'00111111'       ; set the port b as inputs 
      movwf   TRISB    
      bcf      STATUS,5         ; bank 1 -----> bank 0
 
williB said:
alamy Can you use two ' ORG ' statements like that..??
how is the assembler going to handle two ORG statements?
this is the code...i have never tried it though..

Code:
      ORG     0x000             ; processor reset vector 
        goto    main              ; go to beginning of program 


      ORG     0x004             ; interrupt vector location 
main  bsf      STATUS,5         ; bank 0 -----> bank 1


That's EXACTLY the way to use ORG statements, you can use as many as you want - it just moves the current address for the assembler. If I was ading data statements I would add an ORG for that address, or add another ORG in order to place a table at the start of a 256 byte boundary.

The only problem I have with the code is that 'main' is sat on the interrupt vector address, I would use a different address to free up the interrupt vector - or simply start from 0x000 if you're not using interrupts at all.
Like this:

Code:
      ORG     0x000             ; processor reset vector 
        goto    main              ; go to beginning of program 


      ORG     0x004             ; interrupt vector location
      RETFIE                       ; return from interrupt (just in case!)
                                       ; main now at 0x0005 
main  bsf      STATUS,5         ; bank 0 -----> bank 1
 
pls comment my program flow..


You can then check bit 5 to see if it's '1' or not, and the program can branch accordingly - to routines to either turn ON or turn OFF then delay the amount of time set.

read input (set 31 as setpoint ; branch to TurnOn/TurnOff) and i'll have two table ....


Code:
Read	Movf       PORTB,w
                Subwf     SP,w  ; where SP define as 31 (b’11111’)
                Btfss       STATUS,C  ; I’m not sure use this one….
                Call        TurnOn
                Call        TurnOff

TurnOn 	andlw      b’00011111’
               	Call         TableOn
	Call         DelayW
	Bcf          PORTA
           	Goto        Read

TurnOff 	andlw      b’00011111’
               	Call         TableOff
	Call         DelayW
	 Bsf         PORTA
           	 Goto       Read

TableOn 	Addwf pcl,f
	Retlw  1
	Retlw  1
	Retlw  2
	Retlw  1
	Retlw  3
	     :
	     :
	Retlw  1

TableOff 	Addwf pcl,f
	Retlw  1
	Retlw  1
	Retlw  2
	Retlw  1
	Retlw  3
	     :
	     :
	Retlw  1

modified(nigel) version of time delay

Code:
Delay = 300 seconds 
; Clock frequency = 4 MHz 

; Actual delay = 300 seconds = 300000000 cycles 
; Error = 0 % 

   cblock 
   d1 
   d2 
   d3 
   d4 
   count1 
   endc 

DelayW      movwf   count1 

Delay5 
         ;299999995 cycles 
   movlw   0x54 
   movwf   d1 
   movlw   0xA1 
   movwf   d2 
   movlw   0xFD 
   movwf   d3 
   movlw   0x02 
   movwf   d4 
Delay_0 
   decfsz   d1, f 
   goto   $+2 
   decfsz   d2, f 
   goto   $+2 
   decfsz   d3, f 
   goto   $+2 
   decfsz   d4, f 
   goto   Delay_0 

         ;5 cycles 
   goto   $+1 
   goto   $+1 
   nop 

      decfsz   count1   ,f 
      goto   Delay5 
      retlw   0x00


pls advice..

Another way of doing it, would be to use the full 64 byte table, but for the second half of the table have bit 7 set in the entries, then after reading the table test bit 7, and turn On or OFF accordingly - remembering to mask off bit 7 before calling the delay

i've no idea on this...
 

Attachments

  • flow1.jpg
    flow1.jpg
    21.1 KB · Views: 321
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top