找回密码
 立即注册
查看: 970|回复: 18

求问,如何获取内部不精准的32k时钟准确值

[复制链接]
  • 打卡等级:以坛为家II
  • 打卡总天数:425
  • 最近打卡:2025-05-03 00:16:56

3

主题

25

回帖

1333

积分

金牌会员

积分
1333
发表于 2024-9-5 20:43:04 | 显示全部楼层 |阅读模式
首先我知道这个低功耗的32k时钟十分不准,但还是想不加晶振的情况下,尽可能的利用这个做一些东西。现在想获取他在某一时刻的准确值。

我的思路是使用rtc的秒中断,设置一个100us一次的定时器,中断时记录计数值。准确频率值应该是(32768/计数值)x10000。
但是我发现,计算值,和用主时钟输出,示波器/另一个单片机pwm测量值不相同,比如计算值是24983Hz,示波器或pwm测量是25370Hz。
我想问下,这两者之间哪个较为准确,如果计算值不准确,能否看看是哪里的问题。万分感谢

附上主要代码
  1. #include        "config.h"
  2. #include        "STC8G_H_GPIO.h"
  3. #include        "STC8G_H_UART.h"
  4. #include        "STC8G_H_Delay.h"
  5. #include        "STC8G_H_NVIC.h"
  6. #include        "STC8G_H_Switch.h"
  7. bit f_1s;
  8. u16 timeCnt, lastCnt, fwt;
  9. float tmp;
  10. u8 st;
  11. void        GPIO_config(void)
  12. {
  13.     GPIO_InitTypeDef        GPIO_InitStructure;                //结构定义
  14.     P0M0 = 0x00;
  15.     P0M1 = 0x00;
  16.     P1M0 = 0x00;
  17.     P1M1 = 0x00;
  18.     P2M0 = 0x00;
  19.     P2M1 = 0x00;
  20.     P3M0 = 0x00;
  21.     P3M1 = 0x00;
  22.     P4M0 = 0x00;
  23.     P4M1 = 0x00;
  24.     P5M0 = 0x00;
  25.     P5M1 = 0x00;
  26.     GPIO_InitStructure.Pin  = GPIO_Pin_0 | GPIO_Pin_1;                //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7
  27.     GPIO_InitStructure.Mode = GPIO_PullUp;        //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
  28.     GPIO_Inilize(GPIO_P3, &GPIO_InitStructure);        //初始化
  29. }
  30. /***************  串口初始化函数 *****************/
  31. void        UART_config(void)
  32. {
  33.     COMx_InitDefine                COMx_InitStructure;                                        //结构定义
  34.     COMx_InitStructure.UART_Mode      = UART_8bit_BRTx;        //模式, UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTx
  35.     COMx_InitStructure.UART_BRT_Use   = BRT_Timer1;                        //选择波特率发生器, BRT_Timer1, BRT_Timer2 (注意: 串口2固定使用BRT_Timer2)
  36.     COMx_InitStructure.UART_BaudRate  = 115200ul;                        //波特率, 一般 110 ~ 115200
  37.     COMx_InitStructure.UART_RxEnable  = ENABLE;                                //接收允许,   ENABLE或DISABLE
  38.     COMx_InitStructure.BaudRateDouble = DISABLE;                        //波特率加倍, ENABLE或DISABLE
  39.     UART_Configuration(UART1, &COMx_InitStructure);                //初始化串口1 UART1,UART2,UART3,UART4
  40.     NVIC_UART1_Init(ENABLE, Priority_1);                //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
  41.     UART1_SW(UART1_SW_P30_P31);                //UART1_SW_P30_P31,UART1_SW_P36_P37,UART1_SW_P16_P17,UART1_SW_P43_P44
  42. }
  43. /**********************************************/
  44. void Timer0_Init(void)                //100微秒@24.000MHz
  45. {
  46.     AUXR |= 0x80;                        //定时器时钟1T模式
  47.     TMOD &= 0xF0;                        //设置定时器模式
  48.     TL0 = 0xA0;                                //设置定时初始值
  49.     TH0 = 0xF6;                                //设置定时初始值
  50.     TF0 = 0;                                //清除TF0标志
  51.     ET0 = 1;
  52.     TR0 = 1;                                //定时器0开始计时
  53. }
  54. void Timer0Proc() interrupt 1
  55. {
  56.     timeCnt++;
  57. }
  58. //rtc
  59. void RTC_Isr() interrupt 13//RTC_VECTOR
  60. {
  61.     if(RTCIF & 0x08) //秒中断
  62.     {
  63.         RTCIF &= ~0x08;
  64.         lastCnt = timeCnt;
  65.         timeCnt = 0;
  66.         f_1s = 1;
  67.     }
  68. }
  69. void RTC_Init()
  70. {
  71.     //使用内部时钟
  72.     IRC32KCR = 0x80;
  73.     while(!(IRC32KCR & 0x01));
  74.     RTCCFG |= 0x02;
  75.     INIYEAR = 23;                                                                                                    //Y:23
  76.     INIMONTH = 02;                                                                                                   //M:02
  77.     INIDAY = 21;                                                                                                     //D:19
  78.     INIHOUR = 23;                                                                                                    //H:23
  79.     INIMIN = 00;                                                                                                     //M:45
  80.     INISEC = 00;                                                                                                     //S:55
  81.     INISSEC = 0;                                                                                              //S/128:0
  82.     RTCCFG |= 0x01;
  83.     RTCIF = 0;
  84.     RTCIEN = 0x08; //秒中断
  85.     timeCnt = 0;
  86.     RTCCR = 1; //启动
  87. }
  88. void main(void)
  89. {
  90.     u8        i;
  91.     EAXSFR();                /* 扩展寄存器访问使能 */
  92.     GPIO_config();
  93.     UART_config();
  94.     EA = 1;
  95.     Timer0_Init();
  96.     RTC_Init();
  97.        
  98.     fwt = CHIPID9 << 8 | CHIPID10;
  99.     st = 0;
  100.     MCLKOCR = 0x01;                             //主时钟输出到P5.4口
  101.     while (1)
  102.     {
  103.         if(st == 10)
  104.         {
  105.             st++;
  106.             //关闭rtc
  107.             RTCIEN = 0;
  108.             timeCnt = 0;
  109.             RTCCR = 0;
  110.                         //切换主时钟
  111.             CLKDIV = 0x00;                              //时钟不分频
  112.             CLKSEL = 0x03;                              //选择内部32K
  113.         }
  114.         if(f_1s)
  115.         {
  116.             f_1s = 0;
  117.             tmp = 32768.0 / lastCnt * 10000.0;
  118.             printf("b=%huHz  Cnt=%hu calc=%fHz\r\n", fwt, lastCnt, tmp);
  119.             st++;
  120.         }
  121.     }
  122. }
