![]() | ![]() | ![]() |
| | |||||||
| Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc. |
| | Thread Tools | Display Modes |
| | (permalink) |
| Experienced Member | AtomSoft (and gang), I suspect this may be slightly off topic but I wanted to say I agree with donniedj about using a good general purpose delay subroutine and thought I'd share one of the delay systems I use with 16F' devices. This small (12 instruction) delay subroutine system was designed to work with a 4, 8, 12, 16, or 20 MHz clock and provides a variable delay of 16 to 262144 cycles (Tcy) which can be specified in cycles, microseconds, or milliseconds. You can also specify delays in microseconds or milliseconds plus or minus some number of cycles to produce precise isochronous delay loops. Here's a simple key press beep routine to demonstrate. The first example uses the DelayMS() macro but doesn't account for the 6 instruction cycles in the loop and won't produce an exact 500 Hz tone. The second example uses the DelayCy() macro instead with usecs or msecs multiplier in the operand and subtracts 6 instruction cycles to produce an exact 500 Hz tone no matter what clock frequency you're using. Code: ;
; key press beep -- 1 msec delay, no loop timing correction
;
; 497.018 Hz -- 4 MHz clock
; 498.504 Hz -- 8 MHz clock
; 499.004 Hz -- 12 MHz clock
; 499.251 Hz -- 16 MHz clock
; 499.400 Hz -- 20 MHz clock
;
bsf Beep,5 ; do 32 msec switch press beep |B0
DoBeep movf PORTA,W ; read port A |B0
xorlw 1<<Spkr ; toggle speaker bit |B0
movwf PORTA ; toggle speaker pin |B0
DelayMS(1) ; delay 1 msec for 500 Hz tone |B0
decfsz Beep,F ; done? yes, skip, else |B0
goto DoBeep ; loop (toggle Spkr pin again) |B0 Code: ;
; key press beep -- 1 msec delay, with loop timing correction
;
; 500 Hz -- any clock (4, 8, 12, 16, or 20 MHz)
;
bsf Beep,5 ; do 32 msec switch press beep |B0
DoBeep movf PORTA,W ; read port A |B0
xorlw 1<<Spkr ; toggle speaker bit |B0
movwf PORTA ; toggle speaker pin |B0
DelayCy(1*msecs-6) ; delay 1 msec minus 6 cycles |B0
decfsz Beep,F ; done? yes, skip, else |B0
goto DoBeep ; loop (toggle Spkr pin again) |B0 Have fun. Regards, Mike Code: ;******************************************************************
; *
; DelayMS(), DelayUS(), DelayCy() Mike McLaren, K8LH, Jun'07 *
; *
; requires the use of constant operands known at assembly time! *
; *
; simple macro "front ends" and a small 16-bit delay subroutine *
; which allows specifying delays in msecs, usecs, or cycles. *
; *
; the delay range is based on the microprocessor clock and the *
; delay subroutine loop time (a 4 cycle loop in this case). *
; *
; 4 MHz, 1 cycles/usec, 16..262144 usecs, 1..262 msecs *
; 8 MHz, 2 cycles/usec, 8..131072 usecs, 1..131 msecs *
; 12 MHz, 3 cycles/usec, 6...87381 usecs, 1...87 msecs *
; 16 MHz, 4 cycles/usec, 4...65536 usecs, 1...65 msecs *
; 20 MHz, 5 cycles/usec, 4...52428 usecs, 1...52 msecs *
; *
; example: a 1 msec delay can be produced the following ways *
; *
; DelayMS(1) ; delay 1 msec *
; DelayUS(1000) ; delay 1 msec *
; DelayCy(1*msecs) ; delay 1 msec *
; DelayCy(1000*usecs) ; delay 1 msec *
; *
; the latter two methods allow you to add or subtract cycles to *
; maintain precise (clock independent) isochronous loop timing. *
; *
;******************************************************************
radix dec
clock equ 4 ; user clock freq in MHz
usecs equ clock/4 ; cycles per microsecond
msecs equ clock/4*1000 ; cycles per millisecond
; *
; DelayMS(), DelayUS(), and DelayCy() macros *
; *
DelayMS macro pDelay ; msec range from table above
DelayCy(pDelay*msecs) ; convert to cycles
endm ;
DelayUS macro pDelay ; usec range from table above
DelayCy(pDelay*usecs) ; convert to cycles
endm
DelayCy macro pCycles ; cycles, 16..262159 range
movlw high((pCycles-16)/4)+1
movwf TMRH
movlw low ((pCycles-16)/4)
call DelayLo-(pCycles%4)
endm
; *
; example code for simulation testing; *
; *
SimTest DelayUS(16000) ; remember to set 'clock' equate
nop ; put simulator break point here
; *
;******************************************************************
; *
; Delay(16..262159 Tcy) subroutine Mike McLaren, K8LH, Jun'07 *
; *
; 12 words, 1 RAM variable, 14-bit core *
; *
Delay.16
nop ; entry point for delay%4 == 3
nop ; entry point for delay%4 == 2
nop ; entry point for delay%4 == 1
DelayLo addlw -1 ; subtract 4 cycle loop time
skpnc ; borrow? yes, skip, else
goto DelayLo ; do another loop
nop ;
DelayHi addlw -1 ; subtract 4 cycle loop time
decfsz TMRH,F ; done? yes, skip, else
goto DelayLo ; do another loop
goto $+1 ; burn off 2 cycles
return ;
; *
;****************************************************************** Last edited by Mike, K8LH; 20th April 2008 at 11:03 AM. |
| | |
| Bookmarks |
| Thread Tools | |
| Display Modes | |
| |
| | ||||
| Thread | Thread Starter | Forum | Replies | Latest |
| Switching power supply issue. | dbtoutfit | General Electronics Chat | 41 | 25th March 2008 03:21 AM |
| issue with my handheld console draining batterys... | tgg | General Electronics Chat | 0 | 26th September 2007 03:37 AM |
| ESD Issue? Kind of long | Peach | General Electronics Chat | 21 | 8th April 2007 01:47 AM |
| Need Someone Realy Good At Computers..... REAL good | PapaSmurf | Chit-Chat | 16 | 3rd May 2006 10:30 PM |
| EPE magazine - may 2001 issue - PIC graphics LCD scope | evandude | General Electronics Chat | 4 | 12th December 2004 05:43 PM |