前言
本文是基于嵌入式开发板CT117E,stm32f103RBT6。"空手套白狼"就是直接利用官方给的库(v3.5),进行拷贝修改形成可以正常运行的代码。
一、RTC初始化
1.rtc需要初始化两个结构体,一个中断控制器和自身的一个结构体。
2. 打开固件库的RTC文件夹里面有两个文件夹,先看LSI的那个,由于蓝桥杯的板子只能用LSI时钟,所以结构体的初始化参考这里面的。
3. 178行的void RTC_Configuration(void),整个复制过来用,只需把最后面2行去掉就ok了;中断控制器的结构体配置直接复制过来用。
STM32固件库代码V3.5版\STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\RTC\LSI_Calib\main.c
STM32固件库代码V3.5版\STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\RTC\Calendar\main.c h 和 stm32f10x_it.c
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Configure one bit for preemption priority */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
/* Enable the RTC Interrupt */
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);
}
void RTC_Configuration(void)
{
/* Enable PWR and BKP clocks */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
/* Allow access to BKP Domain */
PWR_BackupAccessCmd(ENABLE);
/* Reset Backup Domain */
BKP_DeInit();
/* Enable the LSI OSC */
RCC_LSICmd(ENABLE);
/* Wait till LSI is ready */
while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)
{}
/* Select the RTC Clock Source */
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
/* Enable RTC Clock */
RCC_RTCCLKCmd(ENABLE);
/* Wait for RTC registers synchronization */
RTC_WaitForSynchro();
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Enable the RTC Second */
RTC_ITConfig(RTC_IT_SEC, ENABLE);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Set RTC prescaler: set RTC period to 1sec */
RTC_SetPrescaler(40000);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* To output second signal on Tamper pin, the tamper functionality
must be disabled (by default this functionality is disabled) */
// BKP_TamperPinCmd(DISABLE);
/* Enable the RTC Second Output on Tamper Pin */
//BKP_RTCOutputConfig(BKP_RTCOutputSource_Second);
NVIC_Configuration();
}
二、RTC应用函数
1. 做一个实时时钟,还需要一些其他的函数,这个也可以直接复制固件库的,这个我们需要打开另外一个文件夹,main.c的270行的void Time_Adjust(void)这个函数需要修改一下,我们传入3个参数,分别是时,分,秒,然后把我们传入的时分秒变成秒数总和,改变时间戳,达到设置时间的功能。
void Time_Adjust(u8 THH,u8 TMM,u8 TSS)
{
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Change the current time */
RTC_SetCounter(THH*60*60+TMM*60+TSS);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
}
2. 285行的void Time_Display(uint32_t TimeVar)这个函数直接复制,这个函数的功能是读取目前的秒数,化成时分秒,这个函数的最后一行是用串口的形式展示时间,我这里不需要,把他给删掉了,这里我们需要把函数里面定义的三个变量,放到全局变量那里去,方便我们主函数的调用。
uint32_t THH , TMM , TSS;
void Time_Display(uint32_t TimeVar)
{
/* Reset RTC Counter when Time is 23:59:59 */
if (RTC_GetCounter() == 0x0001517F)
{
RTC_SetCounter(0x0);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
}
/* Compute hours */
THH = TimeVar / 3600;
/* Compute minutes */
TMM = (TimeVar % 3600) / 60;
/* Compute seconds */
TSS = (TimeVar % 3600) % 60;
//printf("Time: %0.2d:%0.2d:%0.2d\r", THH, TMM, TSS);
}
s
三、RTC中断函数
- 配置好和基本的功能后,还需要中断函数,这个也直接复制,我们只需要把calendar里的stm32f10x_it.c里的151行的中断函数复制出来用就好了,然后再把函数里面定义的 TimeDisplay,定义成全局变量就行;
void RTC_IRQHandler(void)
{
if (RTC_GetITStatus(RTC_IT_SEC) != RESET)
{
/* Clear the RTC Second interrupt */
RTC_ClearITPendingBit(RTC_IT_SEC);
/* Toggle LED1 */
//STM_EVAL_LEDToggle(LED1);
/* Enable time update */
TimeDisplay = 1;
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
}
}
四、RTC在主函数的应用
- 完成上面这些操作后,就是怎么显示时间的问题了,这个复制main.c里面的312行void Time_Show里的判断条件就行了。
if (TimeDisplay == 1)
{
/* Display current time */
Time_Display(RTC_GetCounter());
TimeDisplay = 0;
}
- 每秒进入一次中断,我们就更新时间,用Time_Display(RTC_GetCounter())。然后再把全局变量显示就行了;注意为了显示成00:00:00,这样的格式我们需要搞成%0.2d的格式;
sprintf((char *)time_buff,"Time: %0.2d:%0.2d:%0.2d" ,THH , TMM, TSS);