N76E003 has two RC oscillators inside - 16M (HIRC) and 10K (LIRC). The high-speed 16MHz oscillator is factory calibrated to ±2% (over the full temperature and voltage range), while the 10K low-speed oscillator is said to have a 35% error. It is not surprising that a ten-minute extra error is not a surprise for an hour of timing.
The following code is from the official routine of Nuvoton. Its operating principle is to use HLRC & LIRC timers at the same time. Both are turned on at the same time. LIRC is set to a fixed time. After overflow, the HIRC count value is checked and the difference is calculated (the shorter the time, the more accurate it is) to calibrate LIRC.
But in actual testing, the effect is not ideal. It may be a problem with individual chips. I hope everyone can also test it.
//***********************************************************************************************************
// File Function: N76E003 wake up timer self calib demo code
//***********************************************************************************************************
#include #include "N76E003.h" #include "Define.h" #include "Common.h" #include "Delay.h" #include "SFR_Macro.h" #include "Function_define.h" #define TIMER_DIV12_VALUE_25_6ms 65536-34134 //34134*(12/16)=45000 us = 25.6 ms #define TIMER_DIV12_VALUE_45ms 65536-60000 //60000*(12/16)=45000 us = 45 ms // Timer divider = 12 #define TIMER_45MS_BEGIN 5536 #define TIMER_30MS 40000 //40000*(12/16)=30000 us = 30 ms #define TIMER_24MS 32000 //32000*(12/16)=24000 us = 24 ms /********************************************************************************** * FUNCTION_PURPOSE: Self-wake-up timer interrupt service routine **********************************************************************************/ void WakeUp_Timer_ISR (void) interrupt 17 //ISR for self wake-up timer { P12=~P12; //Flip pin // clr_TR0; //THReg = (TH0); // THReg = (THReg<<8)|TL0; // printf("n%x",THReg); clr_WKTF; //Clear interrupt flag } /********************************************************************************** * FUNCTION_PURPOSE: Set timer 0 to count to 45ms **********************************************************************************/ void Timer0_Delay45ms() { clr_T0M; //T0M=0, Timer0 Clock = Fsys/12 TMOD |= 0x01; //Timer0 is 16-bit mode //Trigger Timer0 TL0 = LOBYTE(TIMER_DIV12_VALUE_45ms); TH0 = HIBYTE(TIMER_DIV12_VALUE_45ms); // set_TR0; //THReg = (TH0); // THReg = (THReg<<8)|TL0; // printf("nbegin %x",THReg); } /********************************************************************************** * FUNCTION_PURPOSE: Start the self-wake-up timer and timer 0 to start counting at the same time **********************************************************************************/ void startCheck() { clr_WKTF; WKCON = 0x00; //timer base 10k, Pre-scale = 0, no frequency division, one clock 0.1 ms // RWK = 0XFF; // if prescale is 0x00, never set RWK = 0xff RWK = 0xF; //240 clocks 24 ms // set_EWKT; // enable WKT interrupt set_WKTR; // Wake-up timer run //EA =1; set_TR0; } /********************************************************************************** * FUNCTION_PURPOSE: calibration function Returns a ratio (the ratio of the actual count value of timer 0 to the theoretical count value) The 10K internal clock (self-wake-up timer) and the 16MHZ internal high-speed clock (timer 0) start counting at the same time Count for 20ms. When the self-wake-up timer stops, stop timer 0 and read the current count value of timer 0. Then use the actual running value of timer 0 divided by the value of the counter corresponding to 20ms. **********************************************************************************/ float HIRCCheck10KRC(void) { float temp,a,b; UINT16 THReg =0; Timer0_Delay45ms(); startCheck(); while(!(WKCON&0x10)); clr_TR0; clr_WKTF; THReg = (TH0); THReg = (THReg<<8)|TL0; a = THReg-TIMER_45MS_BEGIN; b = TIMER_24MS; temp = a/b; return temp; // printf("n%x",THReg); // printf("n%f",temp); } /********************************************************************************** * FUNCTION_PURPOSE: Test the self-wake-up timer count **********************************************************************************/ void testSelfWakeUPTimer(float scale) { UINT16 temp; temp = 200 /scale; WKCON = 0x00; //timer base 10k, Pre-scale = 0, no frequency division, one clock 0.1 ms // RWK = 0XFF; // if prescale is 0x00, never set RWK = 0xff RWK = 0XFF-temp; //200 clocks 20 ms // set_EWKT; // enable WKT interrupt set_WKTR; // Wake-up timer run //EA =1; while(!(WKCON&0x10)); clr_WKTF; P12=~P12; } /************************************************************************************************************ * Main function ********************************************************************************************************************/ void main (void) { float rScale; UINT8 iCount=0; Set_All_GPIO_Quasi_Mode; InitialUART0_Timer3(115200); // Timer0_Delay45ms(); rScale=HIRCCheck10KRC(); while(1) { rScale=HIRCCheck10KRC(); printf("n%f",rScale); Timer2_Delay1ms(100); for(iCount = 0;iCount<100;iCount++) { testSelfWakeUPTimer(rScale); testSelfWakeUPTimer(1); } } }
Previous article:Nuvoton M0 core. Use of TTL level and Schmitt level of the interface
Next article:N76E003 Timer 0 Usage
Recommended ReadingLatest update time:2024-11-15 09:19
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
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
- Detailed explanation of intelligent car body perception system
- How to solve the problem that the servo drive is not enabled
- Why does the servo drive not power on?
- What point should I connect to when the servo is turned on?
- How to turn on the internal enable of Panasonic servo drive?
- What is the rigidity setting of Panasonic servo drive?
- How to change the inertia ratio of Panasonic servo drive
- What is the inertia ratio of the servo motor?
- Is it better for the motor to have a large or small moment of inertia?
- What is the difference between low inertia and high inertia of servo motors?
- How can esp32 get the file information in the file system of the micropython task in another task?
- zstack protocol stack serial port problem
- [Summary of the shortlist] GigaDevice GD32L233 review event
- About Ingenic IP5328P
- [Silicon Labs BG22-EK4108A Bluetooth Development Review] 1. Unboxing
- Why is the output ripple of the circuit I designed so large?
- COCOFLY Tutorial - Crazy Shell Drone Series Quick Start [3] OPENMV Script Burning
- [Telink's new generation of low-power, high-performance, multi-protocol wireless kit B91 review] HomeAssistant+B91zigbee network access
- LOTO Lesson 1: RC Resistor-Capacitor Practice --- Low-Pass Filter PWM to DC
- After a busy year, I finally have a holiday.