11.3.4.1.1.1 OSC20M Stored Frequency Error Compensation
This oscillator can operate at multiple frequencies, selected by the value of the Frequency Select bits (FREQSEL) in the Oscillator Configuration fuse (FUSE.OSCCFG) at Reset. As previously mentioned appropriate calibration values are loaded to adjust to center frequency (OSC20M), and temperature drift compensation (TEMPCAL20M), meeting the specifications defined in the internal oscillator characteristics. For applications requiring wider operating range, the relative factory stored frequency error after calibrations can be used. The four errors are measured at different settings and are available in the signature row as signed byte values.
- SIGROW.OSC16ERR3V is the frequency error from 16 MHz measured at 3V
- SIGROW.OSC16ERR5V is the frequency error from 16 MHz measured at 5V
The error is stored as a compressed Q1.10 fixed point 8-bit value, in order not to lose resolution, where the MSB is the sign bit and the seven LSBs the lower bits of the Q1.10.
The minimum legal BAUD register value is 0x40, the target BAUD register value should therefore not be lower than 0x4A to ensure that the compensated BAUD value stays within the legal range, even for parts with negative compensation values. The example code below demonstrates how to apply this value for more accurate USART baud rate:
#include <assert.h> /* Baud rate compensated with factory stored frequency error */ /* Asynchronous communication without Auto-baud (Sync Field) */ /* 16MHz Clock, 3V and 600 BAUD */ int8_t sigrow_val = SIGROW.OSC16ERR3V; // read signed error int32_t baud_reg_val = 600; // ideal BAUD register value assert (baud_reg_val >= 0x4A); // Verify legal min BAUD register value with max neg comp baud_reg_val *= (1024 + sigrow_val); // sum resolution + error baud_reg_val /= 1024; // divide by resolution USART0.BAUD = (int16_t) baud_reg_val; // set adjusted baud rate