However, due to the large discreteness of the resistors and capacitors in the RC oscillator, there is a calibration register called OSCCAL in the internal RAM of the microcontroller with an internal RC oscillator, which can be used to fine-tune the oscillation frequency of the RC oscillator by entering different values. In addition, there is a special word in the program memory of the microcontroller to store the calibration value measured during factory production. Below I will use the commonly used 12C508A and 12F629 as examples to illustrate.
The reset vector of 12C508A is the highest word of the program 0x1FF. This byte has been fixed by the manufacturer as MOVLW 0xXX. After the instruction is executed, the calibration value XX is in the W register. When we need to calibrate, then the next address 0x0 should be an instruction like this: MOVWF OSCCAL. Then the RC oscillator will run at the standard oscillation frequency.
The calibration value of 12F629 is also stored in the highest word - 0x3FF, the content is RETLW 0xXX, but its reset vector is 0x0. So, when we need to calibrate the RC oscillator, we need to add the following two sentences during the initialization process:
CALL 0x3ff
MOVWF OSCCAL
Of course, you also have to pay attention to the block select bits of the register.
In the past, when I was working on a project, I didn't pay much attention to this problem. This is because when using 12C508A, HI-TECH has secretly done this work for us during compilation. It will automatically add a MOVWF OSCCAL at 0x0 of the program. There was no problem when using 12F629 to replace 2272 for receiving decoding, but when using it as a rolling code decoder, it was found that the receiving distance was very discrete. After many tests, I finally found that the oscillation frequency of the oscillator was not calibrated.
Therefore, it is necessary to write additional statements for correction. I used two methods to achieve this goal:
1. Use inline assembly
#asm //This assembly program is used to
put the calibration value of the internal RC oscillator //at call 3ffh in the program segment 3FFH into the calibration register,
bsf _STATUS,5 //This program should be shielded when debugging in C language
movwf _OSCCAL
#endasm
2. Use the standard form of C language
const unsigned char cs @ 0x3ff; //Outside the function
...
OSCCAL=cs; //Shield this sentence during simulation
Both methods have a small flaw - the program cannot run during simulation, because the C compiler does not place a RETLW 0xXX statement at 0x3FF for us. Therefore, after the program runs to this point, it does not put a constant (calibration value) into the W register and then return, but continues to execute the next statement of this statement - 0x0 and the program after it, which means that the program is messed up here. Therefore, as shown in the comments behind the program, these sentences should be blocked during simulation. After the program is debugged, when it needs to be burned, remove the comment symbol and compile it again.
I have another idea, which is to use functions instead of shielding statements. That is, to create a function starting at 0x3FF, with only one statement in the function body, as follows:
char jz()
{
return 0;
}
Of course, we also need to consider that when a C function returns, register 0 will be selected. In fact, the starting address of this function should be less than 0x3FF. However, I have searched all the reference materials I can find and searched the Internet many times, but I still can't find a way to absolutely locate the function. I hope friends who know can give me some advice.
Also, 12C508A is a one-time programmable device, and the content at 0x1FF cannot be changed. That is to say, if you write any instructions here, the programmer will not burn it for you, or even if it is burned, it will not change the content.
However, 12F629 is a FLASH device and can be programmed multiple times. If you do not intentionally select it, the genuine programmer (such as Microchip's PICSTART PLUS) will not program the program space where the calibration value is stored. Even if you accidentally program this program space, you can use a RETLW 0xXX to put it at 0x3FF and program it again, but this XX value may be incorrect and needs to be determined by experiment (please refer to the following instructions).
In order to test the effect of OSCCAL value on oscillator frequency, a small program is written to verify:
#include
//************************************************************
__CONFIG(INTIO & WDTDIS & PWRTEN & MCLRDIS & BOREN & PROTECT & CPD);
//Internal RC oscillator common IO port; invalid watchdog; power-on delay; internal reset; power-off reset; code protection; data protection
//****************************************************************
#define out GPIO0 //Define output terminal
#define jc GPIO3 //Define detection terminal
//****************************************************************
void interrupt zd(); //Declare interrupt function
//Main function*******************************************************
void main()
{
CMCON=7;
OPTION=0B00000011; //Division ratio is 1:16,
TRISIO=0B11111110;
GPIO=0B00000000;
WPU=0;
T0IF=0;
GIE=1;
T0IE=1;
while(1){
if(jc)OSCCAL=0xFF;
else OSCCAL=0;
}
}
//Interrupt function******************************************************
void interrupt zd()
{
T0IF=0;
out=!out;
}
The program is actually very simple. It is to flip the level of the OUT pin in the interrupt. The flipping time is 4096 instruction cycles, and the level cycle is 8192 instruction cycles. The instruction cycle is determined by the RC clock frequency. In the main program, the level of the JC port is constantly detected, and then the value of the OSCCAL register is modified according to the value of the port level. Of course, the change of the value of the OSCCAL register is reflected in the waveform cycle of the OUT pin.
After measuring with an oscilloscope (sorry, I don't have a frequency meter at hand), when the JC terminal is grounded, the level cycle of the OUT terminal is about 9.5 milliseconds; and when the JC terminal is connected to the positive power supply, the level cycle of the OUT terminal is about 6 milliseconds. That is to say, the larger the value of OSCCAL, the higher the clock frequency of the microcontroller. In addition, this range of variation is very large. Therefore, if the internal RC oscillator of the PIC microcontroller is used, it is very necessary to correct its oscillation frequency. This is also the reason why the product discreteness is very large when I make a rolling code receiving decoder. I hope everyone can pay attention to this point when using the internal RC oscillator in the future.
Previous article:PIC18F97J60 TCP/IP reconnection problem after changing IP
Next article:Issues that must be noted when using PIC microcontroller port level change interrupts
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Huawei's Strategic Department Director Gai Gang: The cumulative installed base of open source Euler operating system exceeds 10 million sets
- Download from the Internet--ARM Getting Started Notes
- Learn ARM development(22)
- Learn ARM development(21)
- Learn ARM development(20)
- Learn ARM development(19)
- Learn ARM development(14)
- Learn ARM development(15)
- Analysis of the application of several common contact parts in high-voltage connectors of new energy vehicles
- Wiring harness durability test and contact voltage drop test method
- User feedback post
- "Operational Amplifier Parameter Analysis and LTspice Application Simulation" Reading Notes: Chapter 1 Operational Amplifier Basics
- How UBOOT boots the Linux kernel and passes parameters to the kernel
- μC/OS embedded real-time operating system releases new open source version
- STEVAL-MKI109V3+ Test Basics
- Is there a “great theorist” around you?
- Built-in numeric keyboard to input numeric variable values
- Summary of crystal oscillator problems
- Unboxing of Materials - STM32F7508 & ESP32
- Gigabit Network Contactless Connector-SK202 Evaluation 4: Strict Test Conditions, Reliable Test Data