第43章 RTC—实时时钟—零死角玩转STM32-F429系列

STM32F429 RTC时间不动、不准问题的解决 硬件:阿波罗STM32F429IGTx开发板 软件:keil5,c语言 一、问题描述 在使用正点原子RTC时间时,遇到以下两个问题: 1.将RTC时间精确到亚秒,打印发现:只有亚秒在动,时,分,秒皆不动。 2.打印出来的亚秒是倒计时,循环的从255到0。 二、问题解决 而我想实现时间正常走动且毫秒能从0-999正计时。经查阅相关资料找到解决方法: 1.时间不走动的原因在于: 为了保障读取时间的一致性,读取日历操作要求先读时分秒然后还得读日期,这样做才为一个完整的操作。所以在读取TIME【时分秒】后,硬件会将 阅读详情
 

第43章     RTC—实时时钟

全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn

野火视频教程优酷观看网址:http://i.youku.com/firege

 

 

 

43.1 RTC简介

RTC—real time clock,实时时钟,主要包含日历、闹钟和自动唤醒这三部分的功能,其中的日历功能我们使用的最多。日历包含两个32bit的时间寄存器,可直接输出时分秒,星期、月、日、年。比起F103系列的RTC只能输出秒中断,剩下的其他时间需要软件来实现,429的RTC可谓是脱胎换骨,让我们在软件编程时大大降低了难度。RTC功能框图分析

43.2 RTC功能框图解析

1.    时钟源

RTC 时钟源—RTCCLK 可以从LSE、LSI和HSE_RTC这三者中得到。其中使用最多的是LSE,LSE由一个外部的32.768KHZ(6PF负载)的晶振提供,精度高,稳定,RTC首选。LSI是芯片内部的30KHZ晶体,精度较低,会有温漂,一般不建议使用。HSE_RTC由HSE分频得到,最高是4M,使用的也较少。

2.    预分频器

预分频器PRER由7位的异步预分频器APRE和15位的同步预分频器SPRE组成。异步预分频器时钟CK_APRE用于为二进制 RTC_SSR 亚秒递减计数器提供时钟,同步预分频器时钟CK_SPRE用于更新日历。异步预分频器时钟fCK_APRE=fRTC_CLK/(PREDIV_A+1),同步预分频器时钟fCK_SPRE=fRTC_CLK/(PREDIV_S+1),)。使用两个预分频器时,推荐将异步预分频器配置为较高的值,以最大程度降低功耗。一般我们会使用LSE生成1HZ的同步预分频器时钟

通常的情况下,我们会选择LSE作为RTC的时钟源,即fRTCCLK=fLSE=32.768KHZ。然后经过预分频器PRER分频生成1HZ的时钟用于更新日历。使用两个预分频器分频的时候,为了最大程度的降低功耗,我们一般把同步预分频器设置成较大的值,为了生成1HZ的同步预分频器时钟CK_SPRE,最常用的配置是PREDIV_A=127,PREDIV_S=255。计算公式为:fCK_SPRE=fRTCCLK/{(PREDIV_A+1)*(PREDIV_S+1)}= 32.768/{(127+1)*(255+1)}=1HZ。

3.    实时时钟和日历

我们知道,实时时钟一般是这样表示的:时/分/秒/亚秒,其中时分秒可直接从RTC 时间寄存器 (RTC_TR)中读取,有关时间寄存器的说明具体见错误!未找到引用源。和错误!未找到引用源。。

图 431RTC 时间寄存器(RTC_TR)

表格 431 时间寄存器位功能说明

位名称

位说明

PM

AM/PM符号,0:AM/24小时制,1:PM

HT[1:0]

小时的十位

HU[3:0]

小时的个位

MNT[2:0]

分钟的十位

MNU[3:0]

分钟的个位

ST[2:0]

秒的十位

SU[3:0]

秒的个位

亚秒由RTC 亚秒寄存器 (RTC_SSR)的值计算得到,公式为:亚秒值 = ( PREDIV_S – SS[15:0] ) / ( PREDIV_S + 1 ) ,SS[15:0]是同步预分频器计数器的值,PREDIV_S是同步预分频器的值。

图 432RTC亚秒寄存器(RTC_SSR)

日期包含的年月日可直接从RTC 日期寄存器 (RTC_DR)中读取。

图 433 RTC日期寄存器(RTC_DR)

表格 432 RTC日期寄存器位功能说明

位名称

位说明

YT[1:0]

年份的十位

YU[3:0]

年份的个位

WDU[2:0]

星期几的个位,000:禁止,001:星期一,…,111:星期日

MT

月份的十位

MU

月份的个位

DT[1:0]

日期的十位

DU[3:0]

日期的个位

当应用程序读取日历寄存器时,默认是读取影子寄存器的内容,每隔两个 RTCCLK 周期,便将当前日历值复制到影子寄存器。我们也可以通过将 RTC_CR 寄存器的BYPSHAD 控制位置 1 来直接访问日历寄存器,这样可避免等待同步的持续时间。

RTC_CLK经过预分频器后,有一个512HZ的CK_APRE和1个1HZ的CK_SPRE,这两个时钟可以成为校准的时钟输出RTC_CALIB,RTC_CALIB最终要输出则需映射到RTC_AF1引脚,即PC13输出,用来对外部提供时钟。

4.    闹钟

RTC有两个闹钟,闹钟A和闹钟B,,当RTC运行的时间跟预设的闹钟时间相同的时候,相应的标志位ALRAF(在RTC_ISR寄存器中)和ALRBF会置1。利用这个闹钟我们可以做一些备忘提醒功能。

如果使能了闹钟输出(由RTC_CR的OSEL[0:1]位控制),则ALRAF和ALRBF会连接到闹钟输出引脚RTC_ALARM,RTC_ALARM最终连接到RTC的外部引脚RTC_AF1(即PC13),输出的极性由RTC_CR 寄存器的 POL 位配置,可以是高电平或者低电平。

5.    时间戳

