引子
RTC好像考的并不多,而且RTC也可以用滴答定时器实现。不过RTC既然是专门定时的外设,还是学了一下不怎么难。
驱动编写
参考例程STM32F10x_StdPeriph_Examples\RTC\LSI_Calib main.c
复制RTC_Configuration(void)和NVIC_Configuration(void)
RTC_Configuration(void)去掉最后两行,添加初始化设定函数RTC_SetCounter(uint32_t CounterValue)
中断服务函数
STM32F10x_StdPeriph_Examples\RTC\LSI_Calib stm32f10x_it.c
标准库常用函数
void RTC_SetCounter(uint32_t CounterValue); //初始化设定时间
uint32_t RTC_GetCounter(void); //获取当前时间
数据处理和现实
为了方便,数据处理使用了结构体分别存放时分秒。会在最后代码体现,这里贴一下之前关于学习结构体对Struct和typedef Struct的总结。
数据显示用到sprintf()函数,用法可以自行百度。这里贴出来整理的关于输出格式符的一些用法总结。
高亮显示
高亮分为字体高亮和背景高亮,两个用法一样,只是设置背景/文本色函数一处不同
利用官方提供的LCD函数编写函数,主要用到设置背景色函数LCD_SetBackColor()、设置文本色函数LCD_SetTextColor()写字节LCD_DisplayChar()
每次操作之前需要 设置背景色/文本色 再写即可(这里需要分块写,否则在main函数while里循环会出现切换颜色频闪,后面提到的函数是利用了这一思想)
代码
#include "rtc.h"
#include "lcd.h"
#include "stdio.h"
u32 Time = 23*3600+59*60+55;
typedef struct
{
u8 hour;
u8 min;
u8 sec;
}_Calendar;
_Calendar Calendar;
void RTC_Init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
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(Time);
}
void RTC_IRQHandler(void)
{
if (RTC_GetITStatus(RTC_IT_SEC) != RESET)
{
if(RTC_GetCounter()==86400-1)
RTC_SetCounter(0x00);
RTC_ClearITPendingBit(RTC_FLAG_SEC);
}
}
void RTC_Show(void)
{
u32 time;
u8 str[20];
time=RTC_GetCounter();
Calendar.hour=time/3600;
Calendar.min=time/60%60;
Calendar.sec=time%60;
sprintf((char*)str," Time:%02d-%02d-%02d ",Calendar.hour,Calendar.min,Calendar.sec);
// LCD_DisplayStringLine(Line6,str);
Highlight(str,9,16);
}
void Highlight(u8 *str,u8 start,u8 end)
{
u8 i;
for(i=0;i<20;i++)
{
if(i<start||i>end)
LCD_DisplayChar(Line6,(320 - (16 * i)),str[i]);
}
LCD_SetBackColor(Green);
for(i=start;i<=end;i++)
LCD_DisplayChar(Line6,(320 - (16 * i)),str[i]);
LCD_SetBackColor(Blue);
}
效果图
常见问题
1.例程使用的LSI即低速内部时钟,频率40K。之前自己写代码尝试使用告诉外部时钟貌似这块板子不支持,也可能没有外部晶振。
2.需要添加的标准库函数
3.如果要利用中断服务函数更新时间需要配置中断。