I took a 4Mhz crystal out of an old circuit and built the simplest thing I possibly could:
I’ve reconstructed that from memory, so it might not be completely right – but hopefully you get the picture. It’s using the crystal as a clock signal and an LED to indicate when RA1 is high. I haven’t used any pull-up resistors even though I know I should have (naughty).
I loaded this up with a very simple program (I’ve snipped out the boilerplate code from the MPLAB template file, see below for a full, updated file):
bsf STATUS,5 ; Switch to Bank 1 movlw 0x00 ; Make the Port A pins into outputs movwf TRISA bcf STATUS,5 ; Switch back to Bank 0 movlw 0x2 ; Turn on the LED: put 0x00010 into W movwf PORTA ; Turn on the LED: and then move W into port A
This worked first time, which was pretty excellent. So I decided to try and make the LED flash. I added some more code to turn the LED back off, and put a loop in between those calls to create a delay. Later, I added some more delay, and moved the loops into a subroutine. Here’s the full program.
Unfortunately, this didn’t work at all. I spent quite some time trying to debug the program, assuming that was at fault. I did find a couple of bugs, including one where I hadn’t disabled the AD convertor by putting 0x07 into ADCON1. This made me a bit suspicious that the LED lighting up the first time was a fluke, but I didn’t investigate.
After a while, I noticed that if I touched OSC1 with my finger, the circuit worked. And stopped working when I took my finger away. This made me suspicious that the clock signal was broken in some way. I thought I might have broken the crystal, so I tried to check it with my scope — I couldn’t see anything except noise, but that is perhaps to be expected.
I didn’t have another crystal, so I decided to replace it with an RC oscillator and see if that solved the problem:
I used this handy calculator to pick values for C and R — 33pF and 10K respectively. This does seem to be a different kind of oscillator but these values worked, so I wasn’t too worried.
As soon as I turned this on, it worked perfectly — hooray. The LED flashes quite quickly – at about 31Hz – which I learned how to calculate here. With the scope’s time/div set to 2ms, the on period and off period were both 8 divisions long, making a duty cycle of 16 divisons, or 32 ms. f = 1/T = 1/0.032 = 31.25Hz.
Using the same method, I tried to calculate the frequency of the oscillator — but its waveform is quite different from the LED output’s square wave, and certainly not a sine wave, and not exactly triangular either — as expected for a capacitor charging up, it curves:
The results of this calculation also differ quite a lot from the handy calculator above, so something’s obviously squiffy. Probably my maths. But anyway. The duty cycle is 4.5 divisions long with time/div set to 0.5µs, making it 2.25µs long. f = 1/T = 1/0.00000225 = 444444.4Hz = 444Khz — whereas the handy calculator says I should be getting 1694Khz.
I think I need a second pair of eyes, preferably in the head of someone who knows what they’re talking about.
Finally, I found — but ultimately didn’t use — this document from Microchip about common PIC problems. I think it might come in handy another day though.