时间戳即时间点的意思,就是某一个时刻的时间。时间戳复用功能 (RTC_TS) 可映射到 RTC_AF1 或 RTC_AF2,当发生外部的入侵事件时,即发生时间戳事件时, RTC_ISR 寄存器中的时间戳标志位 (TSF) 将置 1,日历会保存到时间戳寄存器( RTC_TSSSR、 RTC_TSTR 和 RTC_TSDR)中。时间戳往往用来记录危及时刻的时间,以供事后排查问题时查询。

6.    入侵检测

RTC自带两个入侵检测引脚RTC_AF1(PC13)和RTC_AF2(PI8),这两个输入既可配置为边沿检测,也可配置为带过滤的电平检测。当发生入侵检测时,备份寄存器将被复位。备份寄存器 (RTC_BKPxR) 包括20 个 32 位寄存器,用于存储 80 字节的用户应用数据。这些寄存器在备份域中实现,可在 VDD 电源关闭时通过 VBAT 保持上电状态。备份寄存器不会在系统复位或电源复位时复位,也不会在器件从待机模式唤醒时复位。

43.3 RTC初始化结构体讲解

标准库函数对每个外设都建立了一个初始化结构体,比如RTC_InitTypeDef,结构体成员用于设置外设工作参数,并由外设初始化配置函数,比如RTC_Init()调用,这些配置好的参数将会设置外设相应的寄存器,达到配置外设工作环境的目的。

初始化结构体和初始化库函数配合使用是标准库精髓所在,理解了初始化结构体每个成员意义基本上就可以对该外设运用自如。初始化结构体定义在stm32f4xx_rtc.h头文件中,初始化库函数定义在stm32f4xx_rtc.c文件中,编程时我们可以结合这两个文件内注释使用。

RTC初始化结构体用来设置RTC小时的格式和RTC_CLK的分频系数。

代码 431 RTC初始化结构体

1 typedef struct {

2 uint32_t RTC_HourFormat; /* 指定RTC小时格式*/

3

4 uint32_t RTC_AsynchPrediv; /* 配置RTC_CLK的异步分频因子 */

5

6 uint32_t RTC_SynchPrediv; /* 配置RTC_CLK的同步分频因子 */

7 } RTC_InitTypeDef;

1)    RTC_HourFormat:小时格式设置,有RTC_HourFormat_24和RTC_HourFormat_12两种格式,一般我们选择使用24小时制,具体由RTC_CR寄存器的FMT位配置。

2)    RTC_AsynchPrediv:RTC_CLK异步分频因子设置,7位有效,具体由RTC 预分频器寄存器RTC_PRER的PREDIV_A[6:0]位配置。

3)    RTC_SynchPrediv:RTC_CLK同步分频因子设置,15位有效,具体由RTC 预分频器寄存器RTC_PRER的PREDIV_S[14:0]位配置。

43.4 RTC时间结构体讲解

RTC时间初始化结构体用来设置初始时间,配置的是RTC时间寄存器RTC_TR。

代码 432 RTC时间结构体

1 typedef struct {

2 uint8_t RTC_Hours; /* 小时设置 */

3

4 uint8_t RTC_Minutes; /* 分钟设置 */

5

6 uint8_t RTC_Seconds; /* 秒设置 */

7

8 uint8_t RTC_H12; /* AM/PM 符号设置 */

9 } RTC_TimeTypeDef;

1)    RTC_Hours:小时设置,12小时制式时,取值范围为0~11,24小时制式时,取值范围为0~23。

2)    RTC_Minutes:分钟设置,取值范围为0~59。

3)    RTC_Seconds:秒钟设置,取值范围为0~59。

4)    RTC_H12:AM/PM设置,可取值RTC_H12_AM和RTC_H12_PM,RTC_H12_AM时则是24小时制,RTC_H12_PM则是12小时制。

43.5 RTC日期结构体讲解

RTC日期初始化结构体用来设置初始日期,配置的是RTC日期寄存器RTC_DR。

代码 433 RTC 日期结构体

1 typedef struct {

2 uint8_t RTC_WeekDay; /* 星期几设置 */

3

4 uint8_t RTC_Month; /* 月份设置 */

5

6 uint8_t RTC_Date; /* 日期设置 */

7

8 uint8_t RTC_Year; /* 年份设置 */

9 } RTC_DateTypeDef;

1)    RTC_WeekDay:星期几设置,取值范围为1~7,对应星期一~星期日。

2)    RTC_Month:月份设置,取值范围为1~12。

3)    RTC_Date:日期设置,取值范围为1~31。

4)    RTC_Year:年份设置,取值范围为0~99。

43.6 RTC闹钟结构体讲解

RTC闹钟结构体主要用来设置闹钟时间,设置的格式为[星期/日期]-[时]-[分]-[秒],共四个字段,每个字段都可以设置为有效或者无效,即可MASK。如果MASK掉[星期/日期]字段,则每天闹钟都会响。

代码 434 RTC闹钟结构体

1 typedef struct {

2 RTC_TimeTypeDef RTC_AlarmTime; /* 设定RTC时间寄存器的值:时/分/秒 */

3

4 uint32_t RTC_AlarmMask; /* RTC 闹钟掩码字段选择 */

5

6 uint32_t RTC_AlarmDateWeekDaySel; /*闹钟的日期/星期选择 */

7

8 uint8_t RTC_AlarmDateWeekDay; /* 指定闹钟的日期/星期

9 * 如果日期有效,则取值范围为1~31

10 * 如果星期有效,则取值为1~7

11 */

12    } RTC_AlarmTypeDef;

1)    RTC_AlarmTime:闹钟时间设置,配置的是RTC时间初始化结构体,主要配置小时的制式,有12小时或者是24小时,配套具体的时、分、秒。

2)    RTC_AlarmMask:闹钟掩码字段选择,即选择闹钟时间哪些字段无效,取值 可为:RTC_AlarmMask_None(全部有效)、RTC_AlarmMask_DateWeekDay(日期或者星期无效)、RTC_AlarmMask_Hours(小时无效)、RTC_AlarmMask_Minutes(分钟无效)、RTC_AlarmMask_Seconds(秒钟无效)、RTC_AlarmMask_All(全部无效)。比如我们选择RTC_AlarmMask_DateWeekDay,那么就是当RTC的时间的小时等于闹钟时间小时字段时,每天的这个小时都会产生闹钟中断。

