新网站制作市场,wordpress页面转文章,网站做多少分辨率,商业综合体设计RTC#xff1a;实时时钟 1、实时时钟2、闹钟中断3、秒中断4、输出功能5、BKP的读写6、BKP的侵入事件 1、实时时钟
①RTC.c
#include RTC.h/*** brief#xff1a;RTC初始化函数*/
RCC_PeriphCLKInitTypeDef RTCPeriphClkInit; //RTC时钟配置结构体
RTC_HandleT… RTC实时时钟 1、实时时钟2、闹钟中断3、秒中断4、输出功能5、BKP的读写6、BKP的侵入事件 1、实时时钟
①RTC.c
#include RTC.h/*** briefRTC初始化函数*/
RCC_PeriphCLKInitTypeDef RTCPeriphClkInit; //RTC时钟配置结构体
RTC_HandleTypeDef hrtc; //RTC配置结构体
void RTC_Init(void)
{/* 配置RTC的时钟源 */RTCPeriphClkInit.PeriphClockSelection RCC_PERIPHCLK_RTC; //需要配置的外设RTCRTCPeriphClkInit.RTCClockSelection RCC_RTCCLKSOURCE_LSE; //RTC时钟源LSE(外部低速时钟)HAL_RCCEx_PeriphCLKConfig(RTCPeriphClkInit);/* RTC的初始化配置 */__HAL_RCC_RTC_ENABLE(); //使能RTC的时钟__HAL_RCC_PWR_CLK_ENABLE(); //使能PWR的时钟__HAL_RCC_BKP_CLK_ENABLE(); //使能BKP的时钟hrtc.Instance RTC; //选择RTChrtc.Init.AsynchPrediv RTC_AUTO_1_SECOND; //时钟源的分频值,1Hzhrtc.Init.OutPut RTC_OUTPUTSOURCE_NONE; //无输出HAL_RTC_Init(hrtc);
}/*** briefHAL_RTC_Init()调用函数*/
void HAL_RTC_MspInit(RTC_HandleTypeDef *hrtc)
{/* 其他的配置 */
}/*** brief日期转换为时间戳秒函数*/
void Time_Set(int Year,int Mon,int Day,int Hour,int Min,int Sec)
{struct tm DayData; //定义结构体变量DayDataDayData.tm_year Year - 1900; //设置为2025年DayData.tm_mon Mon; //设置为1月DayData.tm_mday Day; //设置为2号DayData.tm_hour Hour; //设置为20时DayData.tm_min Min; //设置为04分DayData.tm_sec Sec; //设置为40秒time_t temp mktime(DayData); //将设置的日期转换为时间挫数据__HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); //关闭RTC写保护WRITE_REG(hrtc.Instance-CNTH,(temp 16)); //将转换好的时间挫写入RTC计数寄存器高16位WRITE_REG(hrtc.Instance-CNTL,temp 0x0000FFFF); //将转换好的时间挫写入RTC计数寄存器低16位__HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); //开启RTC写保护
}/*** brief将RTC中的计数器寄存器值转换为日期*/
struct tm* Time_Get(void)
{/* 读取数据寄存器的值 */time_t temp (READ_REG(hrtc.Instance-CNTH) 16) | READ_REG(hrtc.Instance-CNTL);/* 将计数器的值转换为日期 */return localtime(temp);//将时间戳转换为本地的年月日时分秒
}②RTC.h
#ifndef __RTC_H
#define __RTC_H#include stm32f1xx_hal.h
#include time.h
extern RTC_HandleTypeDef hrtc; //RTC配置结构体
void RTC_Init(void);
void Time_Set(int Year,int Mon,int Day,int Hour,int Min,int Sec);
struct tm* Time_Get(void);#endif③main.c
#include stm32f1xx_hal.h
#include STM32_RCC_Init.h
#include RTC.h
#include UART.hstruct tm* Day;
int main(void){HAL_Init();HSE_RCC_Init(); UART1_Init(115200);RTC_Init();printf(代码测试\r\n);Time_Set(2025,1,2,21,8,30);//2025-01-02 20:55:30while(1){Day Time_Get();printf(%d-%d-%d %d:%d:%d\r\n,Day-tm_year 1900,Day-tm_mon,Day-tm_mday,Day-tm_hour,Day-tm_min,Day-tm_sec);HAL_Delay(1000);}
}2、闹钟中断
①RTC.c
#include RTC.h/*** briefRTC初始化函数*/
RCC_PeriphCLKInitTypeDef RTCPeriphClkInit; //RTC时钟配置结构体
RTC_HandleTypeDef hrtc; //RTC配置结构体
void RTC_Init(void)
{/* 配置RTC的时钟源 */RTCPeriphClkInit.PeriphClockSelection RCC_PERIPHCLK_RTC; //需要配置的外设RTCRTCPeriphClkInit.RTCClockSelection RCC_RTCCLKSOURCE_LSE; //RTC时钟源LSE(外部低速时钟)HAL_RCCEx_PeriphCLKConfig(RTCPeriphClkInit);/* RTC的初始化配置 */__HAL_RCC_RTC_ENABLE(); //使能RTC的时钟__HAL_RCC_PWR_CLK_ENABLE(); //使能PWR的时钟__HAL_RCC_BKP_CLK_ENABLE(); //使能BKP的时钟hrtc.Instance RTC; //选择RTChrtc.Init.AsynchPrediv RTC_AUTO_1_SECOND; //时钟源的分频值,1Hzhrtc.Init.OutPut RTC_OUTPUTSOURCE_NONE; //无输出HAL_RTC_Init(hrtc);/* 开启闹钟中断 */__HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF); //清除闹钟标志__HAL_RTC_ALARM_ENABLE_IT(hrtc, RTC_IT_ALRA); //开启闹钟中断__HAL_RTC_ALARM_EXTI_ENABLE_IT(); //开启闹钟外部中断线EXTI17为闹钟事件__HAL_RTC_ALARM_EXTI_ENABLE_RISING_EDGE(); //上升沿触发HAL_NVIC_SetPriority(RTC_Alarm_IRQn,3,0);HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn);
}/*** briefHAL_RTC_Init()调用函数*/
void HAL_RTC_MspInit(RTC_HandleTypeDef *hrtc)
{/* 其他的配置 */
}/*** brief日期转换为时间挫函数*/
void Time_Set(int Year,int Mon,int Day,int Hour,int Min,int Sec)
{struct tm DayData; //定义结构体变量DayDataDayData.tm_year Year - 1900; //设置为2025年DayData.tm_mon Mon; //设置为1月DayData.tm_mday Day; //设置为2号DayData.tm_hour Hour; //设置为20时DayData.tm_min Min; //设置为04分DayData.tm_sec Sec; //设置为40秒time_t temp mktime(DayData); //将设置的日期转换为时间挫数据__HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); //关闭RTC写保护WRITE_REG(hrtc.Instance-CNTH,(temp 16)); //将转换好的时间挫写入RTC计数寄存器高16位WRITE_REG(hrtc.Instance-CNTL,temp 0x0000FFFF); //将转换好的时间挫写入RTC计数寄存器低16位__HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); //开启RTC写保护HAL_Delay(20); //等待写保护成功必须要有
}/*** brief闹钟时间转换为时间挫函数*/
void AlarmTime_Set(int Year,int Mon,int Day,int Hour,int Min,int Sec)
{struct tm DayData; //定义结构体变量DayDataDayData.tm_year Year - 1900; //设置为2025年DayData.tm_mon Mon; //设置为1月DayData.tm_mday Day; //设置为2号DayData.tm_hour Hour; //设置为20时DayData.tm_min Min; //设置为04分DayData.tm_sec Sec; //设置为40秒time_t temp mktime(DayData); //将设置的日期转换为时间挫数据__HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); //关闭RTC写保护WRITE_REG(hrtc.Instance-ALRH,(temp 16)); //将转换好的时间挫写入RTC闹钟寄存器高16位WRITE_REG(hrtc.Instance-ALRL,temp 0x0000FFFF); //将转换好的时间挫写入RTC闹钟寄存器低16位__HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); //开启RTC写保护HAL_Delay(20); //等待写保护成功必须要有
}/*** brief将RTC中的计数器寄存器值转换为日期*/
struct tm* Time_Get(void)
{/* 读取数据寄存器的值 */time_t temp (READ_REG(hrtc.Instance-CNTH) 16) | READ_REG(hrtc.Instance-CNTL);/* 将计数器的值转换为日期 */return localtime(temp);//将时间戳转换为本地的年月日时分秒
}②RTC.h
#ifndef __RTC_H
#define __RTC_H#include stm32f1xx_hal.h
#include time.h
extern RTC_HandleTypeDef hrtc; //RTC配置结构体
void RTC_Init(void);
void Time_Set(int Year,int Mon,int Day,int Hour,int Min,int Sec);
void AlarmTime_Set(int Year,int Mon,int Day,int Hour,int Min,int Sec);
struct tm* Time_Get(void);#endif③main.c
#include stm32f1xx_hal.h
#include STM32_RCC_Init.h
#include RTC.h
#include UART.hstruct tm* Day;
int main(void){HAL_Init();HSE_RCC_Init(); UART1_Init(115200);RTC_Init();printf(代码测试\r\n);Time_Set(2025,1,2,21,8,30); //2025-01-02 20:55:30AlarmTime_Set(2025,1,2,21,8,35); //闹钟时钟为2025-01-02 20:55:35while(1){Day Time_Get();printf(%d-%d-%d %d:%d:%d\r\n,Day-tm_year 1900,Day-tm_mon,Day-tm_mday,Day-tm_hour,Day-tm_min,Day-tm_sec);HAL_Delay(1000);}
}④stm32f1xx_it.c
#include stm32f1xx_hal.h
#include stm32f1xx_it.h
#include RTC.h
#include UART.h/*** briefRTC闹钟中断服务函数*/
void RTC_Alarm_IRQHandler(void)
{HAL_RTC_AlarmIRQHandler(hrtc);
}
/******************* 下面的中断的回调函数 ***************************/
/*** briefRTC闹钟中断回调函数函数*/
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
{printf(起床啦\r\n);
}3、秒中断
①RTC.c
#include RTC.h/*** briefRTC初始化函数*/
RCC_PeriphCLKInitTypeDef RTCPeriphClkInit; //RTC时钟配置结构体
RTC_HandleTypeDef hrtc; //RTC配置结构体
void RTC_Init(void)
{/* 配置RTC的时钟源 */RTCPeriphClkInit.PeriphClockSelection RCC_PERIPHCLK_RTC; //需要配置的外设RTCRTCPeriphClkInit.RTCClockSelection RCC_RTCCLKSOURCE_LSE; //RTC时钟源LSE(外部低速时钟)HAL_RCCEx_PeriphCLKConfig(RTCPeriphClkInit);/* RTC的初始化配置 */__HAL_RCC_RTC_ENABLE(); //使能RTC的时钟__HAL_RCC_PWR_CLK_ENABLE(); //使能PWR的时钟__HAL_RCC_BKP_CLK_ENABLE(); //使能BKP的时钟hrtc.Instance RTC; //选择RTChrtc.Init.AsynchPrediv RTC_AUTO_1_SECOND; //时钟源的分频值,1Hzhrtc.Init.OutPut RTC_OUTPUTSOURCE_NONE; //无输出HAL_RTC_Init(hrtc);/* 开启秒中断 */HAL_RTCEx_SetSecond_IT(hrtc); //开启秒中断HAL_NVIC_SetPriority(RTC_IRQn,3,0);HAL_NVIC_EnableIRQ(RTC_IRQn);
}/*** briefHAL_RTC_Init()调用函数*/
void HAL_RTC_MspInit(RTC_HandleTypeDef *hrtc)
{/* 其他的配置 */
}/*** brief日期转换为时间挫函数*/
void Time_Set(int Year,int Mon,int Day,int Hour,int Min,int Sec)
{struct tm DayData; //定义结构体变量DayDataDayData.tm_year Year - 1900; //设置为2025年DayData.tm_mon Mon; //设置为1月DayData.tm_mday Day; //设置为2号DayData.tm_hour Hour; //设置为20时DayData.tm_min Min; //设置为04分DayData.tm_sec Sec; //设置为40秒time_t temp mktime(DayData); //将设置的日期转换为时间挫数据__HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); //关闭RTC写保护WRITE_REG(hrtc.Instance-CNTH,(temp 16)); //将转换好的时间挫写入RTC计数寄存器高16位WRITE_REG(hrtc.Instance-CNTL,temp 0x0000FFFF); //将转换好的时间挫写入RTC计数寄存器低16位__HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); //开启RTC写保护HAL_Delay(20); //等待写保护成功必须要有
}/*** brief闹钟时间转换为时间挫函数*/
void AlarmTime_Set(int Year,int Mon,int Day,int Hour,int Min,int Sec)
{struct tm DayData; //定义结构体变量DayDataDayData.tm_year Year - 1900; //设置为2025年DayData.tm_mon Mon; //设置为1月DayData.tm_mday Day; //设置为2号DayData.tm_hour Hour; //设置为20时DayData.tm_min Min; //设置为04分DayData.tm_sec Sec; //设置为40秒time_t temp mktime(DayData); //将设置的日期转换为时间挫数据__HAL_RTC_WRITEPROTECTION_DISABLE(hrtc); //关闭RTC写保护WRITE_REG(hrtc.Instance-ALRH,(temp 16)); //将转换好的时间挫写入RTC闹钟寄存器高16位WRITE_REG(hrtc.Instance-ALRL,temp 0x0000FFFF); //将转换好的时间挫写入RTC闹钟寄存器低16位__HAL_RTC_WRITEPROTECTION_ENABLE(hrtc); //开启RTC写保护HAL_Delay(20); //等待写保护成功必须要有
}/*** brief将RTC中的计数器寄存器值转换为日期*/
struct tm* Time_Get(void)
{/* 读取数据寄存器的值 */time_t temp (READ_REG(hrtc.Instance-CNTH) 16) | READ_REG(hrtc.Instance-CNTL);/* 将计数器的值转换为日期 */return localtime(temp);//将时间戳转换为本地的年月日时分秒
}②RTC.h
#ifndef __RTC_H
#define __RTC_H#include stm32f1xx_hal.h
#include time.h
extern RTC_HandleTypeDef hrtc; //RTC配置结构体
void RTC_Init(void);
void Time_Set(int Year,int Mon,int Day,int Hour,int Min,int Sec);
void AlarmTime_Set(int Year,int Mon,int Day,int Hour,int Min,int Sec);
struct tm* Time_Get(void);#endif③main.c
#include stm32f1xx_hal.h
#include STM32_RCC_Init.h
#include RTC.h
#include UART.h
#include LED.hstruct tm* Day;
int main(void){HAL_Init();HSE_RCC_Init(); UART1_Init(115200);LED_GPIO_Init();RTC_Init();printf(代码测试\r\n);Time_Set(2025,1,2,21,8,30); //2025-01-02 20:55:30while(1){Day Time_Get();printf(%d-%d-%d %d:%d:%d\r\n,Day-tm_year 1900,Day-tm_mon,Day-tm_mday,Day-tm_hour,Day-tm_min,Day-tm_sec);HAL_Delay(1000);}
}④stm32f1xx_it.c
#include stm32f1xx_hal.h
#include stm32f1xx_it.h
#include RTC.h
#include UART.h
#include LED.h/*** briefRTC秒中断服务函数*/
void RTC_IRQHandler(void)
{HAL_RTCEx_RTCIRQHandler(hrtc);
}/******************* 下面的中断的回调函数 ***************************/
/*** briefRTC秒中断回调函数*/
void HAL_RTCEx_RTCEventCallback(RTC_HandleTypeDef *hrtc)
{LED_Turn();
}4、输出功能
①RTC.c文件需要修改的代码如下
hrtc.Init.OutPut RTC_OUTPUTSOURCE_SECOND; //输出秒脉冲
hrtc.Init.OutPut RTC_OUTPUTSOURCE_ALARM ; //输出闹钟脉冲
hrtc.Init.OutPut RTC_OUTPUTSOURCE_CALIBCLOCK; //输出32768Hz/64后的脉冲输出引脚是PC13但是不用配置它。其他的代码不用修改
5、BKP的读写
BKP的读写需要RTC的配置但是不需要开启LSE的时钟源。只需要打开RTC时钟配置RTC总控结构体 ①RTC.c文件的代码如下
#include RTC.h/*** briefRTC初始化函数*/
RTC_HandleTypeDef hrtc; //RTC配置结构体
void RTC_Init(void)
{ /* RTC的初始化配置 */__HAL_RCC_RTC_ENABLE(); //使能RTC的时钟__HAL_RCC_PWR_CLK_ENABLE(); //使能PWR的时钟__HAL_RCC_BKP_CLK_ENABLE(); //使能BKP的时钟hrtc.Instance RTC; //选择RTCHAL_RTC_Init(hrtc);
}/*** briefHAL_RTC_Init()调用函数*/
void HAL_RTC_MspInit(RTC_HandleTypeDef *hrtc)
{/* 其他的配置 */
}②main.c文件的代码如下
#include stm32f1xx_hal.h
#include STM32_RCC_Init.h
#include RTC.h
#include UART.huint16_t Data 0x1234;
int main(void){HAL_Init();HSE_RCC_Init(); UART1_Init(115200);RTC_Init(); //初始化BKPprintf(代码测试\r\n);HAL_RTCEx_BKUPWrite(hrtc, 1, Data); //向BKP的第一个数据寄存器写入数据printf(%x\r\n,HAL_RTCEx_BKUPRead(hrtc, 1)); //读取BKP的第一个数据寄存器的数据while(1){}
}6、BKP的侵入事件
若发生了侵入事件会将BKP中的数据清除主电源断电侵入事件也有效。侵入事件检测引脚为PC13且检测电平。但是我们不用配置PC13。 当侵入事件产生后应该先关闭侵入检测。需要侵入检测则重新调用API函数开启侵入检测。 ①RTC.c文件的代码如下
#include RTC.h/*** briefRTC初始化函数*/
RTC_HandleTypeDef hrtc; //RTC配置结构体
RTC_TamperTypeDef Tamper; //侵入事件配置结构体
void RTC_Init(void)
{ /* RTC的初始化配置 */__HAL_RCC_RTC_ENABLE(); //使能RTC的时钟__HAL_RCC_PWR_CLK_ENABLE(); //使能PWR的时钟__HAL_RCC_BKP_CLK_ENABLE(); //使能BKP的时钟hrtc.Instance RTC; //选择RTCHAL_RTC_Init(hrtc);/* 侵入事件配置 */Tamper.Tamper RTC_TAMPER_1; //指定引脚PC13Tamper.Trigger RTC_TAMPERTRIGGER_HIGHLEVEL; //高电平触发HAL_RTCEx_SetTamper_IT(hrtc,Tamper); //配置侵入事件开启中断HAL_NVIC_SetPriority(TAMPER_IRQn,3,0);HAL_NVIC_EnableIRQ(TAMPER_IRQn);
}②main.c文件的代码如下
#include stm32f1xx_hal.h
#include STM32_RCC_Init.h
#include RTC.h
#include UART.huint16_t Data 0x1234;
int main(void){HAL_Init();HSE_RCC_Init(); UART1_Init(115200);RTC_Init(); //初始化BKP,初始化侵入事件printf(代码测试\r\n);HAL_RTCEx_BKUPWrite(hrtc, 1, Data); //向BKP的第一个数据寄存器写入数据printf(%x\r\n,HAL_RTCEx_BKUPRead(hrtc, 1)); //读取BKP的第一个数据寄存器的数据while(1){}
}③stm32f1xx_it.c文件的代码如下
#include stm32f1xx_hal.h
#include stm32f1xx_it.h
#include RTC.h
#include UART.h/*** briefRTC侵入事件中断服务函数*/
void TAMPER_IRQHandler(void)
{HAL_RTCEx_TamperIRQHandler(hrtc);
}/******************* 下面的中断的回调函数 ***************************/
/*** briefRTC侵入中断回调函数*/
void HAL_RTCEx_Tamper1EventCallback(RTC_HandleTypeDef *hrtc)
{printf(发生侵入事件了\r\n);HAL_RTCEx_DeactivateTamper(hrtc, RTC_TAMPER_1);//关闭侵入事件
}