Ever try to measure the Crystal frequency of your MCU clock? Its hard to do without high-end gear. But using an Arduino Timer, we can get a seriously close idea. And RTM_TimerCalc makes it a breeze to set up.
For your convenience, the sketch code is included below.
Arduino Timer Setup
You need to have a decent Frequency Counter or Oscilloscope with a built-in Frequency Counter. You also need an MCU board like a Nano, Uno or Mega2560. With those two requirements filled, we can move forward.
Using RTM_TimerCalc, we then;
- Select an Internal Clock of 16 MHz.
- Choose Timer1
- Select Fast-PWM mode.
- Enter a desired output Frequency of 1,000,000 Hz.
Press the Calculate button and copy the resulting code into your IDE. Be sure you un-comment the appropriate pinMode lines depending on which board you chose to use. Compile and Upload to your Arduino.
Here's a snapshot of what you should see
Getting the Answer
Next take your Scope or Counter probes and connect to one of the PWM pins you chose. You should see a frequency reading very close to 1 MHz plus-or-minus some amount of error.
Write down the number shown. Multiply it by 16. The resulting number indicates where your MCU clock frequency is actually running!
So why divide it in the first place you might ask. Well, because of how the hardware is set up. Trying to measure the crystal directly will throw it off due to added loading from the Counter probe. The direct-connect measurement is misleading since it indicates a value far from the true frequency.
But by using the Arduino Timer to divide by 16, we get a useful sample of the oscillator without loading it down. Since the Timer output is divided by 16, we just multiply by 16 to get the actual value. That reveals the true frequency with a very high confidence factor!
You can take your calculated Crystal Frequency and compare it to the number 16 MHz. Just subtract the smaller of the two numbers from the larger and you have your error as an integer. Divide by 16,000,000 to get the actual error as a proportion. Multiply the proportion by 100 to get error in per-cent. Let's do an example.
Here's a snapshot of my scope using a 2560 to run this code. I was on pin-12, 50% duty cycle.
The above scope snap shows a frequency of 1.00029 MHZ. Multiplied by 16 gives us a Clock frequency of 16.00464 MHz.
If I subtract that from 16.00000 MHz, I get 4,640 Hz error. Then I divide 4,640 by 16,000,000 to get .00029. Multiply by 100 to express the error as a percent and we get .029% error.
Clock Crystal Error Checking Code
Here's the Arduino Timer code we used. Its ready to run on a Nano, Uno or Mega2560. Just copy and paste into the Setup() section of your sketch. Be sure to un-comment the appropriate pinMode lines for your particular Arduino MCU!
generated by: RTM_TimerCalc -- RuntimeMicro.com // Timer1 Mode_14_16Bit_Fast_TOP_is_ICR TCCR1A = 0xA2; // 1010 0010 TCCR1B = 0x18 | 1; // Prescale=1 ICR1 = 16-1; OCR1A = (int) (ICR1 * 0.25); OCR1B = (int) (ICR1 * 0.5); // UnComment following lines for UNO-NANO Timer-1 Pins // pinMode(9, OUTPUT); // OC1a // pinMode(10, OUTPUT); // OC1b // UnComment following lines for 2560 Timer-1 Pins // pinMode(11, OUTPUT); // OC1a // pinMode(12, OUTPUT); // OC1b
If you disagree with my math, please leave a comment and let me know.
Thanks.
Lee
Created: Jan 3, 2020 Updated: Jan 11, 2024 |