复制代码


输出示例 b=30070Hz Cnt=13116 calc=24983Hz
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:425
  • 最近打卡:2025-05-03 00:09:43
已绑定手机

77

主题

4850

回帖

8388

积分

超级版主

DebugLab

积分
8388
发表于 2024-9-5 20:55:39 | 显示全部楼层
内部高频时钟比内部32K时钟精度高
DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:425
  • 最近打卡:2025-05-03 00:09:43
已绑定手机

77

主题

4850

回帖

8388

积分

超级版主

DebugLab

积分
8388
发表于 2024-9-5 20:57:50 | 显示全部楼层
内部32K时钟精度只适合掉电唤醒和段式LCD刷屏,有温飘和压飘,不要做别的用
DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:425
  • 最近打卡:2025-05-03 00:16:56

3

主题

25

回帖

1333

积分

金牌会员

积分
1333
发表于 2024-9-5 21:23:55 | 显示全部楼层
Debu*** 发表于 2024-9-5 20:57
内部32K时钟精度只适合掉电唤醒和段式LCD刷屏,有温飘和压飘,不要做别的用 ...

你说的我知道,通过上面代码试验我也看出来了,飘的挺多,费劲去校准不如加外部晶振。正常需要精准定时是不会去用的。我现在想的是否是代码问题导致获取到的频率不同,或者有什么不了解的机制
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:387
  • 最近打卡:2025-05-02 10:19:07
已绑定手机

8

主题

137

回帖

1049

积分

金牌会员

积分
1049
发表于 2024-9-5 21:27:42 | 显示全部楼层
你这个属于逻辑问题啊,没有参照,怎么会知道自己是多少呢?
你手上只有一把尺子,你能有办法判断这把尺子准不准吗?没有其他已知量的情况下。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:424
  • 最近打卡:2025-05-03 00:02:01
已绑定手机

19

主题

3191

回帖

4876

积分

论坛元老

积分
4876
发表于 2024-9-5 22:13:23 | 显示全部楼层
最简单的方法还是加外部晶振啊
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:215
  • 最近打卡:2025-05-03 00:37:12
已绑定手机

36

主题

561

回帖

1942

积分

荣誉版主

积分
1942
发表于 2024-9-5 23:50:08 | 显示全部楼层
既然pwm测量值=示波器测量值,那肯定相信这个准确。
至于理论计算值,怎么也要把能想到的误差都考虑进去然后更正,这样应该可以无限接近测量值,且在一定的范围内。
至于何时准确的话,怎么也必须得把测试条件(温度、湿度、供电等)调整到最相近的理论条件吧。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:322
  • 最近打卡:2025-05-02 10:02:36
已绑定手机

21

主题

487

回帖

1041

积分

金牌会员

积分
1041
发表于 2024-9-6 08:22:18 | 显示全部楼层
这种钻研的精神值得学习,如果各方面都试过确实不行,至少测试过程的经验是真正的收获
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:425
  • 最近打卡:2025-05-03 00:16:56

3

主题

25

回帖

1333

积分

金牌会员

积分
1333
发表于 2024-9-6 10:18:01 | 显示全部楼层
Yim_*** 发表于 2024-9-5 23:50
既然pwm测量值=示波器测量值,那肯定相信这个准确。
至于理论计算值,怎么也要把能想到的误差都考虑进去然 ...

对,测量值应该是准确的,现在就是想不出来计算的值误差在哪里,用的stc8h8k64u,换了一个单片机也是差200-500,所以就想把代码发出来给大佬们看看有无没考虑到的地方

点评

搞定温漂 压漂,试试看  详情 回复 发表于 2024-9-6 12:40
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:425
  • 最近打卡:2025-05-03 00:16:56

3

主题

25

回帖

1333

积分

金牌会员

积分
1333
发表于 2024-9-6 10:30:11 | 显示全部楼层
cn*** 发表于 2024-9-5 21:27
你这个属于逻辑问题啊,没有参照,怎么会知道自己是多少呢?
你手上只有一把尺子,你能有办法判断这把尺子 ...

按老师您说的,我认为我并不是只有一把尺子,是3把,两把长尺(示波器和另一个单片机)可以直接测量出准确值,一把短尺(单片机自身高速时钟),通过计算得到数据。现在尺子是准的,测量/计算方法可能有问题
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-3 05:34 , Processed in 0.159316 second(s), 119 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表