找回密码
 立即注册
查看: 1331|回复: 17

有没有内部RTC的例程

[复制链接]
  • 打卡等级:偶尔看看I
  • 打卡总天数:11
  • 最近打卡:2025-03-27 08:29:56

22

主题

58

回帖

329

积分

中级会员

积分
329
发表于 2024-5-30 14:48:37 | 显示全部楼层 |阅读模式
STC8H4K32TL的
回复

使用道具 举报 送花

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

19

主题

3191

回帖

4930

积分

论坛元老

积分
4930
发表于 2024-5-30 14:52:44 | 显示全部楼层
这个只有校准IRC时针没RTC吧
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:32
  • 最近打卡:2025-04-30 10:59:33

25

主题

1154

回帖

2391

积分

超级版主

积分
2391
发表于 2024-5-30 15:27:46 | 显示全部楼层
视频教学RTC实时时钟,年/月/日/时/分/秒,1/128秒

https://www.stcaimcu.com/forum.p ... 3184&extra=page%3D1
28.3     范例程序1.3.1          串口打印RTC时钟范例
C语言代码

//测试工作频率为22.1184MHz,需要将C语言代码文件与下面的汇编代码文件加载到同一个项目里使用
#include "stc8h.h"
#include "intrins.h"
#include "stdio.h"
#define       MAIN_Fosc                22118400L
#define       Baudrate                      115200L
#define       TM                               (65536-(MAIN_Fosc/Baudrate+2)/4)
//2操作是为了让Keil编译器
                                                                                                                //自动实现四舍五入运算

bit               B1S_Flag;
void RTC_config(void);

void UartInit(void)
{
         SCON= (SCON & 0x3f) | 0x40;
         T2L  = TM;
         T2H  = TM>>8;
         AUXR|= 0x15;
}
void UartPutc(unsigned char dat)
{
         SBUF= dat;
         while(TI==0);
         TI= 0;
}
char putchar(char c)
{
         UartPutc(c);
         returnc;
}
void RTC_Isr() interrupt 13
{
         if(RTCIF& 0x08)                //判断是否秒中断
         {
                   RTCIF&= ~0x08;                                                              //清中断标志
                   B1S_Flag= 1;
         }
}
void main(void)
{
         P_SW2|= 0x80;                    //使能XFR访问
         P0M1= 0;   P0M0 = 0;   //设置为准双向口
         P1M1= 0;   P1M0 = 0;   //设置为准双向口
         P2M1= 0;   P2M0 = 0;   //设置为准双向口
         P3M1= 0;   P3M0 = 0;   //设置为准双向口
         P4M1= 0;   P4M0 = 0;   //设置为准双向口
         P5M1= 0;   P5M0 = 0;   //设置为准双向口
         UartInit();
         RTC_config();
         EA= 1;
         printf("RTCTest Programme!\r\n");                                         //UART发送一个字符串
         while(1)
         {
                   if(B1S_Flag)
                   {
                            B1S_Flag= 0;
                            printf("Year=20%bd  ", YEAR);
                            printf("Month=%bd  ", MONTH);
                            printf("Day=%bd  ", DAY);
                            printf("Hour=%bd  ", HOUR);
                            printf("Minute=%bd  ", MIN);
                            printf("Second=%bd  ", SEC);
                            printf("\r\n");
                   }
         }
}
void RTC_config(void)
{
//       //选择内部低速IRC
//       IRC32KCR = 0x80;                                                                      //启动内部低速振荡器
//       while (!(IRC32KCR & 0x01));                                                     //等待时钟稳定
//       RTCCFG |= 0x02;                                                                        //选择内部低速IRC作为RTC时钟源
         //选择外部32K
         X32KCR= 0xc0;                                                                           //启动外部32K晶振
         while(!(X32KCR & 0x01));                                                         //等待时钟稳定
         RTCCFG&= ~0x02;                                                                    //选择外部32K作为RTC时钟源
         INIYEAR= 21;                                                                            //Y:2021
         INIMONTH= 12;                                                                        //M:12
         INIDAY= 31;                                                                               //D:31
         INIHOUR= 23;                                                                           //H:23
         INIMIN= 59;                                                                               //M:59
         INISEC= 50;                                                                               //S:50
         INISSEC= 0;                                                                               //S/128:0
         RTCCFG|= 0x01;                                                                        //触发RTC寄存器初始化
         RTCIF= 0;                                                                                   //清中断标志
         RTCIEN= 0x08;                                                                          //使能RTC秒中断
         RTCCR= 0x01;                                                                            // RTC使能}
}

