ARM32开发——(十八)RTC实时时表

news2024/9/20 8:01:07

1. RTC内置实时时钟

1.1 RTC时钟介绍

RTC是实时时钟(Real-Time Clock)的缩写。它是一种硬件模块或芯片,用于提供准确的日期和时间信息。

GD32F407上有RTC的外设,它提供了一个包含日期(年/月/日)和时间(时/分/秒/亚秒)的日历功能。除亚秒用二进制码显示外,时间和日期都以BCD码的形式显示。

RTC本质上就是一个1秒计数器,通过秒来换算出时间。因此需要我们提供一个1HZ频率的时钟。

1.2 RTC结构框图

1.3 RTC原理图

1.4 RTC时钟电源

RTC时钟分为两个电源域。RTC的核心部分位于备份域中。系统复位或从待机模式唤醒时,RTC的设置和时间都保持不变。另一部分包括APB接口及一组控制寄存器位于VDD电源域中。

1.5 RTC的配置流程

2. RTC时钟备份寄存器

RTC时钟有20个32位(共80字节)通用备份寄存器,能够在省电模式下保存数据。通过备份寄存器可以实现只配置一次时间即可。

注意:如果在尝试向RTC_BKP0写入数据之前或之后调用了rcu_bkp_reset_enable(),那么这确实会导致写入的数据在系统复位后丢失,因为RTC备份寄存器会被复位重置。因此,要确保在向RTC备份寄存器写入数据并期望这些数据在复位后仍然有效时,不能调用rcu_bkp_reset_enable()。

if( RTC_BKP0 == 0xf234 ){	
	//说明不是第一次初始化,可以不用重新设置时间
}else{//如果后备寄存器0 的值 不为 0XF234
    //设置后备寄存器0的值为 0XF234,标记已经初始化过RTC
    RTC_BKP0 = 0xf234;
    //初始化RTC时间
    RtcTimeConfig(0x23,0x07,0x12,0x03,0x12,0x59,0x50);
}

3. RTC闹钟Alarm 

3.1 开发流程

  • 配置RTC时钟

  • 设置RTC闹钟

  • 配置RTC闹钟中断

  • 实现中断函数

3.1.1 RTC闹钟初始化
// RTC Alarm ---------------------------
rtc_alarm_struct rat;
// 设置忽略的选项 (让闹钟在每分钟的xx秒都执行)
rat.alarm_mask  = RTC_ALARM_DATE_MASK | RTC_ALARM_HOUR_MASK | RTC_ALARM_MINUTE_MASK; 
// 设置忽略的选项 (让闹钟在每小时的xx分钟xx秒都执行)
//  rat.alarm_mask  = RTC_ALARM_DATE_MASK | RTC_ALARM_HOUR_MASK; 
// 设置忽略的选项 (让闹钟在每天的xx小时xx分钟xx秒都执行)
//  rat.alarm_mask  = RTC_ALARM_DATE_MASK; 

// 设置选择日期/周  25日/周6 23:59:58
rat.weekday_or_date = RTC_ALARM_DATE_SELECTED;
rat.alarm_day     = 0x25; // 日期
rat.alarm_hour    = 0x23; // 小时
rat.alarm_minute  = 0x59;  // 分钟
rat.alarm_second  = 0x58;  // 秒
rat.am_pm = RTC_PM;		  // AM上午,PM下午
rtc_alarm_config(RTC_ALARM0, &rat);

// NVIC -----------------------------------
nvic_irq_enable(RTC_Alarm_IRQn, 2, 2);
// 启用alarm0中断
rtc_interrupt_enable(RTC_INT_ALARM0);
// 清理alarm0标记
rtc_flag_clear(RTC_FLAG_ALRM0);
/* 启用enable RTC alarm */
rtc_alarm_enable(RTC_ALARM0);

// EXTI --------------------------------------
// 先清理EXTI_17 ALARM0标记
exti_interrupt_flag_clear(RTC_EXTI_LINE);
exti_flag_clear(RTC_EXTI_LINE);
// 初始化EXTI_17 (必须初始化)
exti_init(RTC_EXTI_LINE,EXTI_INTERRUPT,EXTI_TRIG_RISING);
exti_interrupt_enable(RTC_EXTI_LINE);
3.2.2 中断函数
#define RTC_EXTI_LINE   EXTI_17