3)    RTC_AlarmDateWeekDaySel:闹钟日期或者星期选择,可选择RTC_AlarmDateWeekDaySel_WeekDay或者RTC_AlarmDateWeekDaySel_Date。要想这个配置有效,则RTC_AlarmMask不能配置为RTC_AlarmMask_DateWeekDay,否则会被MASK掉。

4)    RTC_AlarmDateWeekDay:具体的日期或者星期几,当RTC_AlarmDateWeekDaySel设置成RTC_AlarmDateWeekDaySel_WeekDay时,取值为1~7,对应星期一~星期日,当设置成RTC_AlarmMask_DateWeekDay时,取值为1~31。

43.7 RTC—日历实验

利用RTC的日历功能制作一个日历,显示格式为:年-月-日-星期,时-分-秒。

43.7.1 硬件设计

该实验用到了片内外设RTC,为了确保在VDD断电的情况下时间可以保存且继续运行,VBAT引脚外接了一个CR1220电池座,用来放CR1220电池给RTC供电。

图 434 RTC 外接CR1220电池座子

43.7.2 软件设计
1.    编程要点

1)    选择RTC_CLK的时钟源;

2)    配置RTC_CLK的分频系数,包括异步和同步两个;

3)    设置初始时间,包括日期;

4)    获取时间和日期,并显示;

2.    代码分析

这里只讲解核心的部分代码,有些变量的设置,头文件的包含等并没有涉及到,完整的代码请参考本章配套的工程。我们创建了两个文件:bsp_rtc.c和bsp_rtc.h文件用来存RTC驱动程序及相关宏定义,中断服务函数则放在stm32f4xx_it.h文件中。

宏定义

代码 435 宏定义

1 // 时钟源宏定义

2 #define RTC_CLOCK_SOURCE_LSE

3 //#define RTC_CLOCK_SOURCE_LSI

4

5 // 异步分频因子

6 #define ASYHCHPREDIV 0X7F

7 // 同步分频因子

8 #define SYHCHPREDIV 0XFF

9

10

11

12 // 时间宏定义

13 #define RTC_H12_AMorPM RTC_H12_AM

14 #define HOURS 1 // 0~23

15 #define MINUTES 1 // 0~59

16 #define SECONDS 1 // 0~59

17

18 // 日期宏定义

19 #define WEEKDAY 1 // 1~7

20 #define DATE 1 // 1~31

21 #define MONTH 1 // 1~12

22 #define YEAR 1 // 0~99

23

24 // 时间格式宏定义

25 #define RTC_Format_BINorBCD RTC_Format_BIN

26

27 // 备份域寄存器宏定义

28 #define RTC_BKP_DRX RTC_BKP_DR0

29 // 写入到备份寄存器的数据宏定义

30 #define RTC_BKP_DATA 0X32F2

为了方便程序移植,我们把移植时需要修改的代码部分都通过宏定义来实现。具体的配合注释看代码即可。

RTC时钟配置函数

代码 436 RTC配置函数

1 /**

2 * @brief RTC配置:选择RTC时钟源,设置RTC_CLK的分频系数

3 * @param 无

4 * @retval 无

5 */

6 void RTC_CLK_Config(void)

7 {

8 RTC_InitTypeDef RTC_InitStructure;

9

10 /*使能 PWR 时钟*/

11 RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

12 /* PWR_CR:DBF置1,使能RTC、RTC备份寄存器和备份SRAM的访问 */

13 PWR_BackupAccessCmd(ENABLE);

14

15 #if defined (RTC_CLOCK_SOURCE_LSI)

16 /* 使用LSI作为RTC时钟源会有误差

17 * 默认选择LSE作为RTC的时钟源

18 */

19 /* 使能LSI */

20 RCC_LSICmd(ENABLE);

21 /* 等待LSI稳定 */

22 while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET) {

23 }

24 /* 选择LSI做为RTC的时钟源 */

25 RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);

26

27 #elif defined (RTC_CLOCK_SOURCE_LSE)

28

29 /* 使能LSE */

30 RCC_LSEConfig(RCC_LSE_ON);

31 /* 等待LSE稳定 */

32 while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) {

33 }

34 /* 选择LSE做为RTC的时钟源 */

35 RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);

36

37 #endif /* RTC_CLOCK_SOURCE_LSI */

38

39 /* 使能RTC时钟 */

40 RCC_RTCCLKCmd(ENABLE);

41

42 /* 等待 RTC APB 寄存器同步 */

43 RTC_WaitForSynchro();

44

45 /*=====================初始化同步/异步预分频器的值======================*/

46 /* 驱动日历的时钟ck_spare = LSE/[(255+1)*(127+1)] = 1HZ */

47

48 /* 设置异步预分频器的值*/

49 RTC_InitStructure.RTC_AsynchPrediv = ASYNCHPREDIV;

50 /* 设置同步预分频器的值 */

51 RTC_InitStructure.RTC_SynchPrediv = SYNCHPREDIV;

52 RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;

53 /* 用RTC_InitStructure的内容初始化RTC寄存器 */

54 if (RTC_Init(&RTC_InitStructure) == ERROR) {

55 printf("\n\r RTC 时钟初始化失败 \r\n");

56 }

57 }

RTC配置函数主要实现两个功能,一是选择RTC_CLK的时钟源,根据宏定义来决定使用LSE还是LSI作为RTC_CLK的时钟源,这里我们选择LSE;二是设置RTC_CLK的预分频系数,包括异步和同步两个,这里设置异步分频因子为ASYNCHPREDIV(127),同步分频因子为ASYNCHPREDIV(255),则产生的最终驱动日历的时钟CK_SPRE=32.768/(127+1)*(255+1)=1HZ,则每秒更新一次。

RTC时间初始化函数

代码 437 RTC时间和日期设置函数

1 /**

2 * @brief 设置时间和日期

3 * @param 无

4 * @retval 无

5 */

6 void RTC_TimeAndDate_Set(void)

