Frequency regulation of IRC internal oscillation source of stc8a, stc8g and stc8h series

Since STC15, macro crystal has gone further and further on the road of built-in RC oscillation source (built-in clock, macro crystal called IRC) The STC15 generation is only "yes", and the accuracy and drift are not satisfactory Since STC8, IRC adjustment has become more and more complex. From one frequency band of STC8A/8F to two frequency bands of STC8G/STC8H, to four frequency bands of STC8A8K64D4, from CODE preset to XDATA read-only preset, the availability is also improving

Here is the IRC setting of STC8 series

Internal clock mechanism of STC8A/STC8F

There is only one IRC band with a frequency range of 16-27MHz. The internal clock rtrim and lirtim are adjusted through two registers and used as the system clock SYSCLK after frequency division through CLKDIV

details

  • For clock calibration during STC-ISP writing, in addition to changing the preset value of IRTRIM, the preset value of clkdiv (clock frequency division coefficient) may also be modified
  • For the preset frequency in STC-ISP, 18MHz-27MHz is not divided (CLKDIV is 0), and the lower frequency will start to change CLKDIV
  • In the code, IRTRIM is assigned with a preset value, and CLKDIV=0 is set to switch the clock to these two frequencies
    • Due to factors such as environment and aging, the frequency generated by the factory calibrated value will drift. If recalibrated, it may be near ± 2 of this value. It is sufficient to use the preset value for communication such as UART
  • IRTRIM values corresponding to 22.1184MHz and 24MHz frequencies calibrated at the factory are built in the chip, which can be read from FLASH and RAM, but this is only limited to burning with STC-ISP and checking the corresponding option
  • Preset values of FLASH part: 22.1184MHz and 24MHz addresses are 0xFDF4 and 0xFDF3 respectively. These addresses are located in code and accessed in the form of * (char code *)0xfdf3
    • When STC-ISP writes each time (note that it is each time), it must check "add important test parameters at the end of the program area" before writing to this part of the address, otherwise the values of this part of the address are all 0xFF
  • Preset values of RAM: 22.1184MHz and 24MHz addresses are 0xFA and 0xFB respectively. These addresses are located in idata and accessed in the form of * (unsigned char idata *) 0xFB
    • These two values have nothing to do with other factors. They can be read when powered on. Compared with the preset value of FLASH, they are more reliable, but they are only limited to programs written through STC-ISP and programs written through stcgal. The values of these two addresses are 0

Calibration of irtrim and lirtim in Linux Environment

If STC-ISP cannot be used for development under Linux, the above methods are invalid and shall be calibrated by auxiliary means

  • Method 1: traverse the entire [0255] interval for ITRIM and L through the program to determine the center point to obtain the rough IRTRIM value
  • Mode 2: equipment, oscilloscope or logic analyzer

Realization idea

  • The preset system clock is 22.1184MHz and the UART baud rate is 115200
  • The code initializes the serial port and timer according to the above conditions
  • Press IRTRIM from [0,255], lirtim from [0,3], and UART outputs a fixed string
  • When the actual clock of the system is close to 22.1184MHz, the receiver can see the correct characters, and what it sees at other times is garbled code
    • Take the center point of the part with normal reception as the IRTRIM and LIRTRIM values of 22.1184MHz
  • If an oscilloscope or logic analyzer is used, the clock can be output in 10 or 20 frequency division. Observe the waveform width during the process and record the IRTRIM and LIRTRIM when the output width is the closest

STC8G clock

STC8G has two built-in oscillation source frequency bands: 20MHz and 33MHz, which can cover 36.864MHz from 20MHz,

Because there are multiple frequency bands, two more registers are used for frequency band switching

  • IRCBAND: used to select frequency band
  • VRTRIM: used to set the voltage of the corresponding frequency band

When setting the frequency, the four registers ircband, vrtrim, irtrim and lirtrim will be involved, which will affect the frequency, and the adjustment degree decreases from left to right

An example

