蓝桥杯嵌入式开发经验分享(8.实时时钟讲解)

作者:马一飞                                                         QQ:791729359      

在学习过程中有什么问题可以联系

(原本资料是以网盘的方式公开提供给任何蓝桥杯爱好者进行下载的,但是最近临近蓝桥杯考试,遇到了很多伸手党,我无偿给爱好者们解答学习上的问题,回复得比较慢居然还有同学来说我这样那样,所以决定不再随意提供自己写的源码和资料。博主已经开始参加工作了,也不是闲着没事干盯着电脑手机为你们服务。记住,不要成为伸手党,要自己多动手实现。)

 

        RTC实际上就是实时时钟,如果接触过单片机的同学也许你听过DS1302实时时钟模块,实际上就是拿来获取时间的,STM32把RTC集成在了芯片内部,它内部具有专门的实时时钟单元,不需要外接其他模块。

        那么我们这里就来讲解一下蓝桥杯RTC如何进行配置。在配置前我们还需要包含四个库函数进来。

        Bkp里是关于备份寄存器的库函数,pwr里是关于电源管理的库函数。在初始化RTC时候,我们首先要先使能pwr时钟和bkp时钟。

RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP | RCC_APB1Periph_PWR,ENABLE);
PWR_BackupAccessCmd(ENABLE);
BKP_DeInit();

我们配置的是RTC,我们为什么还要配置电源管理与备份寄存器呢?我们可以看一stm32f1中文参考手册RTC章节

蓝桥杯嵌入式开发经验分享(8.实时时钟讲解)_第1张图片

可以看到,我们要使能bkp后,才能对RTC进行访问。

        同时,备份寄存器又是收到pwr(电源管理)控制的,因此我们要在pwr中使能Backup寄存器。这一步是非常关键的,如果缺少了这一步,那么后面的RTC读写将会失败

        我们还得对RTC中断进行初始化。

NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn; 
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);  //使能RTC中断

我们可以看一下数据手册,RTC的时钟源是怎么选择的。

蓝桥杯嵌入式开发经验分享(8.实时时钟讲解)_第2张图片

那么很重要的一点来了,我们蓝桥杯嵌入式板子,只能使用LSI时钟源,据官方说明是用不了其他时钟源的,所以这点是非常重要的。接下来我们直接看代码。

RCC_LSICmd(ENABLE); //使能LSI时钟
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); //选择LSI作为时钟源
RCC_RTCCLKCmd(ENABLE); //使能RTC时钟

这三个函数的原型在RCC库函数都能找到。

第一步先把LSI时钟使能,第二部把RTC的时钟选择为LSI作为时钟源,第三部使能RTC时钟

RTC_WaitForSynchro();    //等待APB1时钟与RTC时钟同步
RTC_WaitForLastTask();
		
RTC_SetPrescaler(40000 - 1);  //设置分频
RTC_WaitForLastTask(); //等待操作完成
		
RTC_SetCounter(3600 * HH + 60 * MM + SS); //设置初始时间
RTC_WaitForLastTask();
		
RTC_ITConfig(RTC_IT_SEC,ENABLE);//秒中断使能
RTC_WaitForLastTask();

1. 先等待APB1时钟与RTC时钟同步

2. 设置RTC分频系数,为什么要选择40000-1,因为我们的RTC选择的是LSI作为时钟源,我们首先得看一下LSI的时钟频率

蓝桥杯嵌入式开发经验分享(8.实时时钟讲解)_第3张图片

LSI时钟频率大约40KHZ,RTC需要1HZ的时钟,因此需要40000-1分频

3. 设置初始时间。(这个时间是按照BCD码来存储的,可以简单的理解成,是按秒数来储存的,因此小时,分,都得化为秒,相加在一起)

4. 秒中断使能。

 

在中断函数里:

void RTC_IRQHandler(void)
{
		u32 Times;
		if(RTC_GetITStatus(RTC_IT_SEC) == 1)
		{
				RTC_ClearITPendingBit(RTC_IT_SEC);
				RTC_Flag = 1;
				Times = RTC_GetCounter();
				RTC_WaitForLastTask();
				if(Times == (24 * 3600))
				{
						RTC_SetCounter(0);
						RTC_WaitForLastTask();
				}
		}
}

每次进入到秒中断,我们都另RTC_Flag = 1;然后再主函数里读取对应的时间并显示到LCD上观察。同时我们还得对RTC时间进行判断,如果RTC时间计数到24小时的时候,我们要清零重新开始计数。

在主函数中:

if(RTC_Flag)
{
		RTC_Flag = 0;
		TimeVal = RTC_GetCounter();
		hour = TimeVal / 3600;
		min = TimeVal % 3600 / 60;
		sec = TimeVal % 3600 % 60;
		sprintf((char*)string,"TIME:%.2d:%.2d:%.2d    ",hour,min,sec);
		LCD_DisplayStringLine(Line3, string);
}

我们就可以读取RTC的时间,并把时间分解为时、分、秒,小时到LCD上。

        以往年的赛题分析,RTC在蓝桥杯比赛中考的几率还是蛮大的,而且配置也不难。因此希望大家能够理解并吃透它。

把程序烧录到CT117E开发板中的现象:

蓝桥杯嵌入式开发经验分享(8.实时时钟讲解)_第4张图片

 

 

                                                                                                          (以上仅属于个人观点)

你可能感兴趣的:(蓝桥杯)