7 {

8 RTC_TimeTypeDef RTC_TimeStructure;

9 RTC_DateTypeDef RTC_DateStructure;

10

11 // 初始化时间

12 RTC_TimeStructure.RTC_H12 = RTC_H12_AMorPM;

13 RTC_TimeStructure.RTC_Hours = HOURS;

14 RTC_TimeStructure.RTC_Minutes = MINUTES;

15 RTC_TimeStructure.RTC_Seconds = SECONDS;

16 RTC_SetTime(RTC_Format_BINorBCD, &RTC_TimeStructure);

17 RTC_WriteBackupRegister(RTC_BKP_DRX, RTC_BKP_DATA);

18

19 // 初始化日期

20 RTC_DateStructure.RTC_WeekDay = WEEKDAY;

21 RTC_DateStructure.RTC_Date = DATE;

22 RTC_DateStructure.RTC_Month = MONTH;

23 RTC_DateStructure.RTC_Year = YEAR;

24 RTC_SetDate(RTC_Format_BINorBCD, &RTC_DateStructure);

25 RTC_WriteBackupRegister(RTC_BKP_DRX, RTC_BKP_DATA);

26 }

RTC时间和日期设置函数主要是设置时间和日期这两个结构体,然后调相应的RTC_SetTime和RTC_SetDate函数把初始化好的时间写到相应的寄存器,每当写完之后都会在备份寄存器里面写入一个数,以作标记,为的是程序开始运行的时候检测RTC的时间是否已经配置过。

具体的时间、日期、备份寄存器和写入备份寄存器的值都在头文件的宏定义里面,要修改这些值只需修改头文件的宏定义即可。

RTC时间显示函数

代码 438 RTC时间显示函数

1 /**

2 * @brief 显示时间和日期

3 * @param 无

4 * @retval 无

5 */

6 void RTC_TimeAndDate_Show(void)

7 {

8 uint8_t Rtctmp=0;

9 char LCDTemp[100];

10 RTC_TimeTypeDef RTC_TimeStructure;

11 RTC_DateTypeDef RTC_DateStructure;

12

13

14 while (1) {

15 // 获取日历

16 RTC_GetTime(RTC_Format_BIN, &RTC_TimeStructure);

17 RTC_GetDate(RTC_Format_BIN, &RTC_DateStructure);

18

19 // 每秒打印一次

20 if (Rtctmp != RTC_TimeStructure.RTC_Seconds) {

21

22 // 打印日期

23 printf("The Date : Y:20%0.2d - M:%0.2d - D:%0.2d - W:%0.2d\r\n",

24 RTC_DateStructure.RTC_Year,

25 RTC_DateStructure.RTC_Month,

26 RTC_DateStructure.RTC_Date,

27 RTC_DateStructure.RTC_WeekDay);

28

29 //液晶显示日期

30 //先把要显示的数据用sprintf函数转换为字符串,然后才能用液晶显示函数显示

31 sprintf(LCDTemp,"The Date : Y:20%0.2d - M:%0.2d - D:%0.2d - W:%0.2d",

32 RTC_DateStructure.RTC_Year,

33 RTC_DateStructure.RTC_Month,

34 RTC_DateStructure.RTC_Date,

35 RTC_DateStructure.RTC_WeekDay);

36

37 LCD_DisplayStringLineEx(10,50,48,48,(uint8_t *)LCDTemp,0);

38

39 // 打印时间

40 printf("The Time : %0.2d:%0.2d:%0.2d \r\n\r\n",

41 RTC_TimeStructure.RTC_Hours,

42 RTC_TimeStructure.RTC_Minutes,

43 RTC_TimeStructure.RTC_Seconds);

44

45 //液晶显示时间

46 sprintf(LCDTemp,"The Time : %0.2d:%0.2d:%0.2d",

47 RTC_TimeStructure.RTC_Hours,

48 RTC_TimeStructure.RTC_Minutes,

49 RTC_TimeStructure.RTC_Seconds);

50

51 LCD_DisplayStringLineEx(10,100,48,48,(uint8_t *)LCDTemp,0);

52

53 (void)RTC->DR;

54 }

55 Rtctmp = RTC_TimeStructure.RTC_Seconds;

56 }

57 }

RTC时间和日期显示函数中,通过调用RTC_GetTime()和RTC_GetDate()这两个库函数,把时间和日期都读取保存到时间和日期结构体中,然后以1s为频率,把时间显示出来。

在使用液晶显示时间的时候,需要先调用标准的C库函数sprintf()把数据转换成字符串,然后才能调用液晶显示函数来显示,因为液晶显示时处理的都是字符串。

主函数

代码 439 main函数

1 /**

2 * @brief 主函数

3 * @param 无

4 * @retval 无

5 */

6 int main(void)

7 {

8 /* 初始化LED */

9 LED_GPIO_Config();

10

11 /* 初始化调试串口,一般为串口1 */

12 Debug_USART_Config();

13 printf("\n\r这是一个RTC日历实验 \r\n");

14

15 /*======================液晶初始化开始=========================*/

16 LCD_Init();

17 LCD_LayerInit();

18 LTDC_Cmd(ENABLE);

19

20 /*把背景层刷黑色*/

21 LCD_SetLayer(LCD_BACKGROUND_LAYER);

22 LCD_Clear(LCD_COLOR_BLACK);

23

24 /*初始化后默认使用前景层*/

25 LCD_SetLayer(LCD_FOREGROUND_LAYER);

26 /*默认设置不透明,该函数参数为不透明度,范围 0-0xff ,0为全透明,0xff为不透明*/

27 LCD_SetTransparency(0xFF);

28 LCD_Clear(LCD_COLOR_BLACK);

29 /*经过LCD_SetLayer(LCD_FOREGROUND_LAYER)函数后,

30 以下液晶操作都在前景层刷新,除非重新调用过LCD_SetLayer函数设置背景层*/

31 LCD_SetColors(LCD_COLOR_RED,LCD_COLOR_BLACK);

32 /*=========================液晶初始化结束========================*/

33

34 /*

35 * 当我们配置过RTC时间之后就往备份寄存器0写入一个数据做标记

36 * 所以每次程序重新运行的时候就通过检测备份寄存器0的值来判断

37 * RTC 是否已经配置过,如果配置过那就继续运行,如果没有配置过

38 * 就初始化RTC,配置RTC的时间。

39 */

40 if (RTC_ReadBackupRegister(RTC_BKP_DRX) != RTC_BKP_DATA) {

41 /* RTC配置:选择时钟源,设置RTC_CLK的分频系数 */

42 RTC_CLK_Config();

43 /* 设置时间和日期 */

44 RTC_TimeAndDate_Set();

45 } else {

46 /* 检查是否电源复位 */

47 if (RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET) {

48 printf("\r\n发生电源复位....\r\n");

49 }

50 /* 检查是否外部复位 */

51 else if (RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET) {

52 printf("\r\n发生外部复位....\r\n");

53 }

54

55 printf("\r\n不需要重新配置RTC....\r\n");

56

57 /* 使能 PWR 时钟 */

58 RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

59 /* PWR_CR:DBF置1,使能RTC、RTC备份寄存器和备份SRAM的访问 */

60 PWR_BackupAccessCmd(ENABLE);

61 /* 等待 RTC APB 寄存器同步 */

62 RTC_WaitForSynchro();

63 }

64

65 /* 显示时间和日期 */

66 RTC_TimeAndDate_Show();

67 }

