View previous topic :: View next topic |
Author |
Message |
yadobaka
Joined: 25 Feb 2007 Posts: 4
|
Delay is consistently slightly off. There must be a reason |
Posted: Tue Feb 27, 2007 4:00 pm |
|
|
Hello all, this is my first post here!
I'm creating an electronic instrument using the PIC16F916 and square waves. Essentially it will output quasi-randomized notes in a user-selected key. I can't seem to output perfectly accurate tones. Below is the code I am using to make a 500 Hz signal. It is very close to what it should be, but it is a slightly lower frequency, which means delay is taking just a littttle bit longer than it should be taking. First thing I thought about was the time it takes to complete an instruction; maybe additional delay is being added due to the time it takes to process the code. This chip is only supposed to take 200 nanoseconds per instruction though and I doubt output_high and output_low take more than a few instructions. Second thing I've thought about are interrupt calls. The CCS help file says delay_ms doesn't account for any time spent in interrupts. I didn't specifically enable interrupts, but maybe output_high and output_low perform interrupt service routines? These are some of my thoughts on the issue, but I really can't explain it. Any ideas? I could just adjust for it by taking a few microseconds off the delays but I'd really like to figure out what's going on here.
Thanks!
Code: | #include <16F916.h>
#DEVICE ICD=TRUE
#USE delay(clock=4000000,int=4000000)
#use fast_io(B)
#FUSES NOWDT, NOPROTECT
void main(){
set_tris_b(0); //set port B to all outputs
while (TRUE) { //want to create a 500 Hz square wave. That means each period (cycle)
//should take 2 milliseconds to complete.
output_high(PIN_B7);
delay_ms(1); //here's the first millisecond delay of the cycle
output_low(PIN_B7);
delay_ms(1); //here's the second millisecond delay of the cycle
}
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Feb 27, 2007 4:04 pm |
|
|
With a 4 MHz clock, it's 1 microsecond per instruction cycle.
Some instructions take 2 cycles (and therefore 2 us).
Also, I noticed you're using the internal oscillator. The 16F916
data sheet says the best case accuracy is +/- 1%.
If you want full accuracy, you need a crystal. |
|
|
yadobaka
Joined: 25 Feb 2007 Posts: 4
|
|
Posted: Tue Feb 27, 2007 4:10 pm |
|
|
Thank you for the quick reply. Maybe the 200 ns/instruction I read was for the max clock speed. Also, I am unsure why I use 4 MHz for
Code: | #USE delay(clock=4000000,int=4000000) |
The max clock speed for the 16F916 is 20 MHz. I was under the impression that you're supposed to give delay the clock speed. When I gave it 20 MHz instead of 4 MHz my delays were super fast. I found the 4 MHz figure from some other examples which used the 16F916. I think I am missing something very fundamental here. Is this correct?
I suppose I should have assumed a variable clock will have slight inaccuracies. I think perhaps a small delay adjust will do just fine. Now I know why it didn't work!
Thanks much,
Kyle |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Feb 27, 2007 4:22 pm |
|
|
The "clock=4000000" setting is supposed to be the actual speed
that the PIC is running at.
If your PIC is configured to use the internal oscillator at 4 MHz,
then you set the "clock=" to 4 MHz.
The compiler calculates the software delay loops used in delay_ms()
by looking at this value. |
|
|
|