找回密码
 立即注册
楼主: lezjin

AI8051U RTC星期计数器没有计数

[复制链接]
  • 打卡等级:以坛为家I
  • 打卡总天数:337
  • 最近打卡:2025-04-28 12:55:00

23

主题

296

回帖

1160

积分

金牌会员

积分
1160
发表于 2024-11-20 07:59:55 | 显示全部楼层
晓*** 发表于 2024-11-19 11:05
没搞清楚之前,先用这个方法顶上
专用的星期快速计算代码

好的,试下这个
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:522
  • 最近打卡:2025-05-03 13:32:44

109

主题

1900

回帖

5218

积分

论坛元老

积分
5218
发表于 2024-11-20 09:36:07 | 显示全部楼层
本帖最后由 xxkj2010 于 2024-11-20 11:05 编辑

今天试了,果真日期变了,而那个星期不会变。
星期初始化寄存器INIWEEK你写什么,星期计数寄存器WEEK读取出来就一直是什么。
估计是星期初始化寄存器与计数寄存器用了同一个寄存器,
截图202411200934283132.jpg

还有,手册里面的RTC计数寄存器就没有星期这个寄存器,估计官方本来就知道这情况的:
截图202411200935386619.jpg


回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:522
  • 最近打卡:2025-05-03 13:32:44

109

主题

1900

回帖

5218

积分

论坛元老

积分
5218
发表于 2024-11-20 10:03:17 | 显示全部楼层
本帖最后由 xxkj2010 于 2024-11-20 11:04 编辑

经过测试,这个WEEK可以变化,就是在跳月的瞬间(即每月1日 00:00:00)可以加1,而后如果修改了当前时间就会回到原来初始化的数值。

下面是设置INIWEEK=3的情况:
002.jpg

但是如果修改了时间(只修改INIHOUR、INIMIN、INISEC的数值),
星期就会从INIWEEK拷贝数值过来(如果修改了当前时间,而INIWEEK没有再次赋值的话)
原因很简单,就是因为修改时间的同时触发了初始化:
  1. RTCCFG |= 0x01;   //触发RTC寄存器初始化
复制代码

001.jpg

看起来,星期暂时只能通过公式计算了。

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:522
  • 最近打卡:2025-05-03 13:32:44

109

主题

1900

回帖

5218

积分

论坛元老

积分
5218
发表于 2024-11-20 11:04:29 | 显示全部楼层
补充,STC芯片中的RTC如果需要修改时间,所有的初始化寄存器都得写入正确的数据,如果保护不变,可以将计数寄存器的值赋给初始化寄存器,如:
  1.     INIYEAR = YEAR;   //继承当前年月日
  2.     INIMONTH = MONTH;
  3.     INIDAY = DAY;
  4.     INIWEEK=WEEK;
复制代码


回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:337
  • 最近打卡:2025-04-28 12:55:00

23

主题

296

回帖

1160

积分

金牌会员

积分
1160
发表于 2024-11-21 09:05:20 | 显示全部楼层
xxkj*** 发表于 2024-11-20 10:03
经过测试,这个WEEK可以变化,就是在跳月的瞬间(即每月1日 00:00:00)可以加1,而后如果修改了当前时间 ...

那是不是硬件逻辑错误?
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:337
  • 最近打卡:2025-04-28 12:55:00

23

主题

296

回帖

1160

积分

金牌会员

积分
1160
发表于 2024-11-21 09:08:08 | 显示全部楼层
xxkj*** 发表于 2024-11-20 09:36
今天试了,果真日期变了,而那个星期不会变。
星期初始化寄存器INIWEEK你写什么,星期计数寄存器WEEK读取出 ...

手册中有一页些有WEEK的描述
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:337
  • 最近打卡:2025-04-28 12:55:00

23

主题

296

回帖

1160

积分

金牌会员

积分
1160
发表于 2024-11-21 09:08:39 | 显示全部楼层
WEEK的描述
截图202411210908106052.jpg
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:522
  • 最近打卡:2025-05-03 13:32:44

109

主题

1900

回帖

5218

积分

论坛元老

积分
5218
发表于 2024-11-21 09:18:53 | 显示全部楼层

没错,是从这里读取的
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:522
  • 最近打卡:2025-05-03 13:32:44

109

主题

1900

回帖

5218

积分

论坛元老

