[开发资料]【CW32L052】RTC+LCD电子时钟

12.1 概述
实时时钟(RTC)是一个专用的计数器 / 定时器,可提供日历信息,包括小时、分钟、秒、日、月份、年份以及星期。
RTC 具有两个独立闹钟,时间、日期可组合设定,可产生闹钟中断,并通过引脚输出;支持时间戳功能,可通过
引脚触发,记录当前的日期和时间,同时产生时间戳中断;支持周期中断;支持自动唤醒功能,可产生中断并通
过引脚输出;支持 1Hz 方波和 RTCOUT 输出功能;支持内部时钟校准补偿。
CW32L052 内置经独立校准的 32kHz 频率的 RC 时钟源,为 RTC 提供驱动时钟,RTC 可在深度休眠模式下运行,
适用于要求低功耗的应用场合。
12.2 主要特性
• 日历功能(BCD 码格式)
- 秒、分、时 ( 支持 12 / 24 小时制 )
- 星期、日、月份和年份,支持自动闰年修正
• 中断功能
- 闹钟 A、B 中断,可通过引脚输出
- 周期中断,宽范围:0.5s ~ 1 个月
- 自动唤醒中断,范围:61μs ~ 145h,可通过引脚输出
- 时间戳中断
• 校准补偿功能
- 最小时钟误差补偿步长,0.119ppm
- 1Hz 方波输出引脚
• 寄存器锁定保护功能,防止意外修改
其功能框图如下:
 


可工作于运行模式、休眠模式和深度休眠模式
结合CW32L052开发板上的LCD,可以制作一个电子时钟,可以显示日期、时间。为此将如何实现这一功能分享如下:
本次使用的RTC功能有三个,一个是设置和读取日期寄存器,二个是设置与读取时间寄存器,三是设置周期中官定时器,实现中断回调函数。
根据CW32L052用户手册需要包括以下步骤:
步骤 1:向 RTC_KEY 寄存器顺序写入 0xCA、0x53,解除 RTC 寄存器锁定;
步骤 2:
配置 RTC_CR0.H24 位域,我们选择24小时制;
步骤 3:
配置 RTC_CR1.SOURCE 位域,选择 RTC 时钟源;
注: 如选择 LSE 或 LSI,需要先使能和启动 LSE 或 LSI,并等待时钟稳定。
步骤 4:
设置正确的时间和日期值,写入时间和日期寄存器;
步骤 5:
配置需要的周期中断单元;按照官方给的功能框图,我们选择1秒产生一个中断:
 


步骤 6:
配置 RTC_IER 寄存器,设置周期中断;
步骤 7:
向 RTC_KEY 寄存器顺序写入 0xCA、0x--,启动 RTC 寄存器锁定保护。
用户应用中,对 RTC进行初始化时,应先检查 MCU的复位状态(SYSCTRL_RESETFLAG)。如果是上电复位(SYSCTRL_RESETFLAG.POR = 1),RTC 的寄存器会被复位到默认值,需要重新配置 RTC 控制寄存器、RTC 日期和时间寄存器,
并重新启动 RTC;其它复位条件不会复位 RTC 的寄存器,RTC 持续正常计时。
以上的配置功能,在CW32的固件库中cw32l052_rtc.c/cw32l052_rtc.h中给用户封装好了几个函数,用户只需要指定的时钟源、需要设置的当前日期、时间以及周期中断值就行了。然后使能中断就行了大大的简化了用户的代码量,以及在CW32同系列的移植.
对RTC的设置代码如下:

void my_rtc_init(void)



{



RTC_InitTypeDef RTC_InitStruct = {0};



RCC_APBPeriphClk_Enable1(RCC_APB1_PERIPH_RTC, ENABLE); //开启RTC时钟



RCC_LSI_Enable(); //开启LSI时钟



RTC_InitStruct.DateStruct.Day = 0x19; //设置日期,DAY、MONTH、YEAR必须为BCD方式,星期为0~6,代表星期日,星期一至星期六



RTC_InitStruct.DateStruct.Month = 7;



RTC_InitStruct.DateStruct.Week = RTC_Weekday_Monday;



RTC_InitStruct.DateStruct.Year = 0x23;



RTC_InitStruct.TimeStruct.Hour = 0x11; //设置时间,HOUR、MINIUTE、SECOND必须为BCD方式,用户须保证HOUR、AMPM、H24之间的关联正确性



RTC_InitStruct.TimeStruct.Minute = 0x58;



RTC_InitStruct.TimeStruct.Second = 0x59;



RTC_InitStruct.TimeStruct.AMPM = 0;



RTC_InitStruct.TimeStruct.H24 = 1;



RTC_InitStruct.RTC_ClockSource = RTC_RTCCLK_FROM_LSI; // 用户需选定需要使用的时钟源



RTC_Init(&RTC_InitStruct);



RTC_SetInterval(RTC_INTERVAL_EVERY_1S); //设置周期中断为1S



RTC_ITConfig(RTC_IT_INTERVAL, ENABLE); //配置周期中断开启



__disable_irq();



NVIC_EnableIRQ(RTC_IRQn); //使能RTC中断



__enable_irq();



}


中断函数中,我们设置了一个RTC_IRQHandlerCallBack回调函数,函数中检测是否为周期中断,如果是,先清中断标志,然后执行一个LCD显示日期以及时期的函数,程序代码如下:

void RTC_IRQHandlerCallBack(void)



{



if (RTC_GetITState(RTC_IT_INTERVAL)) //判断是否是RTC周期中断



{



RTC_ClearITPendingBit(RTC_IT_INTERVAL); //清除中断标志



ShowTime(); //执行LCD显示



}



}


在LDC显示函数中,我们首先定义两个结构体,用于存放获取的日期与时间函数,获取日期与时间后,执行LCD的显示函数,将BCD码分解并显示到LCD屏上。在程序中,我们设志了一个标志位,间隔显示日期与时间。

void ShowTime(void)



{



static uint8_t show_state = 0;



show_state =show_state%2;//大于2归标志位



RTC_TimeTypeDef RTC_TimeStruct = {0};



RTC_DateTypeDef RTC_DateStruct = {0};



lcd_clear();//清除显示



RTC_GetDate(&RTC_DateStruct);



RTC_GetTime(&RTC_TimeStruct);



//显示固定的‘-’



lcd_show_string(5,18); //



lcd_show_string(2,18);



if(show_state == 0)



{



lcd_show_string(7,RTC_DateStruct.Year>>4);



lcd_show_string(6,RTC_DateStruct.Year&0x0F);



lcd_show_string(4,RTC_DateStruct.Month>>4);



lcd_show_string(3,RTC_DateStruct.Month&0x0F);



lcd_show_string(1,RTC_DateStruct.Day>>4);



lcd_show_string(0,RTC_DateStruct.Day&0x0F);



}else {



lcd_show_string(7,RTC_TimeStruct.Hour>>4);



lcd_show_string(6,RTC_TimeStruct.Hour&0x0F);



lcd_show_string(4,RTC_TimeStruct.Minute>>4);



lcd_show_string(3,RTC_TimeStruct.Minute&0x0F);



lcd_show_string(1,RTC_TimeStruct.Second>>4);



lcd_show_string(0,RTC_TimeStruct.Second&0x0F);



}



show_state++;



}

程序下载到开发板显示效果如下 :

---------------------
作者:lulugl
链接:https://bbs.21ic.com/icview-3315712-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值