![]() | ![]() | ![]() |
| | |||||||
| Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc. |
| | LinkBack | Thread Tools | Display Modes |
| | (permalink) |
| I started programming 8051 and i calculated exact timing delays by using basic maths when i knew the crystal speed. For example when using a 11.059 crystal the time for a single instruction came out be 1.085x10exp-11. So i could generate exact delays by using this How can i generate such exact timing delays in PIC (dsPIC) to be specific? What is the time for a single instruction in PIC? How can i generate these exact timing delays in C for pic's? | |
| |
| | (permalink) |
| The datasheet will tell you the exact timings (I've never used dsPIC's), but for 16F series devices the timing is 1/4 of the clock speed. So a 16F running at 4MHz takes 1uS per instruction, apart from branch instructions, which takes 2 instruction cycles. | |
| |
| | (permalink) |
| Just as an aside. No professional programmer worth his salt would ever use instruction cycles as a method of generating delays. It is fraught with perils too numerous to mention. If you want to distinguish yourself among your peers use the onboard timers for delays both short and long. In short don't program like a weenie. | |
| |
| | (permalink) |
| Ontopic portion: Usually for C source that require critical timing, this needs to be done in assembly. You can't really guarantee how many cycles the C compiler will use to design your function written in C. I've never used a PIC C compiler, but in gcc for the AVR there's the __asm__() directive which will let you hard code assembly into your C. For these *really* timing sensitive applications you will need to use/tune assembly extensively, and it may be worth to get familiar with it. Be careful with the btfsc, btfss, decfsz, incfsz, etc. instructions as they may have unexpected timing numbers depending on situation. However I'm sure you're well aware of that after using the 8051. Offtopic portion: I actually beg to differ on programming jobs on devices with CPUs that never change. This was a bad assumption for personal computers that received speed bumps, and hence we got unplayable games when moving from an IBM XT to an IBM AT as well as broken emulators, but it may be appropriate for microcontrollers soldered into circuits that will never change/upgrade. Likely microcontroller software should be do once, never touch again. If you need to touch again, likely it's due to a bug that should have been fixed before completing the project. That being said, software timing loops can be really difficult to debug. Back on topic: If your microcontroller is much faster than your target application, and you have the timer resources to do it, you should go ahead and use the timers - there's no excuse not to. However, if you're out of resources, or the resolution of the timer will kill your performance (don't forget: timer interrupt latency dealing with context save and possibly multiplexed timer functions where the timer may be used for more than one thing) then software timers may not be a bad idea after all. Also note: during software timing you'll have to disable interrupts anyway, so I guess the timer resource availability issue is moot. But if you are careful you can get pretty wicked software-timed applications. Just DON'T UPGRADE YOUR CPU (or firmware!) AFTER IT'S DONE! And do remember it's not your job to make people writing emulators for your code happy! (but if you want to be nice... then go ahead!) | |
| |
| | (permalink) | |
| Quote:
The code becomes impractical to maintain if you try to do anything inside the code block. No one wants to recalculate the cycles a code block takes. Interrupts must be disabled during this period, in many systems you can't do this for long. But there are cases where it's fine. If you only need a specific delay, then a loop waiting 156 Nop instructions is fine and generally easy to maintain. If your delay requirement is actually only a minimum delay- like meeting timing of an external device- then interrupts increasing the execution time is just fine.
__________________ I thought what I'd do was I'd pretend I was one of those deaf-mutes. | ||
| |
| | (permalink) | |
| Quote:
Software loop delays are commonplace, and are what HL compilers generate. | ||
| |
| | (permalink) | |
| Quote:
http://www.piclist.com/techref/picli...egen/delay.htm I suppose you could include some asm code within your C program to make the precise delay. I have not used it with dsPIC chips so you may need to check if their instruction cycle timings are the same as the 16F series. The timing for each instruction depends on the clock frequency and the type of instruction. In the 16F and 18F series MOST instructions use 1 instruction cycle (which takes 1uS at a clock speed of 4Mhz - ie clock frequency/4) Conditional instructions may take 1 or 2 cycles depending on the condition being false or true. There are also more complex instructions in the 18F series that can take 3 instruction cycles - so check the manual for your dsPic chip to be sure. | ||
| |
| | (permalink) | |
| Quote:
__________________ I also post at the following sites: http://www.stop-microsoft.org http://www.heated-debates.com Screen name: Aloone_Jonez And http://www.silicontronics.com, same screen name as here. | ||
| |
| | (permalink) | |
| Quote:
| ||
| |
| | (permalink) |
| I wonder if studying this example for 18F' devices might help? Other examples are available on PICLIST. Longer periods, like HH:MM:SS Photo/Appliance Timers, Alarms, Stop Watch Functions, etc., are probably best handled with a Timer based interrupt routine. Regards, Mike Code: radix dec
;******************************************************************
; *
; DelayMS() and DelayUS() Macros Mike McLaren, K8LH, Jun'07 *
; *
; simple 'front end' macros for 24-bit DelayTcy() routines that *
; allow you to specify delays in 'usecs' and 'msecs'. *
; *
; the delay parameter range is based on clock frequency *
; *
; 4 MHz, 1 cycle /usec, 21..16,777,215 us, 1..16,777 ms *
; 6 MHz, 1.5 cycles/usec, 14..11,184,810 us, 1..11,184 ms (1) *
; 8 MHz, 2 cycles/usec, 11...8,388,607 us, 1...8,388 ms *
; 10 MHz, 2.5 cycles/usec, 9...6,710,886 us, 1...6,710 ms (1) *
; 12 MHz, 3 cycles/usec, 7...5,592,405 us, 1...5,592 ms *
; 16 MHz, 4 cycles/usec, 6...4,194,303 us, 1...4,194 ms *
; 20 MHz, 5 cycles/usec, 5...3,355,443 us, 1...3,355 ms *
; 24 MHz, 6 cycles/usec, 4...2,796,202 us, 1...2,796 ms *
; 28 MHz, 7 cycles/usec, 3...2,396,745 us, 1...2,396 ms *
; 32 MHz, 8 cycles/usec, 3...2,097,151 us, 1...2,097 ms *
; 36 MHz, 9 cycles/usec, 3...1,864,135 us, 1...1,864 ms *
; 40 MHz, 10 cycles/usec, 3...1,677,721 us, 1...1,677 ms *
; 48 MHz, 12 cycles/usec, 2...1,398,101 us, 1...1,398 ms *
; *
; (1) 6 and 10 MHz clocks produce inprecise timing *
; *
; DelayMS() and DelayUS() macros require a 'clock' equate; *
; *
clock equ 32 ; insert your clock freq (MHz)
; *
; DelayMS() and DelayUS() macros; *
; *
DelayMS macro msecs ; delay range: see list above
DelayUS(msecs*1000)
endm
DelayUS macro usecs ; delay range: see list above
DelayTcy(usecs*(10000/(4000/clock))/10)
endm
; *
;******************************************************************
; *
; DelayTcy(), 24-bit Mike McLaren, K8LH, Jun-07 *
; *
; simple macro for simulation testing; *
; *
DelayTcy macro delay ; parameter 21..16777215
if delay < 256
movlw delay ; 2 instructions, 3 cycles
rcall DelayTcy.byte ;
else
if delay < 65536
movlw ~(high(delay)) ; 4 instructions, 5 cycles
movwf TMRH ;
movlw low delay ;
rcall DelayTcy.16 ;
else
movlw ~(upper(delay)) ; 6 instructions, 7 cycles
movwf TMRU ;
movlw ~(high(delay)) ;
movwf TMRH ;
movlw low delay ;
rcall DelayTcy.24 ;
endif
endif
endm
; *
; code for simulation testing; *
; *
SimTest DelayMS(2000) ; DelayTcy(), DelayUS(), DelayMS()
nop ; put simulator breakpoint here
; *
; *
;******************************************************************
; *
; DelayTcy() subroutine Mike McLaren, K8LH, Jun-07 *
; *
; 20 words, 2 RAM variables (16 bit core) *
; ^^^^^^^^^^^ *
DelayTcy.byte
clrf TMRH ;
comf TMRH,F ; compliment TMRH
DelayTcy.16
clrf TMRU ;
comf TMRU,F ; compliment TMRU
DelayTcy.24
addlw -24 ; subtract "overhead" + 1 cycle
bnc DelayHi ; borrow? yes, branch, else
addlw 1 ; replace unused 'borrow' cycle
DelayLo
addlw -3 ; subtract 3 cycle loop time
bc DelayLo ;
DelayHi
addlw -3 ; subtract 3 cycle loop time
incfsz TMRH,F ; TMRH done? yes, skip, else
bra DelayLo ; loop again
addlw -3 ; subtract 3 cycle loop time
incfsz TMRU,F ; TMRU done? yes, skip, else
bra DelayLo ; loop again
;
; account for delay%3 timing (3, 4, or 5 cycles before return)
;
xorlw 0xF7 ; F7 (1), F8 (1), F9 (1)
bz DelayXit ; F7 (2), F8 (1), F9 (1)
xorlw 0xF9^0xF7 ; F8 (1), F9 (1)
bz DelayXit ; F8 (1), F9 (2)
DelayXit ; ----------------------
return ; F7=(3), F8=(4), F9=(5)
; *
;****************************************************************** | |
| |
| | (permalink) |
| A couple problems with coded delay loops, they don't work with heavy interupt usage, they can also depend on the exact compiler options that are used to compile the code. Interupt timers are good but they can't do really fine timeing, only hard coded delay routines can do that. A mix of both is usually what's best. A hardware timer for course timeing to free the processor up to do things while it's waiting with some fudge room for other interupts, and then when you need to count out very precisly for one brief period the exact number of clock pulses from the event you disable interupts and run your delay code.
__________________ "Because I be what I be. I would tell you what you want to know if I could, mum, but I be a cat, and no cat anywhere ever gave anyone a straight answer, har har." Last edited by Sceadwian; 21st September 2007 at 02:09 AM. | |
| |
| Bookmarks |
| Thread Tools | |
| Display Modes | |
| |
| | ||||
| Title | Starter | Forum | Replies | Latest |
| Can i make an Intelligent Switch by using PIC 16F84A | rukshankb | Micro Controllers | 3 | 22nd September 2007 04:58 PM |
| Rf Pic | flemmard | Electronic Projects Design/Ideas/Reviews | 1 | 9th September 2007 09:34 PM |
| Timing Circuit with Relay | Coded_Bananas | Electronic Projects Design/Ideas/Reviews | 6 | 6th October 2006 08:28 AM |
| Timing Diagram and waveform viewer available for PIC? | janetsmith2000@yahoo.com | Micro Controllers | 7 | 12th August 2005 02:17 AM |
| timing system for drag races | itayi | Electronic Projects Design/Ideas/Reviews | 2 | 16th October 2003 04:02 PM |