汇编代码

;将以下代码保存为ASM格式文件,一起加载到项目里,例如:isr.asm
                            CSEG    AT 0123H
                            JMP                    006BH
                            END

28.3.2          利用ISP软件的用户接口实现不停电下载保持RTC参数
C语言代码

//测试工作频率为11.0592MHz
/*************  功能说明 *********************************************************************
现有单片机系列的RTC模块,在单片机复位后RTC相关的特殊功能寄存器也会复位
本例程主要用于解决ISP下载后用户的RTC参数丢失的问题
解决思路:ISP下载前,先将RTC相关参数通过ISP下载软件的用户接口上传到PC保存,等待ISP下载完成后,下载软件再将保存的相关参数写入到FLASH的指定地址(范例中指定的地址为FE00H)。ISP下载完成后会立即运行用户代码,用户程序在初始化RTC寄存器时,可从FLASH的指定地址中读取之前上传的RTC相关参数对RTC寄存器进行初始化,即可实现不停电下载保持RTC参数的目的。
下载时, 选择时钟 11.0592MHZ
************************************************************************************************/
#include "stc8h.h"
#include "intrins.h"
#include "stdio.h"
#include "stc8h.h"
#include "intrins.h"
#define       FOSC                          11059200UL
#define       BAUD                         (65536- FOSC/4/115200)
typedef       bit                                 BOOL;
typedef       unsigned char              BYTE;
typedef       unsigned int                 WORD;
struct RTC_INIT
{
         BYTE bValidTag;                                                                      //数据有效标志(0x5a)
         BYTE bIniYear;                                                                        //(RTC初始化值)
         BYTE bIniMonth;                                                                    //
         BYTE bIniDay;                                                                         //
         BYTE bIniHour;                                                                       //
         BYTE bIniMinute;                                                                    //
         BYTE bIniSecond;                                                                    //
         BYTE bIniSSecond;                                                                  //次秒
         BYTE bAlaHour;                                                                      //(RTC闹钟设置值)
         BYTE bAlaMinute;                                                                   //
         BYTE bAlaSecond;                                                                   //
         BYTE bAlaSSecond;                                                                 //次秒
};
struct RTC_INIT code InitBlock_at_ 0xfe00;
void SysInit();
void UartInit();
void RTCInit();
void SendUart(BYTE dat);
void UnpackCmd(BYTE dat);
void IapProgram(WORD addr, BYTEdat);
BOOL fUartBusy;
BOOL fFetchRtc;
BOOL fReset2Isp;
BYTE bUartStage;
BYTE bDump[7];
void main()
{
         SysInit();                                                                                       //系统初始化
         UartInit();
         RTCInit();
         EA= 1;
         fUartBusy= 0;
         fFetchRtc= 0;
         fReset2Isp= 0;
         bUartStage= 0;
         while(1)
         {
                  if (fFetchRtc)                                                                       //获取RTC数据请求
                  {
                            fFetchRtc = 0;
                            RTCCR = 0;                                                               //上传当前的RTC值时,必须临时停止RTC
//以免发生进位错误
                            bDump[0] = YEAR;                                                   //快速将当前的RTC值缓存,
//以缩短RTC暂停的时间,减小误差
                            bDump[1] = MONTH;
                            bDump[2] = DAY;
                            bDump[3] = HOUR;
                            bDump[4]= MIN;
                            bDump[5]= SEC;
                            bDump[6]= SSEC;
                            RTCCR= 1;
                            SendUart(0x5a);                                                         //上传12字节RTC参数
                            SendUart(bDump[0]);
                            SendUart(bDump[1]);
                            SendUart(bDump[2]);
                            SendUart(bDump[3]);
                            SendUart(bDump[4]);
                            SendUart(bDump[5]);
                            SendUart(bDump[6]);
                            SendUart(ALAHOUR);
                            SendUart(ALAMIN);
                            SendUart(ALASEC);
                            SendUart(ALASSEC);
                  }
                  if (fReset2Isp)                                                                      //重启请求
                  {
                            fReset2Isp = 0;
                            IAP_CONTR = 0x60;                                                //软件触发复位到系统ISP
                  }
         }
}
void uart_isr() interruptUART1_VECTOR
{
         BYTEdat;
         if(TI)
         {
                  TI = 0;
                  fUartBusy =        0;
         }
         if(RI)
         {
                  RI = 0;
                  dat = SBUF;
                  switch (bUartStage++)                                                                 //解析串口命令
                  {
                  default:
                  case 0:
L_Check1st:
                            if (dat == '@') bUartStage = 1;
                           elsebUartStage = 0;
                            break;
                  case 1:
                            if (dat == 'F') bUartStage = 2;
                            else if (dat == 'R') bUartStage = 7;
                            else goto L_Check1st;
                            break;
                  case 2:
                            if (dat != 'E') goto L_Check1st;
                            break;
                  case 3:
                            if (dat != 'T') gotoL_Check1st;
                           break;
                  case 4:
                            if (dat != 'C') gotoL_Check1st;
                            break;
                  case 5:
                            if (dat != 'H') gotoL_Check1st;
                            break;
                  case 6:
                            if (dat != '#') gotoL_Check1st;
                            bUartStage = 0;
                            fFetchRtc = 1;                                                            //当前命令序列为获取RTC数据命令:"@FETCH#"
                            break;
                  case 7:
                            if (dat != 'E') goto L_Check1st;
                            break;
                  case 8:
                            if (dat != 'B') goto L_Check1st;
                            break;
                  case 9:
                  case 10:
                            if (dat != 'O') gotoL_Check1st;
                            break;
                  case 11:
                            if (dat != 'T') gotoL_Check1st;
                            break;
                  case 12:
                            if (dat != '#') goto L_Check1st;
                            bUartStage = 0;
                            fReset2Isp = 1;                                                           //当前命令序列为重启命令:"@REBOOT#"
                            break;
                  }
         }
}
void rtc_isr() interruptRTC_VECTOR                                                //RTC中断复位程序
{
         RTCIF= 0x00;                                                                             //RTC中断标志
         P20= !P20;                                                                                   //P2.0口每秒闪烁一次,测试用
}
void SysInit()
{
         P_SW2|= 0x80;
         P0M0= 0x00; P0M1 = 0x00;
         P1M0= 0x00; P1M1 = 0x00;
         P2M0= 0x00; P2M1 = 0x00;
         P3M0= 0x00; P3M1 = 0x00;
         P4M0= 0x00; P4M1 = 0x00;
         P5M0= 0x00; P5M1 = 0x00;
         P6M0= 0x00; P6M1 = 0x00;
         P7M0= 0x00; P7M1 = 0x00;
}
void UartInit()                                                                                        //串口初始化函数
{
         SCON= 0x50;
         AUXR= 0x40;
         TMOD= 0x00;
         TL1= BAUD;
         TH1= BAUD >> 8;
         TR1= 1;
         ES= 1;
}
void RTCInit()                                                                                        //RTC初始化函数
{
//       IRC32KCR = 0x80;
//       while (!(IRC32KCR & 0x01));
//       RTCCFG |= 0x02;                                                                        //选择内部低速IRCRTC时钟源
         X32KCR= 0xc0;
         while(!(X32KCR & 0x01));
         RTCCFG&= ~0x02;                                                                    //选择外部部32KRTC时钟源
         if(InitBlock.bValidTag == 0x5a)
         {
                   INIYEAR= InitBlock.bIniYear;                                         //如果初始化数据块有效,则使用数据块初始化RTC
                   INIMONTH= InitBlock.bIniMonth;
                   INIDAY= InitBlock.bIniDay;
                   INIHOUR= InitBlock.bIniHour;
                   INIMIN= InitBlock.bIniMinute;
                   INISEC= InitBlock.bIniSecond;
                   INISSEC= InitBlock.bIniSSecond;
                   ALAHOUR= InitBlock.bAlaHour;
                   ALAMIN= InitBlock.bAlaMinute;
                   ALASEC= InitBlock.bAlaSecond;
                   ALASSEC= InitBlock.bAlaSSecond;
                   IapProgram(0x0000,0x00);                                               //销毁初始化数据块,以免重复初始化
         }
         else
         {
                  INIYEAR = 23;                                                                   //否则初始化RTC为默认值
                  INIMONTH = 1;
                  INIDAY = 29;
                   INIHOUR= 12;
                   INIMIN= 0;
                   INISEC= 0;
                   INISSEC= 0;
                   ALAHOUR= 0;
                   ALAMIN= 0;
                   ALASEC= 0;
                   ALASSEC= 0;
         }
         RTCCFG|= 0x01;                                                                        //写入RTC初始值
         RTCCR= 0x01;                                                                            //RTC开始运行
         while(RTCCFG & 0x01);                                                            //等待RTC初始化完成
         RTCIF= 0x00;
         RTCIEN= 0x08;                                                                          //使能RTC秒中断
}
void SendUart(BYTE dat)                                                                     //串口发送函数
{
         while(fUartBusy);
         SBUF= dat;
         fUartBusy= 1;
}
void IapProgram(WORD addr, BYTEdat)                                           //EEPROM编程函数
{
         IAP_CONTR= 0x80;
         IAP_TPS= 12;
         IAP_CMD= 2;
         IAP_ADDRL= addr;
         IAP_ADDRH= addr >> 8;
         IAP_DATA= dat;
         IAP_TRIG= 0x5a;
         IAP_TRIG= 0xa5;
         _nop_();
         _nop_();
         _nop_();
         _nop_();}
}
【新提醒】视频讲解:RTC 实时时钟,年月日时分秒,STC8H数据手册 RTC 内容 - 段码LCD/80mA大电流LED数码管自动刷新显示/RTC实时时钟/触摸按键/低功耗 国芯技术交流网站 - STC全球32位8051爱好者互助交流社区  https://www.stcaimcu.com/forum.p ... &extra=page%3D1