积分
5218
发表于 2024-11-21 10:33:01 | 显示全部楼层
源码如下:

  1. /*
  2. 24MHz+波特率115200
  3. 使用Keil C251编译器,Memory Model推荐设置XSmall模式,默认定义变量在edata,单时钟存取访问速度快。
  4. edata建议保留1K给堆栈使用,空间不够时可将大数组、不常用变量加xdata关键字定义到xdata空间。
  5. */
  6. #include "AI8051U.h"
  7. #include "stdio.h"
  8. #include "intrins.h"
  9. /***********************************************************/
  10. typedef     unsigned char   u8;
  11. typedef     unsigned int    u16;
  12. typedef     unsigned long   u32;
  13. /****************************** 用户定义宏 ***********************************/
  14. #define MAIN_Fosc       24000000L   //定义主时钟
  15. #define PrintUart       1           //1:printf 使用 UART1; 2:printf 使用 UART2
  16. #define Baudrate        115200L
  17. #define TM              (65536 -(MAIN_Fosc/Baudrate/4))
  18. #define Timer0_Reload   (65536UL -(MAIN_Fosc / 1000))   //Timer 0 中断频率, 1000次/秒
  19. /*****************************************************************************/
  20. u8 B_10ms;          //10ms标志
  21. bit B_1s;                        //1s标志
  22. bit B_Alarm;        //闹钟标志
  23. u8  hour,minute,sec; //RTC变量
  24. u16 msecond;
  25. #define LED P35
  26. /*************  本地函数声明    **************/
  27. void WriteRTC(void);
  28. void RTC_config(void);
  29. void Timer0_Init(void);                //1000毫秒@24.000MHz
  30. void delay_ms(u8 ms);
  31. void UartInit(void)
  32. {
  33. #if(PrintUart == 1)
  34.     S1_S1 = 0;      //UART1 switch to, 0x00: P3.0 P3.1, 0x40: P3.6 P3.7, 0x80: P1.6 P1.7, 0xC0: P4.3 P4.4
  35.     S1_S0 = 0;
  36.     SCON = (SCON & 0x3f) | 0x40;
  37.     T1x12 = 1;      //定时器时钟1T模式
  38.     S1BRT = 0;      //串口1选择定时器1为波特率发生器
  39.     TL1  = TM;
  40.     TH1  = TM>>8;
  41.     TR1 = 1;        //定时器1开始计时
  42. //    SCON = (SCON & 0x3f) | 0x40;
  43. //    T2L  = TM;
  44. //    T2H  = TM>>8;
  45. //    AUXR |= 0x15; //串口1选择定时器2为波特率发生器
  46. #else
  47.     S2_S = 1;       //UART2 switch to: 0: P1.2 P1.3,  1: P4.2 P4.3
  48.     S2CFG |= 0x01;  //使用串口2时,W1位必需设置为1,否则可能会产生不可预期的错误
  49.     S2CON = (SCON & 0x3f) | 0x40;
  50.     T2L  = TM;
  51.     T2H  = TM>>8;
  52.     AUXR |= 0x14;   //定时器2时钟1T模式,开始计时
  53. #endif
  54. }
  55. /**********************************************/
  56. void main(void)
  57. {
  58.     WTST = 0;  //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
  59.     EAXFR = 1; //扩展寄存器(XFR)访问使能
  60.     CKCON = 0; //提高访问XRAM速度
  61.     P0M1 = 0x00;   P0M0 = 0x00;   //设置为准双向口
  62.     P1M1 = 0x00;   P1M0 = 0x00;   //设置为准双向口
  63.     P2M1 = 0x00;   P2M0 = 0x00;   //设置为准双向口
  64.     P3M1 = 0x00;   P3M0 = 0x00;   //设置为准双向口
  65.     P4M1 = 0x00;   P4M0 = 0x00;   //设置为准双向口
  66.     P5M1 = 0x00;   P5M0 = 0x00;   //设置为准双向口
  67.     P6M1 = 0x00;   P6M0 = 0x00;   //设置为准双向口
  68.     P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口
  69.     Timer0_Init();
  70.     UartInit();
  71.     RTC_config();
  72.     EA = 1;     //打开总中断
  73.         delay_ms(100);
  74.     while(1)
  75.     {
  76.         if(B_1s)
  77.         {
  78.             B_1s = 0;
  79.                         LED=~LED;
  80. //                        printf("LED---");
  81.                         printf("20%d-%d-%d  Week=%d  %d:%d:%d\r\n",YEAR,MONTH,DAY,WEEK,HOUR,MIN,SEC);//
  82.             
  83.         }
  84. //        if(B_Alarm)
  85. //        {
  86. //            B_Alarm = 0;
  87. //            printf("RTC Alarm!\r\n");
  88. //        }
  89.     }
  90. }
  91. void Timer0_Isr(void) interrupt 1
  92. {
  93.         B_1s=1;       
  94. }
  95. void Timer0_Init(void)                //1000毫秒@24.000MHz
  96. {
  97.         TM0PS = 0x1E;                        //设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 )
  98.         AUXR &= 0x7F;                        //定时器时钟12T模式
  99.         TMOD &= 0xF0;                        //设置定时器模式
  100.         TL0 = 0xFC;                                //设置定时初始值
  101.         TH0 = 0x03;                                //设置定时初始值
  102.         TF0 = 0;                                //清除TF0标志
  103.         TR0 = 1;                                //定时器0开始计时
  104.         ET0 = 1;                                //使能定时器0中断
  105. }
  106. ///********************** 写RTC函数 ************************/
  107. //void WriteRTC(void)
  108. //{
  109. //    INIYEAR = YEAR;   //继承当前年月日
  110. //    INIMONTH = MONTH;
  111. //    INIDAY = DAY;
  112. //    INIHOUR = hour;   //修改时分秒
  113. //    INIMIN = minute;
  114. //    INISEC = sec;
  115. //    INISSEC = 0;
  116. //    RTCCFG |= 0x01;   //触发RTC寄存器初始化
  117. //}
  118. /******************** RTC中断函数 *********************/
  119. void RTC_Isr() interrupt 13
  120. {
  121.     if(RTCIF & 0x80)    //闹钟中断
  122.     {
  123.         RTCIF &= ~0x80;
  124.         B_Alarm = 1;
  125.     }
  126.     if(RTCIF & 0x08)    //秒中断
  127.     {
  128.         RTCIF &= ~0x08;
  129. //        B_1s = 1;
  130.     }
  131. }
  132. //========================================================================
  133. // 函数: void RTC_config(void)
  134. // 描述: RTC初始化函数。
  135. // 参数: 无.
  136. // 返回: 无.
  137. // 版本: V1.0, 2020-6-10
  138. //========================================================================
  139. void RTC_config(void)
  140. {
  141.     INIYEAR = 24;     //年
  142.     INIMONTH = 11;    //月
  143.     INIDAY = 30;      //日
  144.         INIWEEK=3;        //星期
  145.     INIHOUR = 23;     //H:23
  146.     INIMIN = 59;      //M:59
  147.     INISEC = 55;      //S:50
  148.     INISSEC = 0;      //S/128:0
  149.     ALAHOUR = 0;    //闹钟小时
  150.     ALAMIN  = 0;    //闹钟分钟
  151.     ALASEC  = 0;    //闹钟秒
  152.     ALASSEC = 0;    //闹钟1/128秒
  153.     IRC32KCR = 0x80;   //启动内部32K晶振.
  154.     while (!(IRC32KCR & 1));  //等待时钟稳定
  155.     RTCCFG = 0x03;    //选择内部32K时钟源,触发RTC寄存器初始化
  156. //    X32KCR = 0x80 + 0x40;   //启动外部32K晶振, 低增益+0x00, 高增益+0x40.
  157. //    while (!(X32KCR & 1));  //等待时钟稳定
  158. //    RTCCFG = 0x01;    //选择外部32K时钟源,触发RTC寄存器初始化
  159.     RTCIF = 0x00;     //清中断标志
  160.     RTCIEN = 0x88;    //中断使能, 0x80:闹钟中断, 0x40:日中断, 0x20:小时中断, 0x10:分钟中断, 0x08:秒中断, 0x04:1/2秒中断, 0x02:1/8秒中断, 0x01:1/32秒中断
  161.     RTCCR = 0x01;     //RTC使能
  162.     while(RTCCFG & 0x01);    //等待初始化完成,需要在 "RTC使能" 之后判断.
  163.     //设置RTC时间需要32768Hz的1个周期时间,大约30.5us. 由于同步, 所以实际等待时间是0~30.5us.
  164.     //如果不等待设置完成就睡眠, 则RTC会由于设置没完成, 停止计数, 唤醒后才继续完成设置并继续计数.
  165. }
  166. void UartPutc(unsigned char dat)
  167. {
  168. #if(PrintUart == 1)
  169.     SBUF = dat;
  170.     while(TI == 0);
  171.     TI = 0;
  172. #else
  173.     S2BUF  = dat;
  174.     while(S2TI == 0);
  175.     S2TI = 0;    //Clear Tx flag
  176. #endif
  177. }
  178. char putchar(char c)
  179. {
  180.     UartPutc(c);
  181.     return c;
  182. }
  183. void Delay1ms(void)        //@24.000MHz
  184. {
  185.         unsigned long edata i;
  186.         _nop_();
  187.         _nop_();
  188.         _nop_();
  189.         i = 5998UL;
  190.         while (i) i--;
  191. }
  192. void delay_ms(u8 ms)
  193. {
  194.         while(ms--)Delay1ms();
  195. }
复制代码


001.rar

25.49 KB, 下载次数: 48

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:337
  • 最近打卡:2025-04-28 12:55:00

23

主题

296

回帖

1160

积分

金牌会员

积分
1160
发表于 2024-11-21 14:07:34 | 显示全部楼层

嗯,代码都差不多的,应该没有什么逻辑上的问题,我感觉是共用一个地址造成的,不过看你的好像月份变化的时候星期会变,说明也是可以计数的,这个得官方看下是什么原因了
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-3 15:01 , Processed in 0.190934 second(s), 105 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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