对于蓝桥杯嵌入式比赛中的RTC部分呢,也经常考,其实就是一个实时时钟,配置起来也比较容易,偷懒的话,可以直接复制粘贴赛场提供的例程程序。
它需要有RTC配置、中断NVIC配置和时间显示,程序如下:
u8 TimeDisplay=0;
void RTC_Configuration(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
PWR_BackupAccessCmd(ENABLE);
BKP_DeInit();
RCC_LSICmd(ENABLE);
while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)
{}
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
RCC_RTCCLKCmd(ENABLE);
RTC_WaitForSynchro();
RTC_WaitForLastTask();
RTC_ITConfig(RTC_IT_SEC, ENABLE);
RTC_WaitForLastTask();
RTC_SetPrescaler(39999);
RTC_WaitForLastTask();
RTC_SetCounter(HH*3600+MM*60+SS);
RTC_WaitForLastTask();
}
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
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);
}
u8 Text[20];
void Time_Display(u32 TimeVar)
{
u32 THH = 0,TMM = 0,TSS = 0;
THH = TimeVar / 3600;
TMM = (TimeVar % 3600) / 60;
TSS = (TimeVar % 3600) % 60;
sprintf((char*)Text,"Time:%2d:%2d:%2d",THH,TMM,TSS);
LCD_DisplayStringLine(Line7,Text);
}
比赛的时候,RTC和NVIC配置函数是可以直接抄过来的,我们只需要写一个时间显示函数Time_Display(u32 TimeVar)
,这个函数的参数就是通过RTC_GetCounter()
函数得到的,即获取当前RTC内部计数器的计数值,然后将其转化为24小时制,通过LCD显示出来。一般情况下,我们是通过检测秒触发中断RTC_IT_SEC
来刷新LCD显示的,这也符合我们日常时钟表的规律,即一秒变化一次。中断函数是写在stm32f10x.it.c
里面的,中断函数如下:
void RTC_IRQHandler(void)
{
if(RTC_GetFlagStatus(RTC_IT_SEC) != RESET)
{
RTC_ClearITPendingBit(RTC_IT_SEC);
TimeDisplay = 1;
RTC_WaitForLastTask();
if(RTC_GetCounter() == 0x00015180)
{
RTC_SetCounter(0x0);
RTC_WaitForLastTask();
}
}
}
秒中断服务函数的主要任务就是改变标志位TimeDisplay
的值,然后清除秒中断标志位,然后就是需要判断一下有没有达到`23:59:59 ,即:
if(RTC_GetCounter() == 0x00015180)
如果达到了此计数值,那么由于时间是24小时制,那么下一个时间点应该是0:0:0
,所以需要对计数值清零。
注意中断服务函数的函数名字一定不要写错,写错了,编译仍然会通过,但是它是进不了中断服务函数的,没办法,stm32就是这样,所有的中断服务函数的名字都是固定的。
我们在中断服务函数里面改变标志位的状态,然后在主函数中通过检测这个标志位来进行刷新LCD显示,主函数程序如下:
while(1)
{
if(TimeDisplay == 1)
{
Time_Display(RTC_GetCounter());
TimeDisplay = 0;
}
}
综上,RTC配置还是很容易的,一般不会出什么幺蛾子。还有就是比赛的时候一般都会有时间初值,这个初值我们是在RTC配置函数里面写的,这两行程序比赛提供的例程里面是没有的,需要我们自己添加,即:
RTC_SetCounter(HH*3600+MM*60+SS);
RTC_WaitForLastTask();
其中HH、MM、SS
就是设定的初试时间值:(23:59:50)
#define HH 23
#define MM 59
#define SS 50
还有就是关于数值显示的:
sprintf((char*)Text,"Time:%2d:%2d:%2d",THH,TMM,TSS);
这个就是C语言的知识了,可以自己去试一下,改变%2d中的数值,看一下LCD上显示的有什么变化。