主函数中,我们调用RTC_ReadBackupRegister()库函数来读取备份寄存器的值是否等于我们预设的那个值,因为当我们初始化完RTC的时间之后就往备份寄存器写入一个数据做标记,所以每次程序重新运行的时候就通过检测备份寄存器的值来判断,RTC 是否已经配置过,如果配置过则判断是电源复位还是外部引脚复位且继续运行显示时间,如果没有配置过,就初始化RTC,配置RTC的时间,然后显示。

如果想每次程序运行时都重新配置RTC,则用一个异于写入的值来做判断即可。

3.    下载验证

把程序编译好下载到开发板,通过电脑端口的串口调试助手或者液晶可以看到时间正常运行。当VDD不断电的情况下,发生外部引脚复位,时间不会丢失。当VDD断电或者发生外部引脚复位,VBT有电池供电时,时间不会丢失。当VDD断电且VBAT也不供电的情况下,时间会丢失,然后根据程序预设的初始时间重新启动。

43.8 RTC—闹钟实验

在日历实验的基础上,利用RTC的闹钟功能制作一个闹钟,在每天的[XX小时-XX分钟-XX秒钟]产生闹钟,然后蜂鸣器响。

43.8.1 硬件设计

硬件设计跟日历实验部分的硬件设计一样。

43.8.2 软件设计

闹钟实验是在日历实验的基础上添加,相同部分的代码不再讲解,这里只讲解闹钟相关的代码,更加具体的请参考闹钟实验的工程源码。

闹钟相关宏定义

代码 4310 闹钟相关宏定义

1 // 闹钟相关宏定义

2 #define ALARM_HOURS 1 // 0~23

3 #define ALARM_MINUTES 1 // 0~59

4 #define ALARM_SECONDS 10 // 0~59

5

6 #define ALARM_MASK RTC_AlarmMask_DateWeekDay

7 #define ALARM_DATE_WEEKDAY_SEL RTC_AlarmDateWeekDaySel_WeekDay

8 #define ALARM_DATE_WEEKDAY 2

9 #define RTC_Alarm_X RTC_Alarm_A

为了方便程序移植,我们把需要频繁修改的代码用宏封装起来。如果需要设置闹钟时间和闹钟的掩码字段,只需要修改这些宏即可。这些宏对应的是RTC闹钟结构体的成员,想知道每个宏的具体含义可参考"RTC闹钟结构体讲解"小节。

闹钟时间字段掩码ALARM_MASK我们配置为MASK掉日期/星期,即忽略日期/星期,则闹钟时间只有时/分/秒有效,即每天到了这个时间闹钟都会响。掩码还有其他取值,用户可自行修改做实验。

1.    编程要点

1)    初始化RTC,设置RTC初始时间;

2)    编程闹钟,设置闹钟时间;

3)    编写闹钟中断服务函数;

2.    代码分析
闹钟设置函数

代码 4311 闹钟编程代码

1 /*

2 * 要使能 RTC 闹钟中断,需按照以下顺序操作:

3 * 1. 将 EXTI 线 17 配置为中断模式并将其使能,然后选择上升沿有效。

4 * 2. 配置 NVIC 中的 RTC_Alarm IRQ 通道并将其使能。

5 * 3. 配置 RTC 以生成 RTC 闹钟(闹钟 A 或闹钟 B)。

6 *

7 *

8 */

9 void RTC_AlarmSet(void)

10 {

11 NVIC_InitTypeDef NVIC_InitStructure;

12 EXTI_InitTypeDef EXTI_InitStructure;

13 RTC_AlarmTypeDef RTC_AlarmStructure;

14

15 /*=============================第①步=============================*/

16 /* RTC 闹钟中断配置 */

17 /* EXTI 配置 */

18 EXTI_ClearITPendingBit(EXTI_Line17);

19 EXTI_InitStructure.EXTI_Line = EXTI_Line17;

20 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

21 EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;

22 EXTI_InitStructure.EXTI_LineCmd = ENABLE;

23 EXTI_Init(&EXTI_InitStructure);

24

25 /*=============================第②步=============================*/

26 /* 使能RTC闹钟中断 */

27 NVIC_InitStructure.NVIC_IRQChannel = RTC_Alarm_IRQn;

28 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

29 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

30 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

31 NVIC_Init(&NVIC_InitStructure);

32

33 /*=============================第③步=============================*/

34 /* 失能闹钟,在设置闹钟时间的时候必须先失能闹钟*/

35 RTC_AlarmCmd(RTC_Alarm_X, DISABLE);

36 /* 设置闹钟时间 */

37 RTC_AlarmStructure.RTC_AlarmTime.RTC_H12 = RTC_H12_AMorPM;

38 RTC_AlarmStructure.RTC_AlarmTime.RTC_Hours = ALARM_HOURS;

39 RTC_AlarmStructure.RTC_AlarmTime.RTC_Minutes = ALARM_MINUTES;

40 RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds = ALARM_SECONDS;

41 RTC_AlarmStructure.RTC_AlarmMask = ALARM_MASK;

42 RTC_AlarmStructure.RTC_AlarmDateWeekDaySel = ALARM_DATE_WEEKDAY_SEL;

43 RTC_AlarmStructure.RTC_AlarmDateWeekDay = ALARM_DATE_WEEKDAY;

44

45

46 /* 配置RTC Alarm X(X=A或B)寄存器 */

47 RTC_SetAlarm(RTC_Format_BINorBCD, RTC_Alarm_X, &RTC_AlarmStructure);

48

49 /* 使能 RTC Alarm X 中断 */

50 RTC_ITConfig(RTC_IT_ALRA, ENABLE);

51

52 /* 使能闹钟 */

53 RTC_AlarmCmd(RTC_Alarm_X, ENABLE);

54

55 /* 清除闹钟中断标志位 */

56 RTC_ClearFlag(RTC_FLAG_ALRAF);

57 /* 清除 EXTI Line 17 悬起位 (内部连接到RTC Alarm) */

58 EXTI_ClearITPendingBit(EXTI_Line17);

59 }

