STM32基础10--实时时钟(RTC)

发布者:sigma28最新更新时间:2022-07-22 来源: csdn关键字:STM32  实时时钟  RTC 手机看文章 扫描二维码
随时随地手机看文章

前言

        在做51单片机项目时,如果需要年月日时分秒的时间记录,会在51单片机上面外挂一个DS1302的时钟芯片,再加上时间芯片的外围电路。但在STM32F407中,不再需要这么干了,因为在STM32的内部就已经集成了年月日时分秒的时钟电路--也就是实时时钟(RTC)


RTC框图

        下图是RTC的框图,箭头部分是实时时钟基本部分,包括时钟源,预分频,影子寄存器,引脚复用输出。此外还有两个闹钟,周期唤醒,入侵检测以及时间戳。

STM32实时时钟电路

        在开发板上有低速外部时钟源-32.768Khz。

功能需要

1)配置当前时间


        时间可以采取24小时格式,也可以采用12小时格式,默认采用24小时格式。配置时间时,还会设置日期格式,是采用BCD或者二进制。建议采用二进制即可,可以直接填入时间数值。


2)配置闹钟(每隔10s,触发一次闹钟中断)


3)设置周期唤醒(唤醒时间1s)并且可以输出低电平


STM32CubeMx配置RTC

配置RCC

        由于RTC使用到外部时钟源,因此需要在时钟配置使用低速外部时钟源。


配置RTC

配置时间,闹钟,唤醒

        配置时间24小时格式,二进制格式(22年5月2日,12时19分50秒);设置闹钟(由于每10s,闹钟触发一次中断,因此屏蔽掉时分,不屏蔽秒);设置周期时钟,周期为1Hz,不需要计数,也就是1s触发一次;如果计数值为1,则为2s触发一次中断。

开启中断

设置中断优先级

功能代码实现

STM32Cude生成RTC初始化

void MX_RTC_Init(void)

{

 

  /* USER CODE BEGIN RTC_Init 0 */

 

  /* USER CODE END RTC_Init 0 */

 

  RTC_TimeTypeDef sTime = {0};

  RTC_DateTypeDef sDate = {0};

  RTC_AlarmTypeDef sAlarm = {0};

 

  /* USER CODE BEGIN RTC_Init 1 */

 

  /* USER CODE END RTC_Init 1 */

 

  /** Initialize RTC Only

  */

  hrtc.Instance = RTC;

  hrtc.Init.HourFormat = RTC_HOURFORMAT_24;

  hrtc.Init.AsynchPrediv = 127;

  hrtc.Init.SynchPrediv = 255;

  hrtc.Init.OutPut = RTC_OUTPUT_WAKEUP;

  hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;

  hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;

  if (HAL_RTC_Init(&hrtc) != HAL_OK)

  {

    Error_Handler();

  }

 

  /* USER CODE BEGIN Check_RTC_BKUP */

 

  /* USER CODE END Check_RTC_BKUP */

 

  /** Initialize RTC and set the Time and Date

  */

  sTime.Hours = 12;

  sTime.Minutes = 19;

  sTime.Seconds = 50;

  sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;

  sTime.StoreOperation = RTC_STOREOPERATION_RESET;

  if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK)

  {

    Error_Handler();

  }

  sDate.WeekDay = RTC_WEEKDAY_MONDAY;

  sDate.Month = RTC_MONTH_MAY;

  sDate.Date = 2;

  sDate.Year = 22;

 

  if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK)

  {

    Error_Handler();

  }

 

  /** Enable the Alarm A

  */

  sAlarm.AlarmTime.Hours = 0;

  sAlarm.AlarmTime.Minutes = 0;

  sAlarm.AlarmTime.Seconds = 10;

  sAlarm.AlarmTime.SubSeconds = 0;

  sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;

  sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;

  sAlarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY|RTC_ALARMMASK_HOURS

                              |RTC_ALARMMASK_MINUTES;

  sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;

  sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;

  sAlarm.AlarmDateWeekDay = 1;

  sAlarm.Alarm = RTC_ALARM_A;

  if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK)

  {

    Error_Handler();

  }

 

  /** Enable the WakeUp

  */

  if (HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 0, RTC_WAKEUPCLOCK_CK_SPRE_16BITS) != HAL_OK)

  {

    Error_Handler();

  }

  /* USER CODE BEGIN RTC_Init 2 */

 

  /* USER CODE END RTC_Init 2 */

 

}