ADDR: 0x1FE9
       VER1     VER2
VRTRIM 35M      40M:      20
VRTRIM 20M      24M:      1F
ITRIM  ---      48M:      FF
ITRIM  ---      44.2368M: D0
ITRIM 36.864M   40M:      A3
ITRIM 35M       36.864M:  88
ITRIM 33.1776M  35M:      6F
ITRIM 30M       33.1776M: 43
ITRIM 27M       30M:      1A
ITRIM 20M       27M:      63
ITRIM 24M       24M:      BA
ITRIM 22.1184M  22.1184M: 90
32kHz PD FreQ:            8DCC
1.19Vref:                 04A9

MCUID: F7 A4 C4 0D 11 E0 EE 
Current VRTRIM:20, IRTRIM:A3, LIRTRIM:03

STC8H clock

STC8H should distinguish two different series

STC8H1K

There are two built-in oscillation source frequency bands, 20MHz and 35MHz, which are preset by stc-isp. The right column is the measured data of the chip

ADDR: 0x1FE9
       VER1     VER2
VRTRIM 35M      40M:      1F
VRTRIM 20M      24M:      1E
ITRIM  ---      48M:      FF
ITRIM  ---      44.2368M: E4
ITRIM 36.864M   40M:      B5
ITRIM 35M       36.864M:  9A
ITRIM 33.1776M  35M:      7E
ITRIM 30M       33.1776M: 51
ITRIM 27M       30M:      26
ITRIM 20M       27M:      73
ITRIM 24M       24M:      D0
ITRIM 22.1184M  22.1184M: A4
32kHz PD FreQ:            8A48
1.19Vref:                 04AA

MCUID: F7 34 C5 68 00 11 22 
Current VRTRIM:1F, IRTRIM:B7, LIRTRIM:03

STC8H3K

Here is the inconsistency with the manual. For stc8h3k32s2, f / W version: 7.4 1U actually has four frequency bands, that is, the IRCBAND values are 0x00 - 0x03, 24MHz and 40MHz, which belong to 0x02 and 0x03. The preset register should be read two bytes in advance from 0x7FE7. This is correct. It took half a day to study this problem It's a shame that the manuals are inconsistent

ADDR: 0x7FE7
       VER1     VER2
VRTRIM          40M:      19
VRTRIM          24M:      1C
VRTRIM 35M      ??M:      20
VRTRIM 20M      ??M:      1E
ITRIM  ---      45M:      7C
ITRIM  ---      40M:      47
ITRIM 36.864M:            2D
ITRIM 35M:                12
ITRIM 33.1776M:           FF
ITRIM 30M:                D2
ITRIM 27M:                98
ITRIM 20M:                1A
ITRIM 24M:                64
ITRIM 22.1184M:           41
32kHz PD FreQ:            8D04
1.19Vref:                 04A3

MCUID: F7 4A C5 26 03 11 22 
Current IRCBAND:03, VRTRIM:19, IRTRIM:2D, LIRTRIM:00

When setting, if the high frequency band (35MHz or 40MHz) is selected, itrim cannot be set too high. If it is set too high (more than 0xE0), the chip will not start

STC8A8K64D4 clock

The built-in clock on STC8A8K64D4 has been increased to four frequency bands: 6m, 10m, 27m and 44m. This model seems to be more like an enhanced version of STC8H3K The corresponding calibration also increases these frequency bands

The use mode is consistent with STC8H3K of four IRC bands, and the frequency is adjusted through four registers: ircband, vrtrim, irtrim and lirtrim

summary

Make a note to avoid others stepping on the pit, because there is basically no in-depth information on the Internet, and there is so much difference between the same series (STC8H1K and STC8H3K, STC8A8K64S4 and STC8A8K64D4), so it will be wrong to make it clear

For those developed under Linux, it is recommended to burn once through STC-ISP under Windows to obtain the preset calibration value of the chip, so that the frequency can be assigned and set directly in the code in the future

Read the code of each preset value

