Tweaking a PIC

My project manager has a theory: "Take any $100,000 instrument. You can most probably emulate an important subset of its functionality with a PIC." And damn me if he's not right! The only problem is that you need some really tweaked software (or equivalently, some really tweaked programmers).

The good thing is that much of the software exists and is FREE! For example check out the ap-notes at Microchip . If you're just looking for a few ideas, then check out a small collection of routines that I've bit-butchered:

*** WARNING *** DANGER *** Isochronous Loops *** Muck with these at your peril, admonishes Alice Campbell.

a2d.asm - Here's a way to do a2d without an a2d converter. It uses a charge balancing scheme; a technique introduced to me by Walter Banks at Byte Craft. The version that Walter describes require two I/O pins; one configured as an input the other as an ouput:

                    +-----------> PIC (not used in 1-pin version)
Vin  o---/\/\/\---+-+-/\/\/\----< PIC

I also figured out a way to make it work with just one I/O pin too. The algorithm is extremely simple:

For my test, the two resistors were 10k and the capacitor was a 0.56uF mylar film. I didn't experiment much with these values, I basically took some stuff out of one my junk piles. I was able to fairly easily get 12-bits of dynamic range with the 2-I/O version and about 8 with the 1-I/O pin version.

pic_sin and sine18.asm Are 8-bit sine functions for the midrange and 18cxxx cores. These functions use a table look-up approach plus first order linear interpolation. The frequency arguement has a dynamic range of 14 bits (i.e. 360/2^14 = 0.02 degrees) making it really useful for phase locked loops. The program's comments explain the theory, but if that's not enough for you then check out the sine wave page. If you want a sine function that just uses a table look-up then check out Eric Smith (especially Implementing the Sine function on the PIC ).

twist.asm - Is a useful routine to mix two sine waves together. It implements the equation (A*x + B*y)/ 2^N where A and B, the coefficients, constrained to: A+B = 2^N. x & y don't have to two sine waves. The comments of twist.asm discuss a low pass filter that uses the same equation. Tony Kubek has written a twist24.asm version.

arcsine.asm - An 8-bit arcsine function. This function also uses a table look-up approach plus first order linear interpolation.

arctan.asm - An 8-bit arctan function. Yet another example of a table look-up approach plus first order linear interpolation to implement a trig function. This one also has the benefit of being either a single quadrant or a four-quadrant. The four-quadrant version implements a 'fractional division'; e.g. arctan(y/x).

CRC - Highly optimized CRC routines.

pic_sqrt - A square root algorithm that takes the square root of a 16-bit integer. This puppy has been tweaked! It's based on the binary square roots: the non-restoring method.

RAM: 3 bytes (Including the 2 that hold the 16-bit) input.

ROM: 30 words

Execution time: 100 cycles min, 122 cycles max, 105 cycles average.

sqrt18.asm - A 16-bit square root routine for the 18Cxxx family. There are two routines here. One is a looped one similar to the square root routine for the 16C/Fxx but optimized for the 18F's instruction set. It has a best case excution time of 68 cycles and worst case of 108 cycles and uses only 25 words. The other is an unrolled version that executes between 55 and 69 cycles.

pic_log - An 8-bit logarithm program for the PIC.

RAM: 5 bytes

ROM: 58 words

Execution time: 18 cycles min, 102 cycles max.

pic_parity - Here are four different ways to count the number of ones in an 8-bit binary number. Take your pic, I mean pick.

pic_debounce - Here's a routine that's designed to simultaneously debounce 8 inputs. I've used it in conjunction with a keyboard scanning routine and also as a generic parallel digital input port. It's currently set up such that four consecutive samples at the same logic level are required for the filter outputs to change states. BTW, there are no gotos and no counters.

RAM: 4 bytes (3 permanent, 1 temporary)

ROM: 14 words

Execution time: 15 cycles

Vertical Counters - Here's a collection of vertical counters implemented on a PIC. Vertical counters provide an efficient way to simultaneously count up to eight different items. One of these is used in the pic_debounce routine.

Miscellaneous Stuff:

Here's a collection of stuff that myself and others have created:

BCD - Here's a routine written by John Payson that is optimized to convert a 16-bit binary number into 5 BCD digits. Like most of the John writes, this is bizarre, interesting, and extremely fast.

PWM - 32 and PWM - 256 are software PWM generators that have single instruction cycle resolution. The 32-level pwm routine is really intended for fixed pwm duty cycles. This is mainly because it's not possible to maintain single cycle resolution and simultaneously smoothly vary the duty cycle. Well, okay, maybe it's possible. However this routine also provides the application with about 15 free instruction cycles per pwm cycle. The 256-level routine can accomodate smoothly varying duty cycles and still maintain the single cycle resolution. Again, about half of the instruction cycles in one pwm cycle are available for your application. One other point; these routines do not require interrupts either and thus making them suitable for the 12-bit PIC cores (e.g. PIC16C54 or PIC12C508).

pwm8.asm is a software pwm routine for simultaneously generating 8 synchronized pwm outputs. One iteration through the algorithm takes 23 cycles (excluding the return) or 25 cycles if you want to make it a loop. On a 20Mhz pic this would translate to an output frequency of 781.25 Hz; on a 100Mhz Sceniz this would be 15.6 kHz.

Vertical Adders Here's an 8-cycle vertical adder that I wrote a while back. Dmitry Kiryashov, another PIC optimizer, found a way to decimate this to 6 cycles. I think this is as fast as possible with a PIC. But out of uncertainty I wrote two programs: va_optimizer.c and va_optimizer2.c that exhaustively search all possible instruction combinations (from a set of 32 different operations - not to be confused with 32 different instructions; i.e. movf r,w is considered a different operation than movf r,f even though they're the same instruction.

va_optimizer3.c is the latest in this series. The newest feature is that it's commented!


gpasm - A (primarily) linux based assembler for the PIC Microntrollers.

gpsim - A (primarily) linux based simulator for the PIC Microntrollers.


This page is maintained by Scott Dattalo. You can reach me at: .
Visitor 24039
Last modified on 23JUN03