STC官网:https://www.stcai.com/
QQ:2593903262
微信号:18106296598
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:11
  • 最近打卡:2025-03-27 08:29:56

22

主题

58

回帖

329

积分

中级会员

积分
329
发表于 2024-5-30 15:52:32 | 显示全部楼层

有没有完整的工程 这个代码看起来有点乱
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:32
  • 最近打卡:2025-04-30 10:59:33

25

主题

1154

回帖

2391

积分

超级版主

积分
2391
发表于 2024-5-30 16:12:51 | 显示全部楼层
本帖最后由 STCAI-32位8051 于 2024-5-30 16:21 编辑

先从范例学起来

STC32G-RTC基本操作.rar

105.85 KB, 下载次数: 122

52-内部RTC时钟程序-20230515.zip

13.19 KB, 下载次数: 122

STC官网:https://www.stcai.com/
QQ:2593903262
微信号:18106296598
回复 支持 1 反对 0

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:11
  • 最近打卡:2025-03-27 08:29:56

22

主题

58

回帖

329

积分

中级会员

积分
329
发表于 2024-5-30 16:47:32 | 显示全部楼层

printf("------> 20%bd.%2bd.%2bd %2bd:%2bd:%2bd\n",YEAR,MONTH,DAY,HOUR,MIN,SEC);
这个不是BCD 而是HEX,这个要怎么转换成十进制
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:11
  • 最近打卡:2025-03-27 08:29:56