从参考手册知道,要使能RTC闹钟中断,必须按照三个步骤进行,具体见错误!未找到引用源。。RTC_AlarmSet()函数则根据这三个步骤和代码中的注释阅读即可。

图 435 RTC闹钟中断编程步骤(摘自STM32F4xx 中文参考手册RTC章节)

在第3步中,配置RTC以生成RTC闹钟中,在手册中也有详细的步骤说明,编程的时候必须按照这个步骤,具体见错误!未找到引用源。。

图 436RTC闹钟编程步骤(摘自STM32F4xx 中文参考手册RTC章节)

编程闹钟的步骤1和2,由固件库函数RTC_AlarmCmd(RTC_Alarm_X, DISABLE);实现,即在编程闹钟寄存器设置闹钟时间的时候必须先失能闹钟。剩下的两个步骤配套代码的注释阅读即可。

闹钟中断服务函数

代码 4312 闹钟中断服务函数

1 // 闹钟中断服务函数

2 void RTC_Alarm_IRQHandler(void)

3 {

4 if (RTC_GetITStatus(RTC_IT_ALRA) != RESET) {

5 RTC_ClearITPendingBit(RTC_IT_ALRA);

6 EXTI_ClearITPendingBit(EXTI_Line17);

7 }

8 /* 闹钟时间到,蜂鸣器响 */

9 BEEP_ON;

10 }

如果日历时间到了闹钟设置好的时间,则产生闹钟中断,在中断函数中把相应的标志位清0。为了表示闹钟时间到,我们让蜂鸣器响。

main函数

代码 4313 main函数、

1 /**

2 * @brief 主函数

3 * @param 无

4 * @retval 无

5 */

6 int main(void)

7 {

8 /* 初始化LED */

9 LED_GPIO_Config();

10 BEEP_GPIO_Config();

11

12 /* 初始化调试串口,一般为串口1 */

13 Debug_USART_Config();

14 printf("\n\r这是一个RTC闹钟实验 \r\n");

15

16 /*=========================液晶初始化开始============================*/

17 LCD_Init();

18 LCD_LayerInit();

19 LTDC_Cmd(ENABLE);

20

21 /*把背景层刷黑色*/

22 LCD_SetLayer(LCD_BACKGROUND_LAYER);

23 LCD_Clear(LCD_COLOR_BLACK);

24

25 /*初始化后默认使用前景层*/

26 LCD_SetLayer(LCD_FOREGROUND_LAYER);

27 /*默认设置不透明,该函数参数为不透明度,范围 0-0xff ,0为全透明,0xff为不透明*/

28 LCD_SetTransparency(0xFF);

29 LCD_Clear(LCD_COLOR_BLACK);

30 /*经过LCD_SetLayer(LCD_FOREGROUND_LAYER)函数后,

31 以下液晶操作都在前景层刷新,除非重新调用过LCD_SetLayer函数设置背景层*/

32 LCD_SetColors(LCD_COLOR_RED,LCD_COLOR_BLACK);

33 /*=========================液晶初始化结束===========================*/

34

35 /*

36 * 当我们配置过RTC时间之后就往备份寄存器0写入一个数据做标记

37 * 所以每次程序重新运行的时候就通过检测备份寄存器0的值来判断

38 * RTC 是否已经配置过,如果配置过那就继续运行,如果没有配置过

39 * 就初始化RTC,配置RTC的时间。

40 */

41 if (RTC_ReadBackupRegister(RTC_BKP_DRX) != 0X32F3) {

42 /* RTC配置:选择时钟源,设置RTC_CLK的分频系数 */

43 RTC_Config();

44

45 /* 闹钟设置 */

46 RTC_AlarmSet();

47

48 /* 设置时间和日期 */

49 RTC_TimeAndDate_Set();

50

51

52 } else {

53 /* 检查是否电源复位 */

54 if (RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET) {

55 printf("\r\n发生电源复位....\r\n");

56 }

57 /* 检查是否外部复位 */

58 else if (RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET) {

59 printf("\r\n发生外部复位....\r\n");

60 }

61

62 printf("\r\n不需要重新配置RTC....\r\n");

63

64 /* 使能 PWR 时钟 */

65 RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

66 /* PWR_CR:DBF置1,使能RTC、RTC备份寄存器和备份SRAM的访问 */

67 PWR_BackupAccessCmd(ENABLE);

68 /* 等待 RTC APB 寄存器同步 */

69 RTC_WaitForSynchro();

70

71 /* 清除RTC中断标志位 */

72 RTC_ClearFlag(RTC_FLAG_ALRAF);

73 /* 清除 EXTI Line 17 悬起位 (内部连接到RTC Alarm) */

74 EXTI_ClearITPendingBit(EXTI_Line17);

75 }

76

77 /* 显示时间和日期 */

78 RTC_TimeAndDate_Show();

79 }

主函数中,我们通过读取备份寄存器的值来判断RTC是否初始化过,如果没有则初识话RTC,并设置闹钟时间,如果已经初始化过,则判断是电源还是外部引脚复位,并清除闹钟相关的中断标志位。

3.    下载验证

把编译好的程序下载到开发板,当日历时间到了闹钟时间时,蜂鸣器一直响,但日历会继续运行。

43.9 每课一问

1、修改RTC时间的字段掩码,设置每小时的30分钟:30秒都产生闹钟。

 