// 闹铃中断
void RTC_Alarm_IRQHandler(void){

   // 以下判断,二选其一即可
  
  if(SET == rtc_flag_get(RTC_FLAG_ALRM0)){
    rtc_flag_clear(RTC_FLAG_ALRM0);
    exti_flag_clear(RTC_EXTI_LINE);
    printf("Alarm_1!\n");
  }
  
//  if(SET == exti_interrupt_flag_get(RTC_EXTI_LINE)){
//    exti_interrupt_flag_clear(RTC_EXTI_LINE);
//    exti_flag_clear(RTC_EXTI_LINE);
//    rtc_flag_clear(RTC_FLAG_ALRM0);
//    printf("Alarm_2!\n");
//  }
  
}
3.3.3 完整代码
#include "gd32f4xx.h"
#include "systick.h"
#include <stdio.h>
#include "main.h"
#include "Usart.h"

// 十位取出左移4位 + 个位 (得到BCD数)
#define WRITE_BCD(val) 	((val / 10) << 4) + (val % 10)
// 将高4位乘以10 + 低四位 (得到10进制数)
#define READ_BCD(val) 	(val >> 4) * 10 + (val & 0x0F)


void Usart0_recv(uint8_t *data, uint32_t len) {
    printf("%s\r\n", data);
}


static void RTC_config() {
    // 电池管理加载
    rcu_periph_clock_enable(RCU_PMU);
    pmu_backup_write_enable();
    
    // 重置备份域(不重置可能导致无法设置晶振,出现不走字情况)
    /* reset backup domain */
    rcu_bkp_reset_enable();
    rcu_bkp_reset_disable();
    
    // 晶振加载
    rcu_osci_on(RCU_LXTAL);
    rcu_osci_stab_wait(RCU_LXTAL);
    rcu_rtc_clock_config(RCU_RTCSRC_LXTAL);
    // RTC功能加载
    rcu_periph_clock_enable(RCU_RTC);
    rtc_register_sync_wait();

    rtc_parameter_struct rps;
    rps.year = WRITE_BCD(23);
    rps.month = WRITE_BCD(04);
    rps.date = WRITE_BCD(20);
    rps.day_of_week = WRITE_BCD(04);
    rps.hour = WRITE_BCD(23);
    rps.minute = WRITE_BCD(59);
    rps.second = WRITE_BCD(55);
    rps.display_format = RTC_24HOUR;
    rps.am_pm = RTC_AM;
    rps.factor_asyn = 0x7F;
    rps.factor_syn = 0xFF;

    rtc_init(&rps);
}

static void RTC_read() {
    rtc_parameter_struct rps;
    rtc_current_time_get(&rps);

    uint16_t year = READ_BCD(rps.year) + 2000;
    uint8_t month = READ_BCD(rps.month);
    uint8_t date = READ_BCD(rps.date);
    uint8_t week = READ_BCD(rps.day_of_week);
    uint8_t hour = READ_BCD(rps.hour);
    uint8_t minute = READ_BCD(rps.minute);
    uint8_t second = READ_BCD(rps.second);

    printf("%d-%d-%d %d %d:%d:%d\r\n", year, month, date, week, hour, minute, second);
}

static void ALARM_config() {
    // 闹钟外部中断
    exti_flag_clear(EXTI_17);
    exti_init(EXTI_17,EXTI_INTERRUPT,EXTI_TRIG_RISING);

    // 重置闹钟
    rtc_alarm_disable(RTC_ALARM0);

    rtc_alarm_struct ras;
    ras.alarm_mask = RTC_ALARM_HOUR_MASK | RTC_ALARM_MINUTE_MASK | RTC_ALARM_SECOND_MASK;
    ras.weekday_or_date = RTC_ALARM_DATE_SELECTED;
    ras.alarm_day = 0x21;
    ras.alarm_hour = WRITE_BCD(23);
    ras.alarm_minute = WRITE_BCD(59);
    ras.alarm_second = WRITE_BCD(59);
    ras.am_pm = RTC_AM;
    rtc_alarm_config(RTC_ALARM0, &ras);

    // 中断配置
    nvic_irq_enable(RTC_Alarm_IRQn, 2, 2);
    rtc_interrupt_enable(RTC_INT_ALARM0);
    rtc_flag_clear(RTC_FLAG_ALRM0);

    rtc_alarm_enable(RTC_ALARM0);
}

