【蓝桥杯嵌入式】【STM32】7_RTC之实时时间显示和硬件闹钟设置
文章目录
- 1、RTC的三个可用时钟源
- 2、RTC框图
- 3、写代码前需要知道的一些标志位
- 4、配置流程
- 5、源代码
- 6、关于设置闹钟这件事
- 6.1、配置流程
- 6.2、实验源代码
下载工程文件:
https://gitee.com/Joseph_Cooper/blue-bridge-embedded
1、RTC的三个可用时钟源
系统时钟框图中的RTC部分:
RTC可选时钟源:
特别说明:
蓝桥杯嵌入式开发板CT117E
只能使用LSI
即内置RC
振荡器。
2、RTC框图
3、写代码前需要知道的一些标志位
RTOFF
:
0:上一次对RTC的写操作仍在进行
1:上一次对RTC的写操作已经结束
CNF
:
0:不允许配置
1:允许配置
RSF
:
0:寄存器尚未被同步
1:寄存器已经被同步
只有被同步后才能正常读取数据
注:了解标志位只是为了更好的理解工作流程在库函数开发中不涉及具体操作。
因为这些标志位的存在所以在使用库函数的时候有了这两个函数:
RTC_WaitForLastTask();//等待最近一次对 RTC 寄存器的写操作完成
RTC_WaitForSynchro();//等待APB1时钟和RTC时钟同步
4、配置流程
1)使能电源时钟和备份区域时钟。
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
2)取消备份区写保护。
PWR_BackupAccessCmd(ENABLE); //使能 RTC 和后备寄存器访问
3)复位备份区域,开启LSI振荡器。
BKP_DeInit();//复位备份区域
RCC_LSICmd(ENABLE); //开启LSI振荡器。
4)选择 RTC 时钟,并使能。
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); //选择LSI作为时钟源
RCC_RTCCLKCmd(ENABLE); //使能RTC时钟
5)设置 RTC 的分频,以及配置 RTC 时钟。
RTC_EnterConfigMode();/// 允许配置
RTC_ExitConfigMode();//退出配置模式,更新配置
void RTC_SetPrescaler(uint32_t PrescalerValue);//设置 RTC 时钟分频数
void RTC_ITConfig(uint16_t RTC_IT, FunctionalState NewState);//设置秒中断允许
RTC_ITConfig(RTC_IT_SEC, ENABLE); //使能 RTC 秒中断
void RTC_SetCounter(uint32_t CounterValue)//是设置时间
6)更新配置,设置 RTC 中断分组。
RTC_ExitConfigMode();//退出配置模式,更新配置
注:以下函数比赛时可不用
//在退出配置模式更新配置之后我们在备份区域 BKP_DR1 中写入 0X5050 代表我们已经初始化过时钟了,下次开机(或复位)的时候,先读取 BKP_DR1 的值,然后判断是否是 0X5050 来决定是不是要配置。
void BKP_WriteBackupRegister(uint16_t BKP_DR, uint16_t Data);//往备份区域写用户数据的函数
uint16_t BKP_ReadBackupRegister(uint16_t BKP_DR);读备份区域内数据的函数
5、源代码
main.c
:
#include "Headfile.h"void Delay_Ms(u32 nTime);
u32 TimingDelay = 0;//Main Body
int main(void)
{SysTick_Config(SystemCoreClock/1000);Delay_Ms(200);STM3210B_LCD_Init();LCD_Clear(Blue);LCD_SetBackColor(Blue);LCD_SetTextColor(White);RTCInit(23,59,55);while(1);
}//
void Delay_Ms(u32 nTime)
{TimingDelay = nTime;while(TimingDelay != 0);
}
RTC.c
:
#include "Headfile.h"void RTCInit(u8 Hour,u8 Min,u8 Sec)
{//中断配置NVIC_InitTypeDef NVIC_InitStructure;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_BKP|RCC_APB1Periph_PWR,ENABLE);//使能电源时钟和备份区域时钟PWR_BackupAccessCmd(ENABLE);//取消备份区写保护BKP_DeInit();//复位备份区域RCC_LSICmd(ENABLE);//开启LSI震荡器while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);//等待时钟使能完毕RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); //选择LSI作为时钟源RCC_RTCCLKCmd(ENABLE);//使能RTC时钟//RTC配置RTC_WaitForLastTask();//等待最近一次对 RTC 寄存器的写操作完成RTC_WaitForSynchro();//等待APB1时钟和RTC时钟同步RTC_WaitForLastTask();RTC_EnterConfigMode();RTC_WaitForLastTask();RTC_SetPrescaler(40000-1);//设置预分频系数RTC_WaitForLastTask();RTC_ITConfig(RTC_IT_SEC,ENABLE);//使能RTC秒中断RTC_WaitForLastTask();RTC_SetCounter(Hour*3600 + Min*60 + Sec);//设置时间RTC_ExitConfigMode();
}void RTCtoTFT()
{u32 Time = 0;u8 Hour = 0,Min = 0,Sec = 0;u8 str[20];Time = RTC_GetCounter();RTC_WaitForLastTask();if(Time == (23*3600 + 59*60 + 59)){RTC_SetCounter(0);RTC_WaitForLastTask();}Hour = Time / 3600;Min = (Time % 3600) / 60;Sec = (Time % 3600) % 60;sprintf((char *)str,"%.2d:%.2d:%.2d", Hour, Min, Sec);LCD_DisplayStringLine(Line5,str);}
stm32f10x_it.c
/********************************************************************************* @file I2S/SPI_I2S_Switch/stm32f10x_it.c * @author MCD Application Team* @version V3.5.0* @date 08-April-2011* @brief Main Interrupt Service Routines.* This file provides template for all exceptions handler and peripherals* interrupt service routine.******************************************************************************* @attention** THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.** <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>*******************************************************************************//* Includes ------------------------------------------------------------------*/
#include "Headfile.h"extern u32 TimingDelay;/** @addtogroup STM32F10x_StdPeriph_Examples* @{*//** @addtogroup I2S_SPI_I2S_Switch* @{*/ /* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*//******************************************************************************/
/* Cortex-M3 Processor Exceptions Handlers */
/******************************************************************************//*** @brief This function handles NMI exception.* @param None* @retval None*/
void NMI_Handler(void)
{
}/*** @brief This function handles Hard Fault exception.* @param None* @retval None*/
void HardFault_Handler(void)
{/* Go to infinite loop when Hard Fault exception occurs */while (1){}
}/*** @brief This function handles Memory Manage exception.* @param None* @retval None*/
void MemManage_Handler(void)
{/* Go to infinite loop when Memory Manage exception occurs */while (1){}
}/*** @brief This function handles Bus Fault exception.* @param None* @retval None*/
void BusFault_Handler(void)
{/* Go to infinite loop when Bus Fault exception occurs */while (1){}
}/*** @brief This function handles Usage Fault exception.* @param None* @retval None*/
void UsageFault_Handler(void)
{/* Go to infinite loop when Usage Fault exception occurs */while (1){}
}/*** @brief This function handles Debug Monitor exception.* @param None* @retval None*/
void DebugMon_Handler(void)
{
}/*** @brief This function handles SVCall exception.* @param None* @retval None*/
void SVC_Handler(void)
{
}/*** @brief This function handles PendSV_Handler exception.* @param None* @retval None*/
void PendSV_Handler(void)
{
}/*** @brief This function handles SysTick Handler.* @param None* @retval None*/
void SysTick_Handler(void)
{TimingDelay--;
}
//
void RTC_IRQHandler(void)
{if(RTC_GetITStatus(RTC_IT_SEC) == 1){RTC_ClearITPendingBit(RTC_IT_SEC);RTCtoTFT();}
}
//
/******************************************************************************/
/* STM32F10x Peripherals Interrupt Handlers */
/* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */
/* available peripheral interrupt handler's name please refer to the startup */
/* file (startup_stm32f10x_xx.s). */
/******************************************************************************//*** @brief This function handles PPP interrupt request.* @param None* @retval None*/
/*void PPP_Switch_IRQHandler(void)
{
}*//*** @}*/ /*** @}*/ /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
6、关于设置闹钟这件事
6.1、配置流程
1)配置RTCAlarm_IRQn
中断,优先级一定要高于RTC
全局中断。
2)配置EXTI17
上升沿触发。
3)进入RTC
配置模式启动闹钟中断,设置闹钟事件再退出RTC
配置模式。
4)编写RTC_Alarm_IRQHandler
函数。
6.2、实验源代码
于23:59:59
产生闹钟,蜂鸣器响3S
后退出:
RTC.c:
#include "Headfile.h"u8 HourAla = 0;
u8 MinAla = 0;
u8 SecAla = 0;//实时时钟配置函数
void RTCInit(u8 Hour,u8 Min,u8 Sec)
{//时钟中断配置NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);//闹钟中断配置NVIC_InitStructure.NVIC_IRQChannel = RTCAlarm_IRQn; //闹钟中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //比RTC全局中断的优先级高NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure);//时钟电源配置RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP|RCC_APB1Periph_PWR,ENABLE);//使能电源时钟和备份区域时钟PWR_BackupAccessCmd(ENABLE);//取消备份区写保护BKP_DeInit();//复位备份区域RCC_LSICmd(ENABLE);//开启LSI震荡器while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);//等待时钟使能完毕RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); //选择LSI作为时钟源RCC_RTCCLKCmd(ENABLE);//使能RTC时钟//RTC配置RTC_WaitForLastTask();//等待最近一次对 RTC 寄存器的写操作完成RTC_WaitForSynchro();//等待APB1时钟和RTC时钟同步RTC_WaitForLastTask();RTC_EnterConfigMode();//进入配置模式RTC_WaitForLastTask();RTC_SetPrescaler(40000-1);//设置预分频系数RTC_WaitForLastTask();RTC_ITConfig(RTC_IT_SEC,ENABLE);//使能RTC秒中断RTC_WaitForLastTask();RTC_SetCounter(Hour*3600 + Min*60 + Sec);//设置时间RTC_ExitConfigMode();//退出配置模式
}
//闹钟外部中断配置
void AlarmEXITInit()
{EXTI_InitTypeDef EXTI_InitStructure;EXTI_ClearITPendingBit(EXTI_Line17);EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Line = EXTI_Line17;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure);
}
//闹钟设置函数
void AlarmSet(u8 Hour,u8 Min,u8 Sec)
{RTC_EnterConfigMode();//进入配置模式RTC_WaitForLastTask();RTC_ITConfig(RTC_IT_ALR,ENABLE);RTC_WaitForLastTask();RTC_SetAlarm(Hour*3600 + Min*60 + Sec);RTC_WaitForLastTask(); //等待最近一次对RTC寄存器的写操作完成RTC_ExitConfigMode();//退出配置模式HourAla = Hour;MinAla = Min;SecAla = Sec;
}
//秒中断服务函数
void RTC_IRQHandler(void)
{static u8 Cnt = 0;if(RTC_GetITStatus(RTC_IT_SEC) == 1)//秒中断{RTC_ClearITPendingBit(RTC_IT_SEC);//清除秒中断标志if(AlarmFlag == 1)//监控蜂鸣器响3Sec{Cnt ++;if(Cnt > 3){BuzzerReset;//关闭BuzzerAlarmFlag = 0;RTCtoTFT(AlaFlag);//刷新时间Cnt = 0;}else{RTCtoTFT(AlaFlag);//刷新时间}}else{RTCtoTFT(SecFlag);//刷新时间}}
}
//闹钟中断服务函数
void RTCAlarm_IRQHandler(void)
{ if(RTC_GetITStatus(RTC_IT_ALR) == 1)//闹钟中断{RTC_ClearITPendingBit(RTC_IT_ALR);//清除闹钟中断AlarmFlag = 1;BuzzerSet;}EXTI_ClearITPendingBit(EXTI_Line17);RTC_WaitForLastTask();RTC_ClearITPendingBit(RTC_IT_ALR);RTC_WaitForLastTask();
}
//LCD刷新函数
void RTCtoTFT(u8 Flag)
{u32 Time = 0;u8 Hour = 0,Min = 0,Sec = 0;u8 str[20];Time = RTC_GetCounter();RTC_WaitForLastTask();if(Time >= (23*3600 + 59*60 + 59)){RTC_SetCounter(0);RTC_WaitForLastTask();}Hour = Time / 3600;Min = (Time % 3600) / 60;Sec = (Time % 3600) % 60;sprintf((char *)str,"%.2d:%.2d:%.2d", Hour, Min, Sec);LCD_DisplayStringLine(Line5,str);if(Flag == AlaFlag){if(AlarmFlag == 1)//闹钟启动{sprintf((char *)str,"AlarmTime:%.2d:%.2d:%.2d", HourAla, MinAla, SecAla);LCD_DisplayStringLine(Line6,str);//显示闹钟时间字符串}else if(AlarmFlag == 0)//闹钟结束{LCD_ClearLine(Line6);//清除闹钟时间字符串}}
}
main.c:
#include "Headfile.h"void Delay_Ms(u32 nTime);
u32 TimingDelay = 0;
u8 AlarmFlag = 0;//Main Body
int main(void)
{SysTick_Config(SystemCoreClock/1000);Delay_Ms(200);LEDInit();//LED初始化//关闭所有LEDLEDCmd(Bit_SET);GPIO_Write(GPIOC,GPIO_ReadOutputData(GPIOC) | 0xFF00);LEDCmd(Bit_RESET);STM3210B_LCD_Init();LCD_Clear(Blue);LCD_SetBackColor(Blue);LCD_SetTextColor(White);BuzzerInit();//蜂鸣器初始化RTCInit(23,59,55);//实时时钟初始化AlarmEXITInit();AlarmSet(23,59,59);while(1);
}//
void Delay_Ms(u32 nTime)
{TimingDelay = nTime;while(TimingDelay != 0);
}
【蓝桥杯嵌入式】【STM32】7_RTC之实时时间显示和硬件闹钟设置相关推荐
- stm32入门学什么板子_“蓝桥杯”嵌入式stm32开发入门(1)概述
声明:笔者绝不是给"蓝桥杯"打广告,而是笔者曾经参加过蓝桥杯嵌入式设计与开发比赛,想借此机会总结并分享自己的学习中的点点滴滴. 此系列教程将以蓝桥杯官方指定的开发板和接口板来深入浅 ...
- 蓝桥杯嵌入式STM32 G431 HAL库开发速成指南(1)LED
本教程适用于报名参加蓝桥杯嵌入式用新开发板(G431)且想要快速开发的小白,不具体讲解复杂的原理,只讲Cubemx初始化配置以及在KEIL里面使用相应的库函数功能对外设进行编程. CUBEMX配置流程 ...
- 【Pre蓝桥杯嵌入式】【STM32】学习索引
写在前面 0.专栏链接 1.Unkown device 2.移植LCD程序+建立工程+LCD程序分析 3.如何直接使用LCD例程来作为赛场使用的工程 学习目录 ...
- 国信长天蓝桥杯嵌入式类——stm32——使用keil4建立工程文件过程
蓝桥杯嵌入式----使用keil4建立工程文件过程 目录 蓝桥杯嵌入式----使用keil4建立工程文件过程 一.完成文件建立 (一).先建立名为test工程文件夹,如图.并建立如下几个文件夹 (二) ...
- 第九届蓝桥杯-嵌入式比赛体会与备赛经验
原文地址:http://www.cnblogs.com/NickQ/p/8721317.html 说起蓝桥杯,相信很多电子类的学生,应该很熟悉了吧...上周日,我也去湖北工业大学参与了一下.说起这次经 ...
- 蓝桥杯嵌入式开发经验分享(1.嵌入式学习准备)
蓝桥杯嵌入式学习准备 ...
- 蓝桥杯嵌入式第十二届省赛真题
第十二届蓝桥杯嵌入式-停车计费 文章目录 第十二届蓝桥杯嵌入式-停车计费 1.题目分析 2.项目结构 2.1停车部分整体流程 2.2串口数据解析流程 2.3细节部分 3.代码结构 3.1停车部分 3. ...
- 蓝桥杯嵌入式类比赛经验分享
第八届蓝桥杯大赛(嵌入式组) 蓝桥杯的嵌入式组是Stm32rbt6单片机的编程比赛,我想对于学习电子信息工程专业的同学这不是一个陌生的名词,如果你是电信专业的大四同学却没有听说过msp430或者stm ...
- 突击蓝桥杯嵌入式(六)——第十届省赛真题
突击蓝桥杯嵌入式(六)--第十届省赛真题 一.题干 二.题目分析 考点1.ADC(没啥好说的) 占用引脚PB15(R37) 考点2:按键4个(PB0,PB1,PB2,PA0) 考点3:LCD,高亮 考 ...
最新文章
- 怎么把PDF格式改成EXCEL
- dingo php,详细介绍Laravel+Dingo/Api 自定义响应
- SSH登录太慢(等很久才提示输入密码)的问题
- 【3D游戏建模】3D建模师的发展前景
- +++++++子域授权与编译安装(一)
- 如何在Mac上使用Memoji贴纸、屏幕效果、应用程序和Messages
- build.xml:391: javac doesn‘t support the “nativeheaderdir“ attribute
- Python模块:win32com用法详解
- 电气自动化专业英文词汇及缩写
- Redis布隆过滤器和布谷鸟过滤器
- VMware虚拟机网络设置
- Hive架构及相关函数
- 实验四——DPCM编码(1bit、2bit、4bit、8bit量化)
- VR中的9轴传感器(重力加速度/陀螺仪/磁力计)
- 考研【真题】一些名校的部分真题(侵权请通知我删除)
- Android7.1 源码修改之Settings音量调节界面增加通话音量调节
- 【oracle数据库数据恢复】技术人员误操作导致的oracle数据库误删除后的数据恢复
- DataTable 实现新增加合计行
- 小米手机四种刷机方法
- 【身份证识别】形态学二代身份证号码识别系统【含GUI源码 948期】
热门文章
- python调用系统命令_Python调用外部系统命令
- php 5.0打印数据库,thinkphp5.0数据库操作
- java 读写分离 mvc_spring MVC、mybatis配置读写分离
- django解决NameError: name ‘_mysql‘ is not defined 或 mysqlclient 1.4.0 or newer is required报错
- 解决Ubuntu make 命令 sudo: make: command not found
- python3打印不换行
- python 拆分list,按照对应位置重组
- mysql多表删除操作_MySQL多表删除的实现
- MySQL8web安装_mysql 8.0.18 安装配置图文教程
- ssm(Spring、Springmvc、Mybatis)实战之淘淘商城-第四天(非原创)