自定义触发闹钟次数变量 

重写周期唤醒回调函数

        注:


        1)一定要要先读Time然后再度Date,否者会出错;


        2)即使不需要Date数据,也要读Date否则也会出错。 


void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc)

{

   RTC_TimeTypeDef sTime ={0};

   RTC_DateTypeDef sDate={0};

    

    char str[40] ={0};


    //1)一定要要先读Time然后再度Date,否者会出做;即使不需要Date数据,也要度Date否则也会出错

    if((HAL_RTC_GetTime(hrtc,&sTime,RTC_FORMAT_BIN)!=HAL_OK)|| (HAL_RTC_GetDate(hrtc,&sDate,RTC_FORMAT_BIN)!=HAL_OK))

    {

           return;

    }

   

    sprintf(str,"RTC Time = %4d年%2d月%2d日 rn",2000+sDate.Year,sDate.Month,sDate.Date);

    HAL_UART_Transmit(&huart1,(const uint8_t *)str,strlen(str),100);

    

    sprintf(str,"RTC Time = %2d时%2d分%2d秒 rn",sTime.Hours,sTime.Minutes,sTime.Seconds);

    HAL_UART_Transmit(&huart1,(const uint8_t *)str,strlen(str),100);

 

}


重写闹钟中断函数

void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)

{

    char str[40] ={0};

    sprintf(str,"闹钟触发次数: %d rn",++alarmTrigger);

    HAL_UART_Transmit(&huart1,(const uint8_t *)str,strlen((const char *)str),100);


}

关键字:STM32  实时时钟  RTC 引用地址:STM32基础10--实时时钟(RTC)

上一篇:STM32基础11--模数转换(ADC)
下一篇:STM32基础9--串口通信(UART)

推荐阅读最新更新时间:2024-11-04 20:40

