[DemoCode下载] N76E003 HIRC 校准 LIRC 参考代码

[复制链接]
2883|6
 楼主| MLI_William 发表于 2017-2-20 17:10 | 显示全部楼层 |阅读模式
[BSP版本]
N76E003_SampleCode_Keil_C51_V0.07
[案例名称]
HIRC_Calib_LIRC.uvproj
[代码说明]


目前有些应用,需要使用内部10K时钟作为定时器来使用,但该时钟全温下偏差比较大。而N76E003的内部高速震荡器精度比较高。所以可使用HIRC来校准LIRC。
N76E003震荡器精度为:
HIRC 全温下误差2%
LIRC  全温下误差35%

该参考代码的原理是:
使用10K内部时钟(自唤醒定时器)和16MHZ 内部高速时钟(定时器0) 同时开始计数
自唤醒定时器设定计数20ms,当自唤醒定时器溢出时,再去停止定时器0,读取当前定时器0的计数值。
然后使用定时器0计数值除以20ms对应计数器的理论值。就可以得到一个比例系数。
当这个系数大于1时,说明LIRC比实际跑得慢。反之跑得快。

在实际应用中,可以用理论计数周期值除以该系数,得到实际要跑计数周期。
详细应用参考Sample Code.

/************************************************************************************************************
*    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);
                }
        }

}
 楼主| MLI_William 发表于 2017-2-20 17:14 | 显示全部楼层
附件是参考代码和应用说明。

[N76E003][LIRC]HIRC_Calib_LIRC.zip

457.36 KB, 下载次数: 39

稳稳の幸福 发表于 2017-2-20 18:56 | 显示全部楼层
使用10K内部时钟(自唤醒定时器)和16MHZ 内部高速时钟(定时器0) 同时开始计数
643757107 发表于 2017-2-20 19:09 | 显示全部楼层
  1. /*---------------------------------------------------------------------------------------------------------*/
  2. /*                                                                                                         */
  3. /* Copyright(c) 2016 Nuvoton Technology Corp. All rights reserved.                                         */
  4. /*                                                                                                         */
  5. /*---------------------------------------------------------------------------------------------------------*/

  6. //***********************************************************************************************************
  7. //  Nuvoton Technoledge Corp.
  8. //  Website: http://www.nuvoton.com
  9. //  E-Mail : MicroC-8bit@nuvoton.com
  10. //  Date   : 2/20/2017
  11. //***********************************************************************************************************

  12. //***********************************************************************************************************
  13. //  File Function: N76E003 wake up timer self calib demo code
  14. //***********************************************************************************************************

  15. #include <stdio.h>
  16. #include "N76E003.h"
  17. #include "Define.h"
  18. #include "Common.h"
  19. #include "Delay.h"
  20. #include "SFR_Macro.h"
  21. #include "Function_define.h"


  22. #define TIMER_DIV12_VALUE_25_6ms                65536-34134                        //34134*(12/16)=45000 us = 25.6 ms
  23. #define TIMER_DIV12_VALUE_45ms                        65536-60000                        //60000*(12/16)=45000 us = 45 ms                 // Timer divider = 12
  24. #define TIMER_45MS_BEGIN  5536                  
  25. #define TIMER_30MS         40000                                                                    //40000*(12/16)=30000 us = 30 ms
  26. #define TIMER_24MS         32000                                                                        //32000*(12/16)=24000 us = 24 ms

  27. /******************************************************************************
  28. * FUNCTION_PURPOSE: 自唤醒定时器定时中断
  29. ******************************************************************************/
  30. void WakeUp_Timer_ISR (void)   interrupt 17     //ISR for self wake-up timer
  31. {
  32.          P12=~P12;
  33. //   clr_TR0;
  34. //         THReg = (TH0);
  35. //         THReg = (THReg<<8)|TL0;
  36. //         printf("\n%x",THReg);
  37.          clr_WKTF;                                               //clear interrupt flag   
  38. }

  39. /******************************************************************************
  40. * FUNCTION_PURPOSE: 设定定时器0计数45ms
  41. ******************************************************************************/
  42. void Timer0_Delay45ms()
  43. {
  44.     clr_T0M;                                //T0M=0, Timer0 Clock = Fsys/12
  45.     TMOD |= 0x01;                           //Timer0 is 16-bit mode
  46.                                             //Trigger Timer0
  47.     TL0 = LOBYTE(TIMER_DIV12_VALUE_45ms);        
  48.     TH0 = HIBYTE(TIMER_DIV12_VALUE_45ms);
  49. //        set_TR0;
  50. //        THReg = (TH0);
  51. //        THReg = (THReg<<8)|TL0;
  52. //        printf("\nbegin %x",THReg);

  53. }

  54. /******************************************************************************
  55. * FUNCTION_PURPOSE: 启动自唤醒定时器和定时器0同时开始计数
  56. ******************************************************************************/
  57. void startCheck()
  58. {
  59.     clr_WKTF;
  60.         WKCON = 0x00;                                                                                 //timer base 10k, Pre-scale = 0, 不除频,一个时钟0.1 ms
  61. //        RWK = 0XFF;                                                                                        //        if prescale is 0x00, never set RWK = 0xff
  62.         RWK = 0xF;                                                                                        //240 个时钟          24 ms
  63. //  set_EWKT;                                                                                        // enable WKT interrupt
  64.         set_WKTR;                                                                                         // Wake-up timer run
  65. //        EA =1;
  66.     set_TR0;
  67. }


  68. /******************************************************************************
  69. * FUNCTION_PURPOSE: 校准函数
  70. 返回一个比值(实际定时器0跑的计数值与理论计数值的比值)

  71. 10K内部时钟(自唤醒定时器)和16MHZ 内部高速时钟(定时器0) 同时开始计数
  72. 计数20ms,当自唤醒定时器停止时,再去停止定时器0,读取当前定时器0的计数值。
  73. 然后使用定时器0实际跑的值除以20ms对应计数器的值。

  74. ******************************************************************************/

  75. float HIRCCheck10KRC(void)
  76. {
  77.          float temp,a,b;
  78.          UINT16 THReg =0;

  79.          Timer0_Delay45ms();
  80.          startCheck();
  81.           
  82.          while(!(WKCON&0x10));
  83.              
  84.          clr_TR0;
  85.          clr_WKTF;

  86.          THReg = (TH0);
  87.          THReg = (THReg<<8)|TL0;

  88.          a = THReg- TIMER_45MS_BEGIN;
  89.          b = TIMER_24MS;
  90.          temp =  a/b;

  91.          return temp;
  92.        
  93. //         printf("\n%x",THReg);
  94. //         printf("\n%f",temp);

  95. }

  96. /******************************************************************************
  97. * FUNCTION_PURPOSE: 测试自唤醒定时器计数
  98. ******************************************************************************/

  99. void testSelfWakeUPTimer(float scale)
  100. {
  101.         UINT16 temp;
  102.         temp = 200 /scale;
  103.         WKCON = 0x00;                                                                                 //timer base 10k, Pre-scale = 0, 不除频,一个时钟0.1 ms
  104. //        RWK = 0XFF;                                                                                        //        if prescale is 0x00, never set RWK = 0xff
  105.         RWK = 0XFF-temp;                                                                        //200 个时钟          20 ms
  106. //  set_EWKT;                                                                                        // enable WKT interrupt
  107.         set_WKTR;                                                                                         // Wake-up timer run
  108. //        EA =1;
  109.         while(!(WKCON&0x10));

  110.         clr_WKTF;
  111.         P12=~P12;
  112. }


  113. /************************************************************************************************************
  114. *    Main function
  115. ************************************************************************************************************/
  116. void main (void)
  117. {
  118.         float rScale;
  119.         UINT8 iCount=0;

  120.     Set_All_GPIO_Quasi_Mode;
  121.         InitialUART0_Timer3(115200);
  122. //        Timer0_Delay45ms();

  123.         rScale=HIRCCheck10KRC();
  124.        
  125.         while(1)
  126.         {
  127.             rScale=HIRCCheck10KRC();
  128.                 printf("\n%f",rScale);
  129.                 Timer2_Delay1ms(100);
  130.                 for(iCount = 0;iCount<100;iCount++)
  131.                 {
  132.                  testSelfWakeUPTimer(rScale);
  133.                  testSelfWakeUPTimer(1);
  134.                 }
  135.         }

  136. }
598330983 发表于 2017-2-20 19:24 | 显示全部楼层
用两个计时系统进行比对?
heisexingqisi 发表于 2017-2-20 19:46 | 显示全部楼层
在实际应用中,可以用理论计数周期值除以该系数,得到实际要跑计数周期。
我觉得要至少有一个准确的参考。
zhuomuniao110 发表于 2017-2-20 20:40 | 显示全部楼层
RC的一般都不是用于准确计时的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

13

主题

36

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部