void RTC_Alarm_IRQHandler() {
    if (SET == rtc_flag_get(RTC_FLAG_ALRM0)) {
        // 处理RTC闹钟中断
        printf("alarm \r\n");
    }
    rtc_flag_clear(RTC_FLAG_ALRM0);
    exti_flag_clear(EXTI_17);
}


int main(void)
{
    nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
    systick_config();
    Usart0_init();

    RTC_config();
    ALARM_config();

    while(1) {
        RTC_read();

        delay_1ms(1000);
    }
}

3.2 闹钟Bug处理

如果Alarm闹钟未正确触发,或是频繁触发,先检查编译环境配置,尝试把Optimization等级分别调整为-O2 -O3-Ofast 后再编译烧录。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2080953.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JSP中的动态INCLUDE与静态INCLUDE:简明对比

JSP中的动态INCLUDE与静态INCLUDE&#xff1a;简明对比 1、静态INCLUDE2、动态INCLUDE3、总结 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在JSP开发中&#xff0c;页面包含分为动态INCLUDE和静态INCLUDE两种&#xff0c;它们各有特点。…

详细分析Oracle中的ALL_TAB_COLUMNS视图语句

目录 1. 基本知识2. Demo 1. 基本知识 ALL_TAB_COLUMNS 是 Oracle 数据库的一个数据字典视图&#xff0c;用于提供关于数据库中所有可见表的列信息 对于数据库管理、开发和调试非常有用 基本的字段描述如下&#xff1a; 字段名描述OWNER列出表所在的所有者&#xff08;sche…

神经网络——CIFAR10小实战

1.引子 Sequential的使用&#xff1a;将网络结构放入其中即可&#xff0c;可以简化代码。 找了一个对CIFAR10进行分类的模型。 2.代码实战 from torch import nn from torch.nn import Conv2d, MaxPool2d, Flatten, Linearclass Tudui(nn.Module):def __init__(self):super(T…

SOMEIP_ETS_069: Unaligned_SOMEIP_Messages_overUDP

测试目的&#xff1a; 验证设备&#xff08;DUT&#xff09;能够处理在单个UDP包中发送的三个SOME/IP消息&#xff0c;并且即使其中一个SOME/IP消息未对齐&#xff0c;DUT仍能对所有三个请求给出正确的响应。 描述 本测试用例旨在检查DUT在通过UDP协议接收到包含一个未对齐S…

【Pytorch】Linear 层,举例:相机参数和Instance Feaure通过Linear层生成Group Weights

背景 看论文看到这个pipeline&#xff0c;对于相机参数和Instance Fature 的融合有点兴趣&#xff0c;研究如下&#xff1a; Linear 层 Linear 层是最基本的神经网络层之一&#xff0c;也称为全连接层。它将输入与每个输出神经元完全连接。每个连接都有一个权重和一个偏置。…

inflight 守恒算法负反馈解析

终于说到这个话题了。 bbr 不好吗&#xff0c;我自己也做过很多关于 bbr 的仿真验证&#xff0c;现网数据分析以及数学建模&#xff0c;结论均指向 bbr 是一个公平高效且天然不会引发 bufferbloat 的算法&#xff0c;但细节值得商榷&#xff1a; 非理想哑铃拓扑下测量误差的叠…

Dubbo3框架概述

1 什么是分布式系统? 《分布式系统原理与范型》定义: “分布式系统是若干独立计算机的集合,这些计算机对于用户来说就像单个相关系统” 分布式系统(distributed system)是建立在网络之上的软件系统。 简单来说:多个(不同职责)人共同来完成一件事! 任何一台服务器都无法…

Dockerfile+私有仓库

使用Dockerfile创建应用镜像 在Docker file中定义所需要执⾏的指令&#xff0c;使⽤ docker build创建镜 像&#xff0c;过程中会按照dockerfile所定义的内容进⾏打开临时性容器&#xff0c;把docker file中命令全部执⾏完成&#xff0c;就得到了⼀个容器应⽤镜像&#xff0c;每…

PHP-开发工具下载-配置-使用

.1.下载 使用各种人工智能工具推荐的php免费开发工具。 文心一言推荐的工具 讯飞星火的回答 kimi的回答 根据自己的了解&#xff0c;最终选择vscode这款开发工具。 .2.配置 文心一言的回答 讯飞星火的回答 kimi的回答 最终选择使用PHP Debug 插件来支持。 安装中文插件。 …