十五年创新路:意法半导体举办首届STM32中国线上技术周
2022年是意法半导体STM32家族问世15周年。在全球疫情阻止人们面对面沟通交流的当下,7月18-22日,意法半导体举办首届暨2022年STM32中国线上技术周,庆祝与生态合作伙伴共同创新的十五载。 在这个为期五天的线上活动中,意法半导体总裁兼首席执行官Jean-Marc Chery、意法半导体执行副总裁、通用微控制器子产品部总经理Ricardo De Sa Earp、意法半导体执行副总裁、中国区市场营销负责人曹志平(Henry Cao) 将分别作主题演讲。同时,意法半导体和合作伙伴带来30多场在线研讨会、100多个展品视频演示。在在线研讨会后设有技术问答环节,参观者将有机会与我们的专家和工程师进行现场互动。 下面,
[单片机]
十五年创新路:意法半导体举办首届<font color='red'>STM32</font>中国线上技术周
S3C2440 RTC实时时钟 驱动分析以及使用(三十)
RTC驱动分析总结: driversrtcrtc-s3c.c s3c_rtc_init platform_driver_register s3c_rtc_probe rtc_device_register( s3c , &pdev- dev, &s3c_rtcops, THIS_MODULE) rtc_dev_prepare cdev_init(&rtc- char_dev, &rtc_dev_fops); rtc_dev_add_device cdev_add linux中的rtc驱动位于drivers/rtc下,里面包含了许多开发平台的RTC驱动,我们这里是以S3C24XX为主,所以它的RTC驱
[单片机]
S3C2440 <font color='red'>RTC</font><font color='red'>实时时钟</font> 驱动分析以及使用(三十)
stm32学习之七
USART串口学习: 本篇主要是stm32板子与PC机器的连接,由于是初学,花了很长的时间思考的实验,才成功的配置成功串口的通信,煞费脑筋,所以自成一篇博客。 其实在买板子的时候,应该想到有能实现通信功能的连接线,但是主要是笔记本电脑,为了稳妥起见,不敢夸张的实验。 步骤: 1、有一个USB转(串口线)com(不专业的说法,但是清晰的可以看到板子上面有com1,就这样称呼)连接线,然后就有一根连接开发板的com线,这样可以实现PC机器和stm32的连接。如果电脑上显示驱动没有安装成功,那么这个时候就要想到驱动的安装问题了。可以网上找,或者......你知道的。 2、打开设备管理器,可以看到电脑上
[单片机]
<font color='red'>stm32</font>学习之七
Stm32中的USART_RX_STA
代码如下: void USART1_IRQHandler(void) { u8 res; #ifdef OS_CRITICAL_METHOD //如果OS_CRITICAL_METHOD定义了,说明使用ucosII了. OSIntEnter(); #endif if(USART1- SR&(1 5))//接收到数据 { res=USART1- DR; if((USART_RX_STA&0x8000)==0)//接收未完成 { if(USART_RX_STA&0x4000)//接收到了0x0d { if(res!=0x0a)USART_RX_STA=0;//接收错误,重新开
[单片机]
STM32的AD用DMA方式时的请注意初始化顺序
我突然意识到我的数据好像一直没有错位,看到这个我又试验了一下,发现把DMA_Cmd(DMA1_Channel1, ENABLE);放置到哪儿都是一样的啊~~~ 这个是原帖部分: STM32的AD用DMA方式时的请注意初始化顺序 DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_Result; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA
[单片机]
STM32的完整启动流程分析
关于STM32的启动流程,网上有的资料在讨论几种boot模式,有的在回答启动文件的内容,在查阅了很多资料后,本文给出一个比较全面的总结和回答。 1. 根据boot引脚决定三种启动模式 复位后,在 SYSCLK 的第四个上升沿锁存 BOOT 引脚的值。BOOT0 为专用引脚,而 BOOT1 则与 GPIO 引脚共用。一旦完成对 BOOT1 的采样,相应 GPIO 引脚即进入空闲状态,可用于其它用途。BOOT0与BOOT1引脚的不同值指向了三种启动方式: 1)从主Flash启动。主Flash指的是STM32的内置Flash。选择该启动模式后,内置Flash的起始地址将被重映射到0x00000000地址,代码将在该处开始执行。一般我
[单片机]
<font color='red'>STM32</font>的完整启动流程分析
学习STM32单片机,要理解它的堆栈
学习STM32单片机的时候,总是能遇到 “堆栈” 这个概念。对于了解一点汇编编程的人,就可以知道,堆栈是内存中一段连续的存储区域,用来保存一些临时数据。堆栈操作由 PUSH、POP 两条指令来完成。而程序内存可以分为几个区:栈区(stack)、堆区(Heap)、全局区(static)、字符常量区、程序代码区。 栈,用于存放局部变量,局部数组等; 堆,用于malloc申请内存空间; 全局静态区,用于保存全局变量和静态变量; 字符常量区,用于保存字符串等; 代码区,用于保存程序的二进制代码。 程序编译之后,全局变量,静态变量已经分配好内存空间。在函数运行时,程序需要为局部变量分配栈空间,当中断来时,也需要将函数指针入栈,保护现
[单片机]
学习<font color='red'>STM32</font>单片机,要理解它的堆栈
STM32的串口中断
总的来说,STM32单片机的串口还是很好理解的,编程也不算复杂。当然我更愿意希望其中断系统和51单片机一样的简单。 对于接收终端,就是RXNE了,这只在接收完成后才产生,在执行USART_ITConfig(USART1, USART_IT_RXNE, ENABLE)代码时不会进入ISR。但麻烦的就是发送有关的中断了:TXE或者TC,根据资料和测试的结果,TXE在复位后就是置1的,即在执行USART_ITConfig(USART1, USART_IT_TXE, ENABLE)后会立即产生中断请求。因此这造成一个麻烦的问题:如果没有真正的发送数据,TXE中断都会发生,而且没有休止,这将占用很大部分的CPU时间,甚至影响其他程
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved