Thread: embedded design, delay routine question

  1. #1
    Registered User
    Join Date
    Mar 2011
    Posts
    22

    embedded design, delay routine question

    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.

    The PIC is set at 4MHz, so each instruction takes 1us. I suspect there is going to have to be a set, small delay for the routine to start so that has been accounted for. I suspect I am going to be using assembly in the C code also.

    Any help is greatly appreciated.

  2. #2
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Which specific PIC micro you're dealing with here?
    And why is that the infinite loop in main() empty?

  3. #3
    Registered User
    Join Date
    Mar 2011
    Posts
    22
    A PIC16F887, and the while loop is there just to keep the processor idling when it's not doing anything

  4. #4
    Registered User
    Join Date
    Mar 2011
    Posts
    22
    I have a vague idea, using DECFSZ to decrement the variable passed to it from the C program. 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.

  5. #5
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Can you explain what exactly this program is trying to do?
    The posted code includes delay.c where delay.h was meant.
    Does the compiler have any intrinsics for hardware interfacing?

  6. #6
    Registered User
    Join Date
    Mar 2011
    Posts
    22
    Basically the program is to control a spinning persistance of vision LED display, very simalar to this: YouTube - Spinning LED Display using Fan Motor 2 - Featured on Hacked Gadgets

    The include delay.c is actually correct - I was trying out a delay routine I saw available on microchips' website, but it did not work. The delay.c has a few functions written inside it and includes delay.h itself. The function DelayBigUs() used on lines 174 and 176 is defined in delay.c.

    I'm not 100% sure what you mean by intrinsics, I suspect it's the pre-defined names I use to address specific bits? If so, then yes, instead of having to address specific memory locations to access certain configuration bits on the processor, I can use pre-defined names and the compiler takes care of the rest.

    There is a delay function built into the compiler I am using, which would work fine if it could accept variables!
    Last edited by dannybeckett; 03-21-2011 at 01:17 AM.

  7. #7
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Intrinsics are functions that interface with the hardware as the C language cannot manipulate that. Google compiler intrinsics and you should be on your way. Examples of intrinsics would be functions like openLCD() / setupLCD() that control LCD configuration and display. As far as the project goes, I was trying to figure out how is all this wired up - the pinouts etc? Post the schematic if you have one, and what compiler are you using?

  8. #8
    Registered User
    Join Date
    Mar 2011
    Posts
    22
    Ahh I see, I am not using any intrinsic functions like that. The only things not native to the language are the very self explanatory names for accessing certain register bits, output ports, etc such as TRISA, CM1CON0bits.C1CON, TMR1 blah blah blah. They are all defined in the htc.h header file.

    The schematic is that simple I haven't even made one. An optical sensor is wired to a schmitt trigger, which delivers a pulse to pin RC2 on my PIC16F887. This is the CCP1 interrupt pin. I have configured the capture/compare/pwm module to 'capture every rising edge' the contents of timer1. Timer1 is reset at the beginning of the interrupt routine. It then does a little maths in the interrupt function to figure out, for a given set of dimensions, the time it takes for the spinning rotor to move from one pixel row to the next. It then passes the value its calculated to a global which can be accessed by the showMeTheLights() function which flashes the LEDs in such a mannor as to create an image. The rotor spins counterclockwise, and the 'top' LED is connected to RB0, the 'bottom' to RB7.

    I am using the HI-TECH C Compiler.

    I hope this clears things up, let me know any more info you need

    I've tested all my numbers completely (by outputting them to portb) and its working beautifully, bar this damn delay routine fiasco.

  9. #9
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by dannybeckett View Post
    I have a vague idea, using DECFSZ to decrement the variable passed to it from the C program. 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.
    I'm not familiar with HITECH-C, but the inline assembly feature of most compilers can access C symbols, so you can refer to it by name:
    Code:
    #asm
    decfsz some_variable, 3
    Also, your function could simply wrap the __delay_us() function, like so:
    Code:
    void my_delay_us(unsigned short delay_amount)
        while (delay_amount > 10000) {
            __delay_us(9998);    // leave 1us for the comparison and 1 for the subtraction 
            delay_amount -= 10000;
        }
        while (delay_amount > 1000) {
            __delay_us(998);    // leave 1us for the loop comparison and 1 for the subtraction 
            delay_amount -= 1000;
        }
    ...
    }
    It's a little hackish and may suffer a couple microsecond inaccuracy when you get down below 10us, but it's something. Still, it should be better than a NOP loop.

  10. #10
    Registered User
    Join Date
    Mar 2011
    Posts
    22
    Those ideas are really good anduril... I will experiment and let you know how it goes.

  11. #11
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by dannybeckett View Post
    Ahh I see, I am not using any intrinsic functions like that. The only things not native to the language are the very self explanatory names for accessing certain register bits, output ports, etc such as TRISA, CM1CON0bits.C1CON, TMR1 blah blah blah. They are all defined in the htc.h header file.
    Those aren't intrinsics per se, but are close enough as they get translated into assembly.
    Quote Originally Posted by dannybeckett View Post
    The schematic is that simple I haven't even made one. An optical sensor is wired to a schmitt trigger, which delivers a pulse to pin RC2 on my PIC16F887. This is the CCP1 interrupt pin. I have configured the capture/compare/pwm module to 'capture every rising edge' the contents of timer1. Timer1 is reset at the beginning of the interrupt routine. It then does a little maths in the interrupt function to figure out, for a given set of dimensions, the time it takes for the spinning rotor to move from one pixel row to the next. It then passes the value its calculated to a global which can be accessed by the showMeTheLights() function which flashes the LEDs in such a mannor as to create an image. The rotor spins counterclockwise, and the 'top' LED is connected to RB0, the 'bottom' to RB7.
    So the LED outputs one complete segment column before moveing onto the next one?
    Quote Originally Posted by dannybeckett View Post
    I am using the HI-TECH C Compiler.

    I hope this clears things up, let me know any more info you need

    I've tested all my numbers completely (by outputting them to portb) and its working beautifully, bar this damn delay routine fiasco.
    The part I don't get is the "damn delay routine fiasco" if everything's "working beautifully"?
    Explain about what the delay routine is supposed to be doing and how it is not doing that.

  12. #12
    Registered User
    Join Date
    Mar 2011
    Posts
    22
    So the LED outputs one complete segment column before moveing onto the next one?
    Exactly, the calculated time delay is the time it takes for the LED's to move to one columb to the next.

    The part I don't get is the "damn delay routine fiasco" if everything's "working beautifully"?
    Explain about what the delay routine is supposed to be doing and how it is not doing that.
    I was referring to the number crunching part of the program, it's 100% functional. I programmed ports b and d to display the 16 bit numbers of CCP1 and the calculated time delay, one after eachother. I wrote down the binary values and converted them into decimal. I did all the equation working-out manually, and the calculated time delay was exactly what it should have been, given that specific CCP1 time capture - this is how I know the numbers are being dealt with properly.

    The only thing I need is a delay routine, to take in the uS time delay calculated, to get each 'columb' lit up accurately at any given RPM (within reason). Once this has been achieved, the program is complete.

  13. #13
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,834
    At 4 MHz, I doubt each instruction takes 1 us. Most likely instructions take multiple clocks to execute. You'll have to put together a bunch of instructions, even if they are NOPs, inside a loop such that the total including jump and counter increment add to N us. Although you will never get 1 us resolution.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. database app design question
    By MPSoutine in forum Windows Programming
    Replies: 4
    Last Post: 12-02-2003, 10:13 PM
  2. Constructor failed: design question
    By registering in forum C++ Programming
    Replies: 9
    Last Post: 07-01-2003, 03:29 PM
  3. design question: opinion
    By ggs in forum C Programming
    Replies: 2
    Last Post: 01-29-2003, 11:59 AM
  4. Replies: 4
    Last Post: 11-19-2002, 09:18 PM
  5. OO design question
    By PJYelton in forum C++ Programming
    Replies: 8
    Last Post: 10-10-2002, 12:52 PM