有没有内部RTC的例程
STC8H4K32TL的这个只有校准IRC时针没RTC吧
视频教学,RTC实时时钟,年/月/日/时/分/秒,1/128秒
https://www.stcaimcu.com/data/attachment/forum/202310/04/084126z3wnzgnzpmf38363.jpg
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;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 = YEAR; //快速将当前的RTC值缓存,//以缩短RTC暂停的时间,减小误差 bDump = MONTH; bDump = DAY; bDump = HOUR; bDump= MIN; bDump= SEC; bDump= SSEC; RTCCR= 1; SendUart(0x5a); //上传12字节RTC参数 SendUart(bDump); SendUart(bDump); SendUart(bDump); SendUart(bDump); SendUart(bDump); SendUart(bDump); SendUart(bDump); 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; //选择内部低速IRC为RTC时钟源 X32KCR= 0xc0; while(!(X32KCR & 0x01)); RTCCFG&= ~0x02; //选择外部部32K为RTC时钟源 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.php?mod=viewthread&tid=4412&extra=page%3D1
STCAI-32位8051 发表于 2024-5-30 15:27
有没有完整的工程 这个代码看起来有点乱 本帖最后由 STCAI-32位8051 于 2024-5-30 16:21 编辑
先从范例学起来 STCAI-32位8051 发表于 2024-5-30 16:12
先从范例学起来
printf("------> 20%bd.%2bd.%2bd %2bd:%2bd:%2bd\n",YEAR,MONTH,DAY,HOUR,MIN,SEC);
这个不是BCD 而是HEX,这个要怎么转换成十进制 STCAI-32位8051 发表于 2024-5-30 16:12
先从范例学起来
现在是能跑起来的,不知道怎么转换填充到我用到的BUF里边,再拿来用 STCAI-32位8051 发表于 2024-5-30 16:12
先从范例学起来
还有这个一分钟中断 是不是休眠的时候 也会唤醒中断 ZhangChYu 发表于 2024-5-30 17:19
还有这个一分钟中断 是不是休眠的时候 也会唤醒中断
RTC的中断可以唤醒休眠状态。
printf函数 %bd 就是将数据以十进制格式输出,用文本模式就可以正常显示。 乘风飞扬 发表于 2024-5-30 17:28
RTC的中断可以唤醒休眠状态。
printf函数 %bd 就是将数据以十进制格式输出,用文本模式就可以正常显示。 ...
那正常来说 进休眠前要关掉中断其他事件唤醒后再打开终端还有要怎么转换成十进制来用 而不只是printf
页:
[1]
2