Search This Blog

Sunday, July 29, 2012

Programming PIC 18F in C

   I've been playing around with MPLAB X lately.  It's still quite buggy, but I love the convenience of an IDE that manages my code, lets me version the software, program the devices, step debug, etc.  It's a shame they chose NetBeans instead of Eclipse.  Regardless, some new learnings were in the offing.  I wrote some programs in C with Microchips C18 compiler.  I learned how to program the chips for In Circuit Debugging (ICD ) with the PicKit2.  Wow! It is definitely cool to be able to step debug on the actual circuit.

   Not much to show for this first foray.  I redid an old routine that reads from the ADC on AN0 and pushes the value onto an LCD screen.  The set up and whatnot is the same as posted in earlier blogs.  The difference was porting the whole thing to C.  The config fuses are set in an include file to get them out of the way.  Here it is:

configFuses.h

   The source code is fairly compact:

adc_lcd.c


   Next up is a hybrid C and assembly program that I've been wanting to do.  It reads an analog value from AN0.  I took advantage of C to divide the value by 6 and add one.  This result is fed to a servo value.  The servo is driven by chained interrupts on timers 0 and 1.  Timer 0 acts as the controller and interrupts on the period ( 50 Hz or 20ms ).  On interrupt, it resets itself and starts timer 1 for the first .65 ms of the duty cycle.  It turns on all servos ( in this case only one ).  The timer 1 interrupt handles the remaining 1.35 ms of the duty cycle.  It sets itself to interrupt every 7.4 us for 180 times.  This means that the servos will have a resolution of 180 degrees.

   The interrupts are all written in assembly.  While they could have been done in C for one servo, this code wants to evolve to control 16 or 17 servos at a time.  Each will have an independent value.  To control the 18 or more servos for a hexapod, the timings will have to adjust to a PLL driven clock at 48 MHz.  That buys 160 instructions per "degree" of resolution to work with ( as opposed to the 40 instructions available at 20 MHz ).

   The assembly portion is rammed into the code inline.  This led to some interesting knowledge.  The program employs a lot of #define statements to make the code more readable and adjustable.  All of the delays and interrupt timings are done by define.  It should be a simple matter to adjust them to 48 MHz.  For the assembly, the pins needed to be defined as well.  They could not use the definitions from the chip's include file.  As a part of changing the timings for 48 MHz, the assembly will be placed in its own .asm file and linked in.  That should simplify things.

   The same configFuses.h file was used as above.  One thing to note:  The MCLR is ON in this file.  This allows debugging the program in circuit.  It also means a 10k resistor needs to be connected to RE3.

   Here is the code for the servo tester as it stands now: adc_servo.c

   That's all for now!