Add a little to your idea... Assuming the pins in question are on the same port...
Code:TRIS? = %00000000 X VAR BYTE Y VAR BYTE Z VAR BYTE STROBE: PORT? = %00000111 PAUSE X ' Or use PAUSEUS PORT? = %00000011 PAUSE Y PORT? = %00000001 PAUSE Z PORT? = %00000000 RETURN
Dave
Always wear safety glasses while programming.
Hi, Andew
It's in French ... Yes.
But just close to what you look for ...
http://mathieu.agopian.free.fr/prog_pic/servobis/
http://mathieu.agopian.free.fr/prog_pic/servoter/
Alain
************************************************** ***********************
Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
************************************************** ***********************
IF there is the word "Problem" in your question ...
certainly the answer is " RTFM " or " RTFDataSheet " !!!
*****************************************
Hi Andrew,
Would you like me to describe one method for producing up to 8 precisely timed synchronous pulses (on a single port), each pulse with a pulse width value of from 0 (off) to 1023 usecs with 1 usec pulse width resolution? If so, please let me know and I'd be happy to explain how the following code snippets work. I apologize for the C code.
Kind regards, Mike
Code:unsigned int pulse[] = { 120, // pulse 0 (RB0), 120-usecs 44, // pulse 1 (RB1), 44-usecs 45, // pulse 2 (RB2), 45-usecs 1001, // pulse 3 (RB3), 1001-usecs 0, // pulse 4 (RB4), off/not used 0, // pulse 5 (RB5), off/not used 0, // pulse 6 (RB6), off/not used 0 }; // pulse 7 (RB7), off/not used unsigned char toggle[1024] @0x400 // 1024 element (interval) toggle arrayCode:// // 1024 interval output routine (BoostC compiles the following // do-while code into a 5-cycle loop which is perfect for 1-usec // intervals with a 20-MHz clock). // void Output() { fsr0 = 0x400; // interval = 0 do // do { latb ^= postinc0; // { latb ^= toggle[interval++] } while(fsr0h.3 == 0); // } while(interval < 1024) }Code:// // build new toggle array from the pulse array before calling Output() // void PrepArray() { for(i = 0; i < 1024; i++) // toggle[i] = 0; // clear the array toggle[pulse[0]] |= 1; // insert RB0 output toggle bit toggle[pulse[1]] |= 2; // insert RB1 output toggle bit toggle[pulse[2]] |= 4; // insert RB2 output toggle bit toggle[pulse[3]] |= 8; // insert RB3 output toggle bit toggle[pulse[4]] |= 16; // insert RB4 output toggle bit toggle[pulse[5]] |= 32; // insert RB5 output toggle bit toggle[pulse[6]] |= 64; // insert RB6 output toggle bit toggle[pulse[7]] |= 128; // insert RB7 output toggle bit toggle[0] ^= 0xFF; // fix toggle[0] element }
Last edited by Mike, K8LH; - 16th October 2009 at 22:57.
Hi Andrew,
The disadvantage of this particular method is that you need a PIC with lots of RAM, something like an 18F2620, for the 1024 byte toggle array. If this is a one-off project then perhaps that may not be a big deal.
The PrepArray() routine builds the following (abbreviated) toggle[] array from the pulse[] array values and the Output() routine uses those values to update LATB as shown below;
Code:interval ^ LATB 0000-usecs toggle[ 0] = 0b00001111 0b00001111 RB3..RB0 toggled on 0001-usecs toggle[ 1] = 0b00000000 0b00001111 .... 0043-usecs toggle[ 43] = 0b00000000 0b00001111 0044-usecs toggle[ 44] = 0b00000010 0b00001101 RB1 toggled off 0045-usecs toggle[ 45] = 0b00000100 0b00001001 RB2 toggled off 0046-usecs toggle[ 46] = 0b00000000 0b00001001 .... 0119-usecs toggle[ 119] = 0b00000000 0b00001001 0120-usecs toggle[ 120] = 0b00000001 0b00001000 RB0 toggled off 0121-usecs toggle[ 121] = 0b00000000 0b00001000 .... 1000-usecs toggle[1000] = 0b00000000 0b00001000 1001-usecs toggle[1001] = 0b00001000 0b00000000 RB3 toggled off ....
The advantage of using a "toggle" data array and XOR'ing the values with LATB over using an "output" data array and simply writing the values to LATB is that the "toggle" array only requires inserting eight "toggle" bits into the array. An "output" data array would require inserting many many "output" bits into the array.
The Do-While loop in the Output() routine compiles to the following 5-cycle instruction sequence (by the BoostC compiler) for perfect 1-usec intervals (with a 20-MHz clock);
In your program you would edit the pulse array values for the outputs and then call the PrepArray() routine to build the toggle array. Then I suspect you would wait for some "trigger" event before calling the Output() routine.Code:loop: movf _postinc0,W ; xorwf _latb,F ; btfss _fsr0h,3 ; bra loop ;
Any of this make sense Sir? I'm rather pressed for time and that tends to make my rushed explanations rather useless to most people. Sorry...
Regards, Mike
Last edited by Mike, K8LH; - 17th October 2009 at 02:04.
Reply to Dave:
Yup, that's what described.
The issue is that the three outputs will not always be ordered longest to shortest from bit 0 to bit 2 (or bit 2 to 0 as you ordered them). Not difficult to get around - just need to sort the pulse lengths, calculate the incremental time between sequential trailing edges and use a bunch of IF statements to pull them back down in the right order.
But woudn't it be nice if there was single command that could output parallel pulses
Andrew
Last edited by AndrewC; - 14th October 2009 at 10:59.
How are you going to input the parameters to the PIC?
Dave
Always wear safety glasses while programming.
That bit is easy![]()
In this kind of application I probably only need about a dozen discrete pulse lengths. I'll probably store them in an array and select the array member by scrolling through it with single button per output. Depending on the PIC I'll use I might have an "up" and "down" button. Each flash needs a fire and quench signal, so that is 6 pins, plus the buttons takes me up to 9 (or 12) plus a serial output for an LCD plus a synch signal from the camera.
Andrew
Bookmarks