22

主题

58

回帖

329

积分

中级会员

积分
329
发表于 2024-5-30 16:48:32 | 显示全部楼层

现在是能跑起来的,不知道怎么转换填充到我用到的BUF里边,再拿来用
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:11
  • 最近打卡:2025-03-27 08:29:56

22

主题

58

回帖

329

积分

中级会员

积分
329
发表于 2024-5-30 17:19:02 | 显示全部楼层

还有  这个一分钟中断 是不是休眠的时候 也会唤醒中断
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:415
  • 最近打卡:2025-04-30 09:58:34
已绑定手机

39

主题

2006

回帖

6845

积分

论坛元老

积分
6845
发表于 2024-5-30 17:28:43 | 显示全部楼层
Zhang*** 发表于 2024-5-30 17:19
还有  这个一分钟中断 是不是休眠的时候 也会唤醒中断

RTC的中断可以唤醒休眠状态。
printf函数 %bd 就是将数据以十进制格式输出,用文本模式就可以正常显示。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:11
  • 最近打卡:2025-03-27 08:29:56

22

主题

58

回帖

329

积分

中级会员

积分
329
发表于 2024-5-31 08:45:32 | 显示全部楼层
乘风*** 发表于 2024-5-30 17:28
RTC的中断可以唤醒休眠状态。
printf函数 %bd 就是将数据以十进制格式输出,用文本模式就可以正常显示。 ...

那正常来说 进休眠前要关掉中断  其他事件唤醒后再打开终端  还有要怎么转换成十进制来用 而不只是printf
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-4 05:51 , Processed in 0.193533 second(s), 111 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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