NASA数据集:MetOp-A ASCAT 第 2 级海洋表面风矢量,针对沿岸海洋进行了优化

MetOp-A ASCAT Level 2 Ocean Surface Wind Vectors Optimized for Coastal Ocean 简介 该数据集包含 MetOp-A 上的高级散射计&#xff08;ASCAT&#xff09;以 12.5 公里采样分辨率&#xff08;注&#xff1a;有效分辨率为 25 公里&#xff09;进行的近实时 2 级沿岸海面风矢…

实战OpenCV之图像的数学运算

基础入门 在OpenCV中&#xff0c;图像的数学运算是一种基本而强大的工具&#xff0c;可以用于多种图像处理任务&#xff0c;包括&#xff1a;图像增强、图像融合、特征提取等。这些运算包括加法、减法、乘法和除法等基本的数学操作。 加法运算&#xff1a;可以用来合并两个图像…

【JS】卢小姐排队问题(100) |思路参考+代码解析(C++)

题目 LYA 的班级要进行一次班级活动&#xff0c;全班同学按照学号从小到大排成一列。但是卢小姐来晚了&#xff0c;没有来得及排队。现在卢小姐想知道&#xff0c;她应该插入到队列的哪个位置&#xff0c;才能保证队列仍然是按照学号从小到大排列的。请你帮助卢小姐找到她应该…

微服务框架之Kitex

Kitex: 高性能的 Golang 微服务框架 Kitex 是由字节跳动&#xff08;ByteDance&#xff09;开发并开源的一款高性能微服务框架&#xff0c;专为构建分布式系统和微服务架构设计。Kitex 基于 Golang&#xff0c;旨在提供一个简单、高效、灵活的开发体验&#xff0c;帮助开发者快…

ST表(区间查询

解决的问题&#xff1a; 数组区间查询最大值和最小值对于解决数组的树状数组的区间修改 ------- 线段树倍增思想 核心代码&#xff1a; #include<bits/stdc.h> using namespace std; const int N1e5; int num[N]; int f[N][N]; int main(){int n;cin>>n;//输入默…

无线通信频率分配

首先看看无线电信号的频谱如何划分&#xff1a; 一、5G NR 3GPP已指定5G NR 支持的频段列表&#xff0c;5G NR频谱范围可达100GHz&#xff0c;指定了两大频率范围&#xff1a; ① Frequency range 1 &#xff08;FR1&#xff09;&#xff1a;就是我们通常讲的6GHz以下频段 频率…

Lesson07---STL简介(了解)

1. 什么是STL 2. STL的版本 3. STL的六大组件 4. STL的重要性 5. 如何学习STL 6.STL的缺陷 1. 什么是STL STL(standard template libaray- 标准模板库 ) &#xff1a; 是 C 标准库的重要组成部分 &#xff0c;不仅是一个可复用的组件库&#xff0c;而且 是一个包罗数据结构与…

【网络】P2P打洞原理

本文首发于 ❄️慕雪的寒舍 1. 引入 如果你折腾过NAS或者BT下载等等玩意&#xff0c;可能听说过“P2P打洞”这一技术名词。简单来说&#xff0c;P2P打洞可以让我们直接在外网访问内网的设备&#xff0c;从而让没有公网IP的家庭设备也能获得“公网直连”的速度。 比如绿联、极…

【JAVA]DAY 2在网页中输出日期和时间,实时还是静止?

一、如何输出日期文本 使用document.write(Date()); 会在网页中输出当前的日期和时间。在 2024 年 8 月 28 日星期三执行这段代码&#xff0c;可能会输出类似 “Wed Aug 28 2024 [具体时间]” 这样的内容。 Date()是 JavaScript 中的一个内置对象&#xff0c;用于处理日期和…

【机器学习】数据预处理-特征工程与特征选择

目录 一、特征工程 二、数据变换 1.变换 2.归一化 三、数据清洗 1.异常数据 2.数据清洗 四、特征选择 1.Filter过滤法 2.Wrapper包裹法 ... 3.Embedded嵌入法 ... 五、降维算法 1.SVD 2.PCA 一、特征工程 特征工程就是从原始数据提取特征的过程&#xff0c;这些…

免费可商用插画素材网站

1、https://undraw.co/illustrations 2、https://iradesign.io/ 3、https://storyset.com/ 4、https://delesign.com/free-designs/graphics/