INTERRUPT(tm0isr, 1)
{
    uint8_t i, j;
    counter++;
    if (counter == 1000)
    {
        i = 0;
        counter = 0;
        UTIL_PrintString("ADDR: 0x");
        UTIL_PrintHex(__CID_ADDR >> 8);
        UTIL_PrintHex(__CID_ADDR & 0xFF);
        UTIL_PrintString("\r\n");
        UTIL_PrintString("       VER1     VER2\r\n");
        UTIL_PrintString("VRTRIM          40M:      ");
        UTIL_PrintHex(readCode(i++));
        UTIL_PrintString("\r\n");
        UTIL_PrintString("VRTRIM          24M:      ");
        UTIL_PrintHex(readCode(i++));
        UTIL_PrintString("\r\n");
        UTIL_PrintString("VRTRIM 35M      ??M:      ");
        UTIL_PrintHex(readCode(i++));
        UTIL_PrintString("\r\n");
        UTIL_PrintString("VRTRIM 20M      ??M:      ");
        UTIL_PrintHex(readCode(i++));
        UTIL_PrintString("\r\n");
        UTIL_PrintString("ITRIM  ---      45M:      ");
        UTIL_PrintHex(readCode(i++));
        UTIL_PrintString("\r\n");
        UTIL_PrintString("ITRIM  ---      40M:      ");
        UTIL_PrintHex(readCode(i++));
        UTIL_PrintString("\r\n");
        UTIL_PrintString("ITRIM 36.864M:            ");
        UTIL_PrintHex(readCode(i++));
        UTIL_PrintString("\r\n");
        UTIL_PrintString("ITRIM 35M:                ");
        UTIL_PrintHex(readCode(i++));
        UTIL_PrintString("\r\n");
        UTIL_PrintString("ITRIM 33.1776M:           ");
        UTIL_PrintHex(readCode(i++));
        UTIL_PrintString("\r\n");
        UTIL_PrintString("ITRIM 30M:                ");
        UTIL_PrintHex(readCode(i++));
        UTIL_PrintString("\r\n");
        UTIL_PrintString("ITRIM 27M:                ");
        UTIL_PrintHex(readCode(i++));
        UTIL_PrintString("\r\n");
        UTIL_PrintString("ITRIM 20M:                ");
        UTIL_PrintHex(readCode(i++));
        UTIL_PrintString("\r\n");
        UTIL_PrintString("ITRIM 24M:                ");
        UTIL_PrintHex(readCode(i++));
        UTIL_PrintString("\r\n");
        UTIL_PrintString("ITRIM 22.1184M:           ");
        UTIL_PrintHex(readCode(i++));
        UTIL_PrintString("\r\n");
        UTIL_PrintString("32kHz PD FreQ:            ");
        UTIL_PrintHex(readCode(i++));
        UTIL_PrintHex(readCode(i++));
        UTIL_PrintString("\r\n");
        UTIL_PrintString("1.19Vref:                 ");
        UTIL_PrintHex(readCode(i++));
        UTIL_PrintHex(readCode(i++));
        UTIL_PrintString("\r\n");
        UTIL_PrintString("\r\n");
        UTIL_PrintString("MCUID: ");
        for (j = 0; j < 7; j++)
        {
            UTIL_PrintHex(readCode(i+j));
            UTIL_PrintChar(' ');
        }
        UTIL_PrintString("\r\n");
        UTIL_PrintString("Current IRCBAND:");
        UTIL_PrintHex(IRCBAND);
        UTIL_PrintString(", VRTRIM:");
        UTIL_PrintHex(VRTRIM);
        UTIL_PrintString(", IRTRIM:");
        UTIL_PrintHex(IRTRIM);
        UTIL_PrintString(", LIRTRIM:");
        UTIL_PrintHex(LIRTRIM);
        UTIL_PrintString("\r\n\r\n");
    }
}

Added by xsgatour on Mon, 03 Jan 2022 14:29:54 +0200