Okay, so I'm trying to resurrect my long-deceased PIC skills. (I do a lot of C++ programming, off and on, but my last significant firmware was about 2000--the Footprints sensor, running on a PIC17C456.)
From last time, I remember that MCU programming is all about getting the configuration bits right--once that's done, it's pretty simple. Sooo, I'm trying something fairly simple to start with, namely controlling an RC airplane servo.
The servo needs 0.8-2.4 ms pulses, at a rep rate between 50 and 100 Hz. I'm using a PIC 18F46k20 demo board with a nice little OLED display, running at a clock frequency of 64 MHz (16 MHz instruction clock). The PWM is done with Timer 2 and capture/PWM module ECCP 1.
I started with demo program, which ran fine. Next I ported that to Hi-Tech C, which I remember very fondly from back when--it was pretty nearly bug-free, in stark contrast to Microchip's C17, which stank on ice. So far, so good.
I got the PWM working OK, but with a 64 MHz clock, the slowest rate the PWM can go is 4 kHz (10-bit resolution and 16x prescaler), which is too quick for the servos. Sooo, I used the TMR2 interrupt handler to implement a divide-by-64 counter. For N+M/1024 cycles, it turns ON the RD5 output when the down-count reaches N, and then switches to the PWM for cycle 0 only. That way, I could have N complete cycles and M/1024 partial cycles, yielding 15 bits resolution at a 61 Hz rep rate. Plenty good for an RC servo.
The 15 bits are made up of the number of full cycles (5 bits), bits 4 and 5 of the CCP1CON register, plus an 8-bit value in CCP1L. According to the datasheet, any time I'm using x256 division in TMR2, I should be getting 10 bits worth of resolution, but it's acting exactly as though I were getting only 8--changing the programmed delay produces 4 times more PWM duty cycle change than it should, and the two CCP1CON bits don't seem to do anything, though I can read and write them correctly.
The setup values are: T2CKPS0 = 0; T2CKPS1 = 1; //prescale by 16 PR2 = 0xFF; // divide by 256 DC1B1:DC1B0:CCPR1L = many values
This is almost certainly pilot error, but the reason doesn't exactly leap out of the 450-page datasheet.
C'mon, all you PIC guys--what gives?