巧用STM32片内RTC亚秒特性之应用示例 绝大多数STM32系列里的RTC都具有亚秒【或称子秒】计数单元。为了了解亚秒特性及功能,不妨先看RTC的功能框图。本文中的有关截图若无特别说明均来自STM32L4系列参考手册。RTC的时钟源【RTCCLK】可以是LSE、LSI或者HSE/32,由RTCCLK最终变成日历的秒脉冲驱动信号经过了2次分频。先经过上图中A处的异步分频单元,默认分频系数是128,形成ck_apre时钟,默认情况下该时钟频率... 阅读详情

相关推荐

STM32F030 RTC内部晶振/外部晶振/闹钟

【一】RTC初始化函数,用宏定义设置内部/外部晶振,使用主频晶振8MHz,外部RTC晶振32.768KHz。 /****************************************************************************/ /*Function Name : RTC Config */ /*Author ...

weindi2009的专栏 4802

linux 下的clock_gettime() 获取精确时间函数

#include <time.h> int clock_gettime(clockid_t clk_id, struct timespec* tp); clock_gettime() 函数是基于linux 操作系统的。 可以根据需要,获取不同要求的精确时间,通过第一个参数。 参数 clk_id : 检索和设置的clk_id指定的时钟时间。CLOCK_REALTIM...

weixin_30389003的博客 693

《Linux系统调用:chmod,fchmod》

dd

yexiang优快云的专栏 683

STM32F429 >> 19. RTC_实时时钟

简介 RTC—real time clock,实时时钟,主要包含日历、闹钟和自动唤醒这三部分的功能,其中的日历功能我们使用的最多。日历包含两个 32bit 的时间寄存器,可直接输出时分秒,星期、月、日、年。 功能框图 1. 时钟源 RTC 时钟源 —RTCCLK 可以从 LSE、LSI 和 HSE_RTC 这三者中得到。其中使用最多的是 LSE。 LSE 由一个外部的 32.768KHZ(6...

原谅我这一生不羁放纵爱自由 2521

ATR2660:卫星导航高增益低噪声放大器芯片数据手册

中国BDS(北斗卫星导航系统),美国的GPS,俄罗斯的GLONASS和欧盟的GALILEO导航系统应用而专门设计。芯片支持3.3V至5V宽电源供电。采用2级放大器的结构设计,具有28dB高增益和0.85dB的低噪声系数。支持BDS、GPS、GALILEO、GLONASS等L。典型功率增益:30dB@5V;典型输入P1dB:-18dBm@3.3V;典型工作电流:12.7mA@3.3V;宽供电电压范围:3.3V~5V;典型噪声系数:0.85dB;频段的多个卫星导航系统;ATR2660是一颗。

YHPsophie的博客 561

保姆级教程:在CentOS 8上用libvirt + QEMU/KVM搭建ARM64虚拟机(含UEFI配置与常见坑点)

本文提供在CentOS 8上使用libvirt + QEMU/KVM搭建ARM64虚拟机的详细教程,涵盖UEFI配置与常见问题解决方案。通过环境准备、特殊配置要点、UEFI固件安装等步骤,帮助用户在x86架构服务器上高效运行ARM64虚拟化环境,特别适合开发测试与跨平台应用场景。

weixin_30292745的博客 130

第43章 RTC—实时时钟—零死角玩转STM32-F429系列

第43章 RTC—实时时钟 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/firege 43.1 RTC简介 RTC—real time clock,实时时钟,主要包含日历、闹钟和自动唤醒这三部分的功能,其中的日历功能我们使用的最多。日历包含两个32bit的时间寄存器,可直接...

EmbeddedCoder 的优快云博客 1742

Python实战:5分钟搞定N-CMAPSS航空发动机数据集解析(附完整代码)

本文提供了一份针对N-CMAPSS航空发动机数据集的快速解析实战指南。通过Python的h5py库,详细演示了如何读取HDF5文件结构、理解数据分类(如传感器、健康参数、场景描述符)并加载为Pandas DataFrame。文章还澄清了数据集中常见的变量数量疑惑,并给出了从数据加载到构建剩余使用寿命预测模型预处理流水线的完整代码,帮助工程师和研究人员高效入门航空发动机预测性维护分析。

weixin_29057065的博客 422

Linux clock_gettime函数不同时钟的区别

Linux 不同时钟的区别 函数: int clock_gettime(clockid_t clk_id, struct timespec *tp); clockid_t: 用于指定计时时钟的类型,有以下几种类型: 1 2 3 4 CLOCK_REALTIME CLOCK_MONOTONIC CLOCK_MON...

wwwtovvv的专栏 758

【多模态大模型】GLIP:零样本目标检测新范式与视觉语言理解

本文深入解析了多模态大模型GLIP在零样本目标检测和视觉语言理解领域的创新应用。GLIP通过统一目标检测与自然语言理解任务,实现了零样本学习能力,能够精准定位复杂文本描述对应的图像区域。文章详细介绍了GLIP的核心技术、数据策略及实战表现,并对比了与其他多模态模型的差异,为AI视觉理解提供了新范式。

weixin_29186249的博客 263

折叠式共源共栅放大器设计/备忘

w折叠式共源共栅基本结构如图

Czy1377004611的博客 3万+

Linux 下使用clock_gettime给程序计时详解

Linux 下使用clock_gettime给程序计时详解,函数的原型如下: int clock_gettime(clockid_t clk_id, struct timespect *tp); clockid_t clk_id用于指定计时时钟的类型,对于我们Programmr以下三种比较常用: CLOCK_REALTIME, a system-wide realtim

YUZHIBOYI的专栏 6401

【制作100个unity游戏之30】使用unity实现一款2d俯视角RPG战斗游戏,主要使用InputSystem+有限状态机+A*寻路实现(完结,附带项目源码)

【制作100个unity游戏之30】使用unity实现一款2d俯视角RPG战斗游戏,主要使用InputSystem+有限状态机+A*寻路实现

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 4653

STM32日历读取,设置和输出

一、了解时钟RTC RTC (Real Time Clock):实时时钟 RTC是个独立的定时器。RTC模块拥有一个连续计数的计数器,在相应的软件配置下,可以提供时钟日历的功能。修改计数器的值可以重新设置当前时间和日期 RTC还包含用于管理低功耗模式的自动唤醒单元。 在断电情况下 RTC仍可以独立运行 只要芯片的备用电源一直供电,RTC上的时间会一直走。 RTC实质是一个掉电后还继续运行的定时器,从定时器的角度来看,相对于通用定时器TIM外设,它的功能十分简单,只有计时功能(也可以触发中断)。但其高

qq_45874317的博客 6027

1、基于改进3D卷积神经网络的阿尔茨海默病分类

本文提出了一种基于改进3D卷积神经网络的阿尔茨海默病(AD)分类方法,利用3D CNN对预处理后的T1加权MRI数据进行空间特征提取,并在VGG网络结构中引入类似ResNet的跳跃连接以缓解模型退化和过拟合问题。实验基于ADNI数据集,包含AD、MCI和NC三类样本,结果表明改进后的3D VGG模型在AD/NC、MCI/NC及多分类任务中均取得了优异性能,尤其在AD/MCI/NC分类中准确率达到98.50%,优于现有典型3D深度学习方法。研究验证了3D CNN在脑部疾病诊断中的有效性,并为AD的早期识别提供

kk1234的博客 90

基于Spring Security 6的OAuth2 系列之二 - 客户端--非代码演示授权码模式

至此,我们就使用浏览器+postman工具演示了通过授权码模式去获取Gitee的用户信息。这过程中,我们只是遵循OAuth2的流程,就能够实现授权方法。那么接下来,我们采用代码方式来实现这个流程。

代码让AI扣 1813

RTC时钟操作

RTC(Real Time Clock):实时时钟 1、RTC是个独立的BCD定时计数器,提供一个日历时钟,两个可编程闹钟中断,以及一个具有中断功能的周期性可编程唤醒标志。RTC还包含用于管理低功耗模式的自动唤醒单元。 2、两个32位寄存器包含二进制码十进制格式(BCD)的秒,分钟,小时(12/24小时制),星期几,日期,月份和年份,此外还可以提供二进制的亚秒值。 3、系统还可以自动将月份的天数补...

flying_man_的博客 4453

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

RT-thread之RTC时间的获取

开启RTC后,用rt-thread官方给的例程,可以正确打印时间了,但如何使用时间的数值呢?比如要判断是白天和晚上的时间??官方没有给出说明,但前面说过,rt-thread与linux操作很相似,和时间相关time.h也是兼容ANSIC的。所以关于时间的获取这块,可以参考linux时间的用法。下面简要说明下linux时间几种使用方式。 linux下常用的几个时间函数:asctime, ctime, gmtime, localtime,gettimeofday,mktime, asctime_r...

guangod的博客 1万+

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Linux时间相关函数

声明:如果涉及侵权,请联系本人删除侵权内容。 声明:本文由本人以以往工作经验为依据,总结而得,如果错误,欢迎指正,便于后人参考,少走弯路。 开发中经常会用到时间,针对不同应用,对时间的需求有所不同: 时间精度(计时等,秒级、毫秒级、微秒级、纳秒级); 时间格式(RTC显示等,年、月、日、时、分、秒的常用不同排列组合); 时间计时(周期报文的发送等); 时间...

BurgessKzg的博客 1334

使用stm32内部时钟的RTC配置

#include "rtc.h" #include "delay.h" #include "led.h" ////////////////////////////////////////////////////////////////////////////////// //本程序只供学习使用,未经作者许可,不得用于其它任何用途 //ALIENTEK STM32F429开发板 //RTC...

qq_20312079的博客 3086

Stm32 中RTC秒中断的使用方法及例子

RTC(Real Time Clock)是实时时钟的意思,它其实和TIM有点类似,也是利用计数的原理,选择RTC时钟源,再进行分频,到达计数的目的。 该文主要讲述关于RTC的秒中断功能,这个功能类似SysTick系统滴答的功能。RTC秒中断功能其实是每计数一次就中断一次。注意,这里所说的秒中断并非一定是一秒的时间,它是由RTC时钟源和分频值决定的“秒”的时间,当然也是可以做到1秒钟中断一次。 ...

lilp2896的博客 2万+

STM32 的 RTC(实时时钟)详解

STM32 的 RTC 模块为嵌入式系统提供了可靠的时间基准。通过了解 RTC 的工作原理、配置方法和应用场景,开发者可以充分利用 RTC 的功能,为系统添加时间记录、定时任务等功能,提高系统的实用性和可靠性。在使用 RTC 时,需要注意时钟源的选择、时间的初始化和校准以及备份寄存器的使用等问题,以确保 RTC 的正常运行和数据的安全性。希望本文对大家在使用 STM32 的 RTC 模块时有所帮助。

千千道的博客 9979

RTC_TimeTypeDef结构体:STM32

一看我就知道这个参数是当使用12小时制的时候,表示上午或者下午的,只能取上面这2个值里面的一个。这个结构体最后2个已经没有用了:DayLightSaving,StoreOperation。其他的4个参数又不用怎么说,一看就知道;最后一个:SecondFraction。其中的TimeFormat。

316

STM32——RTC实时时钟

RTC简介 STM32F4的RTC,是一个独立的BCD 定时器/计数器。STM32F4的RTC 提供一个日历时钟(包含年月日时分秒信息)、两个可编程闹钟(ALARM A和ALARM B)中断,以及一个具有中断功能的周期性可编程唤醒标志。RTC 还包含用于管理低功耗模式的自动唤醒单元。STM32F4的实时时钟(RTC)相对于STM32F1来说,改进了不少,自带了日历功能,让软件编程更加简单。 两个32位寄存器(TR和DR)包含二进码十进数格式(BCD) 的秒、分钟、小时(12或24小时制)、星期、日期、月份和

没实力的码农写的渣渣博客 5622

初窥门径32系列15--RTC,读写时间,设置闹钟

STM32HAL库RTC配置使用

weixin_60301126的博客 1379
上一篇: 第41章 RS-485通讯实验—零死角玩转STM32-F429系列
下一篇: 第44章 MPU6050传感器—姿态检测—零死角玩转STM32-F429系列
0木木0
博客等级 码龄17年 458粉丝 58原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值