蓝桥杯嵌入式(六)RTC配置

STM32的实时时钟(RTC)是一个独立的定时器,是用来获取时间的。在蓝桥杯嵌入式比赛中也是比较常考的一个知识点。配置起来较为简单,也可以直接复制考场提供的固件库中的例程。

在进行RTC配置前,我们需要从固件库添加几个文件,添加方法在串口配置中有详细说明。

stm32f10x_rtc.c是关于RTC的库函数,stm32f10x_bkp.c是关于备份寄存器的库函数,stm32f10x_pwr.c是关于电源控制的库函数。

RTC配置代码如下:

void RTC_Init(u8 HH,u8 MM,u8 SS)
{
	NVIC_InitTypeDef NVIC_InitStructure;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP | RCC_APB1Periph_PWR, ENABLE);
	
	NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;//RTC全局中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
 
	PWR_BackupAccessCmd(ENABLE);//使能后备寄存器访问
	BKP_DeInit();//复位备份区域																		//复位备份区域
	RCC_LSICmd(ENABLE);//使能LSI时钟													
	while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == 0);//检查指定的RCC标志位设置值与否
	RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);//设置RTC时钟
	RCC_RTCCLKCmd(ENABLE);//使能RTC时钟  
	
	RTC_WaitForSynchro();//等待APB1时钟与RTC时钟同步
	RTC_WaitForLastTask();//等待最近一次对RTC寄存器的写操作完成
	
	RTC_ITConfig(RTC_IT_SEC, ENABLE);//使能RTC秒中断
	RTC_WaitForLastTask();
	
	RTC_SetPrescaler(40000-1);//设置分频
	RTC_WaitForLastTask();
	
	RTC_SetCounter(HH * 3600 + MM * 60 + SS);//设置初始时间
	RTC_WaitForLastTask();  
}

1.使能电源时钟和备份区域时钟:配置任何东西,第一件事使能时钟。我们要访问RTC和备份区域就必须先使能电源时钟和备份区域时钟。

2.设置RTC中断:调用NVIC_Init函数即可。

3.取消备份区写保护:要向备份区域写入数据,就要先取消备份区域写保护,否则后面无法对RTC进行读写。

4.复位备份区域,开启内部低速时钟:蓝桥杯嵌入式开发板上,我们只能使用LSI时钟源。

5.选择RTC时钟,并使能:相关函数在stm32f10x_rcc.c中。

6.等待APB1时钟与RTC时钟同步

7.RTC秒中断使能

8.设置RTC时钟分频数:LSI时钟频率约为40KHz,RTC需要1Hz的时钟,所以需要进行40000-1分频。

9.设置初始时间:其实就是设置RTC的计数值,时间与计数值之间是需要换算的。

接下来就要编写中断服务函数,写在stm32f10x_it.c中,代码如下:

extern u8 RTC_Flag;

void RTC_IRQHandler(void)
{
	if(RTC_GetFlagStatus(RTC_IT_SEC) == 1)
	{
		RTC_ClearITPendingBit(RTC_IT_SEC);
		RTC_Flag = 1;//时间更新标志位
		if(RTC_GetCounter() == 86400)
		{
			RTC_SetCounter(0);
			RTC_WaitForLastTask();
		}	
  }
}

在秒钟中断产生的时候,清除中断标志位,把时间更新标志位置1(用于在主函数计算时间并显示),当满足一天的时间,需要吧计数值清零。

主函数代码:

#include "stm32f10x.h"
#include "rtc.h"
#include "lcd.h"
#include "stdio.h"

u32 TimingDelay = 0;
void Delay_Ms(u32 nTime);

u8 RTC_Flag=0;
u32 Time_Total=0;
u8 Hour=0,Min=0,Sec=0;
u8 str[20];

//Main Body
int main(void)
{
	SysTick_Config(SystemCoreClock/1000);
	RTC_Init(23,59,55);
	STM3210B_LCD_Init();
	LCD_Clear(Blue);
	LCD_SetBackColor(Blue);
	LCD_SetTextColor(White);
	while(1)
	{
		if(RTC_Flag)
		{
			Time_Total = RTC_GetCounter(); //获取RTC寄存器值
			Hour = Time_Total / 3600;      //时
			Min  = Time_Total % 3600 / 60;	//分
			Sec  = Time_Total % 3600 % 60;	//秒
			RTC_Flag = 0;					//RTC标志位清空
			sprintf((char*)str,"%02d:%02d:%02d",Hour,Min,Sec);
			LCD_DisplayStringLine(Line2,str);
		}
	}
}
//1ms延时函数
void Delay_Ms(u32 nTime)
{
	TimingDelay = nTime;
	while(TimingDelay != 0);	
}

主函数中做的工作很简单,就是把获取的计数值分解为时、分、秒,并在LCD上显示出来。

  • 7
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值