delay routine question (assembly + C)

Thread Starter

dannybeckett

Joined Dec 9, 2009
185
Hi guys. I have prtty much completed an embedded design project I am working on, a spinning LED persistance of vision display. Every aspect of the program works fine apart from the delay routine.

For interests sake, here is my program (it's heavily annotated):

C code - 270 lines - codepad

Basically, all I need to do is create a delay routine which takes in a 0-65535 number, and delays for that many microseconds. So a value of 43 passed into the routine creates a delay for 43us. I'm using a PIC16F887.

The PIC is set at 4MHz, so each instruction takes 1us. I suspect there is going to have to be a fixed, small delay for the routine to start so that shouldnt be a problem so long as its not too long. I suspect I am going to be using assembly in the C code, I have a vague idea of how this might work. DECFSZ decrements the variable modified by the C program and does so until the delay routine is up.

Does anyone know how to protect 16 bits of memory from being overwritten by anything else, and place a variable in this specific location? This way, I can easily address it in assembly.

Thanks for your help
 

t06afre

Joined May 11, 2009
5,934
Synopsis
__delay_ms(x) // request a delay in milliseconds
__delay_us(x) // request a delay in microseconds
Description
As it is often more convenient request a delay in time-based terms rather than in cycle
counts, the macros __delay_ms(x) and __delay_us(x) are provided. These macros
simply wrap around _delay(n) and convert the time based request into instruction
cycles based on the system frequency. In order to achieve this, these macros require
the prior definition of preprocessor symbol _XTAL_FREQ. This symbol should be
defined as the oscillator frequency (in Hertz) used by the system. Also the
An error will result if these macros are used without defining oscillator frequency​
symbol or if the delay period requested is too large.
HI-TECH has native functions for that. And they work very well well in newer versions (after 9.70). No need for using external functions here.
Also the #define _XTAL_FREQ value must be set to the value you have in respect to the OSCON settings 1 MHz in your case. Se figure 4.1 in the data-sheet
 

someonesdad

Joined Jul 7, 2009
1,583
Can't you just use the _delay() function that's already written? I believe I used it with a 16 bit value a few weeks ago. This was the Microchip C18 compiler.

Edit: Oops, I started to respond and got dragged away for a few minutes and didn't see t06afre's post.
 

Thread Starter

dannybeckett

Joined Dec 9, 2009
185
Hi guys. I have tried the delay routine on the microchip website and that didn't work properly. The hi tech delay function works well, but you can't pass variables to it.
 

t06afre

Joined May 11, 2009
5,934
The hi tech delay function works well, but you can't pass variables to it.
He he that both wrong and correct. Then the compiler is used in Lite mode(free version) you are correct. But in at least PRO mode you can pass variables. Then you install the compiler you will get 30 days pro mode. Unless you pay o fcourse. If you do not have installed the latest version. You can download it and get a new 30 days trail in pro mode
 

eblc1388

Joined Nov 28, 2008
1,542
Basically, all I need to do is create a delay routine which takes in a 0-65535 number, and delays for that many microseconds. So a value of 43 passed into the routine creates a delay for 43us. I'm using a PIC16F887. The PIC is set at 4MHz, so each instruction takes 1us.
You are not being realistic about the lower bound of the time delay.

At 4MHz, a single PIC instruction already takes 1us and you specified 0us as your lower limit. What about the function calling/returning overhead?

Even with asm codes, the realistic delay timing of a generic delay routine starts from about 14 instructions upwards. You can have other separate routines to delay anything less than 14 cycles.

I have seen asm routine that delay 14~65535 instruction cycles by placing the delay variable in a 16-bit variable. Alternatively the lower byte is placed in W and only the higher byte requires register storage.

If you want more information, see this thread on the Microchip forum:http://www.microchip.com/forums/tm.aspx?high=&m=409798&mpage=1#409798
 

Thread Starter

dannybeckett

Joined Dec 9, 2009
185
eblc1338 you are absolutely correct, I had already accounted for that I just didnt explicity say it. I was expecting to lose a few microseconds calling the function etc. That link you have found looks incredibly useful, thanks so much for sharing it. I'm going to have a thorough read through the thread, hopefully I wont have too many questions to ask once I've understood the basic principle in whats going on lol.
 
Top