N76E003 calibrated 10Khz low speed oscillator

Publisher:龙腾少年Latest update time:2022-07-06 Source: csdnKeywords:N76E003 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

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

                }

        }


}

Keywords:N76E003 Reference address:N76E003 calibrated 10Khz low speed oscillator

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

N76E003 PWM interrupt and setting new duty cycle
First, let's take a look at the PWM interrupt register and its meaning. The PWM module has a flag bit PWMF (PWMCON0.5) to mark the completion status of the current PWM cycle. PWMF can be cleared by software. Don't forget to enable PWM interrupt and turn on the general interrupt. Let's take a look at the interrup
[Microcontroller]
N76E003 PWM interrupt and setting new duty cycle
N76E003 BMP180
BMP180.C File #include "N76E003.h" #include "Common.h" #include "Delay.h" #include "SFR_Macro.h" #include "Function_define.h" #include "bmp180.h" #include  math.h     //Keil library   #include  stdlib.h   //Keil library   #include  stdio.h    //Keil library #include  INTRINS.H //Keil library  #define   uchar
[Microcontroller]
N76E003 BMP180
N76E003 HMC5883
HMC5883.c #include "N76E003.h" #include "Common.h" #include "Delay.h" #include "SFR_Macro.h" #include "Function_define.h" #include "HMC5883.h" #include  math.h     //Keil library   #include  stdlib.h   //Keil library   #include  stdio.h    //Keil library #include  INTRINS.H //Keil library  #define   uchar u
[Microcontroller]
N76E003 HMC5883
10kHz Oscillator Circuit Diagram
10kHz Oscillator Circuit Diagram
[Analog Electronics]
10kHz Oscillator Circuit Diagram
Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号