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"); } }