版权声明:转载记得声明~~~ :) https://blog.csdn.net/ReCclay/article/details/87603212
工程可见Github<传送门>
一、主要代码
main.c
/*******************************************************************************
* 文件名:main.c
* 描 述:
* 作 者:CLAY
* 版本号:v1.0.0
* 日 期: 2019年2月18日
* 备 注:修改后的LCD例程
* RTC显示到LCD上,并注意到24:00:00的特殊处理!
*******************************************************************************
*/
#include "stm32f10x.h"
#include "lcd.h"
#include "e2prom.h"
#include "stdio.h"
#include "i2c.h"
#include "adc.h"
#include "rtc.h"
u32 TimingDelay = 0;
void Delay_Ms(u32 nTime);
u8 RTC_Flag = 0;
u32 time = 0;
u8 hour, min, sec;
//Main Body
int main(void)
{
u8 str[20];
STM3210B_LCD_Init();
LCD_Clear(Blue);
LCD_SetBackColor(Blue);
LCD_SetTextColor(White);
SysTick_Config(SystemCoreClock/1000);
RTC_Init(23, 59, 55);
while(1)
{
if(RTC_Flag)
{
RTC_Flag = 0;
time = RTC_GetCounter();
RTC_WaitForLastTask();
if(time == 24 * 3600)
{
RTC_SetCounter(1);//特殊处理下,不至于到0的时候卡顿。
RTC_WaitForLastTask();
LCD_DisplayStringLine(Line5, " 00:00:00 ");
}
else
{
hour = time / 3600;
min = time % 3600 / 60;
sec = time % 3600 % 60;
sprintf((char *)str, " %.2d:%.2d:%.2d ", hour, min, sec);
LCD_DisplayStringLine(Line5, str);
}
}
}
}
//
void Delay_Ms(u32 nTime)
{
TimingDelay = nTime;
while(TimingDelay != 0);
}
rtc.c
#include "stm32f10x.h"
void RTC_Init(u8 HH, u8 MM, u8 SS)
{
NVIC_InitTypeDef NVIC_InitStructure;
//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);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);//使能PWR和BKP时钟
PWR_BackupAccessCmd(ENABLE);//使能BKP
BKP_DeInit();//BKP复位
RCC_LSICmd(ENABLE);//使能LSI时钟
while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);//等待时钟使能完毕
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);//选择LSI作为RTC时钟源
RCC_RTCCLKCmd(ENABLE);//使能RTC时钟
RTC_WaitForSynchro();//等待APB1时钟和RTC时钟同步
RTC_WaitForLastTask();
RTC_ITConfig(RTC_IT_SEC, ENABLE);//使能秒中断
RTC_WaitForLastTask();
RTC_SetPrescaler(40000-1);//LSI时钟40K
RTC_WaitForLastTask();
RTC_SetCounter(HH * 3600 + MM * 60 + SS);//设置RTC时间
RTC_WaitForLastTask();
}
rtc.h
#ifndef _RTC_H
#define _RTC_H
void RTC_Init(u8 HH, u8 MM, u8 SS);
#endif
stm32f10x_it.c
extern u8 RTC_Flag;
void RTC_IRQHandler(void)
{
if(RTC_GetITStatus(RTC_IT_SEC) == 1)
{
RTC_ClearITPendingBit(RTC_IT_SEC);
RTC_Flag = 1;
}
}
二、注意事项
1、RTC首先要注意,配置RTC前要配置好PWR时钟和BKP时钟,并使能BKP然后复位。
2、蓝桥板子的RTC时钟必须使用LSI时钟
3、如果忘记RTC对应中断函数名称则从启动文件中寻找
4、可参考例程路径
嵌入式设计与开发项目加密资料\嵌入式设计与开发\STM32固件库v3.5\stm32f10x_stdperiph_lib\STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\RTC\LSI_Calib\main.c
5、参考例程中需要添加的东西
初始化配置
RTC_SetCounter(HH * 3600 + MM * 60 + SS);//设置RTC时间
RTC_WaitForLastTask();
6、到达24:00:00
要进行特殊处理
注意此时要设置计数器为1!
7、关于秒中断中的判断if(RTC_GetITStatus(RTC_IT_SEC) == 1)
如果函数想不起可通过溯源的方式查找函数名,<蓝桥嵌入式之 ADC_Again>行文中有过详细介绍,这里不再赘述。
8、时间显示最好加上宽度控制格式符%.2d
sprintf((char *)str, " Time: %.2d-%.2d-%.2d ", HH, MM, SS);
//这里加上格式控制符.2d是最好的!