STM32开发(十六)STM32F103 片内资源 —— 实时时钟RTC 详解

news2024/11/17 15:36:56

文章目录

    • 一、基础知识点
    • 二、开发环境
    • 三、STM32CubeMX相关配置
    • 四、Vscode代码讲解
    • 五、结果演示
      • 串口显示乱码解决方案


一、基础知识点

本实验通过stm32片内资源RTC实现实时时钟,通过数码管显示时间。设定闹钟,实现准点报时。
数码管相关知识点:
1、数码管 TM1620芯片手册 解析
2、数码管显示
RTC相关知识点:
1、RTC特点
(1)可编程的预分频系数:分频系数最高为2^20。
(2)32位的可编程计数器,可用于较长时间段的测量。
(3)2个分离的时钟:用于APB1接口的PCLK1和RTC时钟(RTC时钟的频率必须小于PCLK1时钟频率的四分之一以上)。
(4)可以选择以下三种RTC的时钟源:

  • HSE时钟除以128
  • LSE振荡器时钟;
  • LSI振荡器时钟

(5)2个独立的复位类型:

  • APB1接口由系统复位;
  • RTC核心(预分频器、闹钟、计数器和分频器)只能由后备域复位。

(6)3个专门的可屏蔽中断:

  • 闹钟中断,用来产生一个软件可编程的闹钟中断。
  • 秒中断,用来产生一个可编程的周期性中断信号(最长可达1秒)。
  • 溢出中断,指示内部可编程计数器溢出并回转为0的状态

2、RTC内部框图

灰色部分是后备区域,在设备断电后,可由纽扣电池供电。
后备区域包括(RTC时钟预分配器、计数器),这里注意的是闹钟,RTC溢出,秒中断在断电之后不起作用。

3、当断电之后CLK时钟是怎么产生的? ———— LSE时钟(纽扣电池供电)


二、开发环境

1、硬件开发准备
主控:STM32F103ZET6
芯片内部RTC

2、软件开发准备
软件开发使用虚拟机 + VScode + STM32Cube 开发STM32,在虚拟机中直接完成编译下载。
该部分可参考:软件开发环境构建


三、STM32CubeMX相关配置

1、STM32CubeMX基本配置
本实验基于CubeMX详解构建基本框架 进行开发。

2、STM32CubeMX RTC相关配置
(1)时钟配置
在这里插入图片描述

(2)RTC参数配置
在这里插入图片描述

(3)中断开启并配置
在这里插入图片描述

在这里插入图片描述


四、Vscode代码讲解

1、RTC相关结构体定义以及初始化

typedef struct
{
    RTC_TimeTypeDef *pMyrtc_current_time;
    RTC_DateTypeDef *pMyrtc_current_date;

    void (*Myrtc_Set_Alarm_Time_Date)(void);              // 设置闹钟时间
    void (*Myrtc_Set_Current_Time_Date)(void);            // 设置当前时间和日期
    void (*Myrtc_Get_Current_Time_Date)(void);            // 获取当前时间和日期
    void (*Myrtc_Disp_Current_Time_Date)(void);            // 打印当前时间和日期
} Myrtc_t;

extern Myrtc_t Myrtc;

Myrtc_t Myrtc ={
    &RTC_TimeStruct_CurrentValue,
    &RTC_DateStruct_CurrentValue,

    Myrtc_Set_Alarm_Time_Date,        // 设置闹钟时间
    Myrtc_Set_Current_Time_Date,      // 设置当前时间和日期
    Myrtc_Get_Current_Time_Date,      // 获取当前时间和日期
    Myrtc_Disp_Current_Time_Date      // 数码管打印当前时间和日期
};

2、函数具体实现

(1)获取当前时间和日期

static void Myrtc_Get_Current_Time_Date(void)
{
  // 获取当前时间
  HAL_RTC_GetTime(&hrtc, Myrtc.pMyrtc_current_time, RTC_FORMAT_BIN);
  // 获取当前日期
  HAL_RTC_GetDate(&hrtc, Myrtc.pMyrtc_current_date, RTC_FORMAT_BIN);
}

(2)数码管打印当前时间和日期

static void Myrtc_Disp_Current_Time_Date(void)
{
    //串口打印日期
    printf("当前时间为: %02u年%02d月%02d日(星期%s)  ", 2000+Myrtc.pMyrtc_current_date->Year,Myrtc.pMyrtc_current_date->Month,Myrtc.pMyrtc_current_date->Date,Week_Str[Myrtc.pMyrtc_current_date->WeekDay]);
    //串口打印时间
    printf("%02u:%02u:%02u\r\n",Myrtc.pMyrtc_current_time->Hours,Myrtc.pMyrtc_current_time->Minutes,Myrtc.pMyrtc_current_time->Seconds);
    // 数码管显示
    Display.Disp(Disp_NUM_GRID1, Myrtc.pMyrtc_current_time->Hours/10, Disp_DP_OFF);
    Display.Disp(Disp_NUM_GRID2, Myrtc.pMyrtc_current_time->Hours%10, Disp_DP_ON);
    Display.Disp(Disp_NUM_GRID3, Myrtc.pMyrtc_current_time->Minutes/10, Disp_DP_OFF);
    Display.Disp(Disp_NUM_GRID4, Myrtc.pMyrtc_current_time->Minutes%10, Disp_DP_ON);
    Display.Disp(Disp_NUM_GRID5, Myrtc.pMyrtc_current_time->Seconds/10, Disp_DP_OFF);
    Display.Disp(Disp_NUM_GRID6, Myrtc.pMyrtc_current_time->Seconds%10, Disp_DP_ON);
}

(3)设置当前时间和日期

// 设置时间
static void Myrtc_Set_Current_Date(void)
{
    RTC_DateTypeDef RTC_DateStruct_SetValue;
    uint8_t SetValue;
    
    printf("=========================DWB日期设置==================\n");
    printf("请输入年份(00-99): 20\n");
    SetValue = 0xFF;
    while (SetValue == 0xFF)
    {
        SetValue = Input_RTC_SetValue(99);
    }
    printf("年份被设置为:  20%02u\n", SetValue);
    RTC_DateStruct_SetValue.Year = SetValue;
    getchar();
    
    printf("请输入月份(01-12):  \n");
    SetValue = 0xFF;
    while (SetValue == 0xFF)
    {
        SetValue = Input_RTC_SetValue(12);
        
        if(SetValue == 0x00)
        {
            printf("月份不能设置为0,请重新输入月份:\r\n");
            SetValue = 0xFF;
        }
    }
    printf("月份被设置为:  %02u\n", SetValue);
    RTC_DateStruct_SetValue.Month = SetValue;
    getchar();
    
    printf("请输入日期(01-31):  \n");
    SetValue = 0xFF;
    while (SetValue == 0xFF)
    {
        SetValue = Input_RTC_SetValue(31);
        
        if(SetValue == 0x00)
        {
            printf("日期不能设置为0,请重新输入日期:\r\n");    
            SetValue = 0xFF;
        }
    }
    printf("日期被设置为:  %02u\r\n", SetValue);
    RTC_DateStruct_SetValue.Date = SetValue;
    getchar();

    //设置日期
    HAL_RTC_SetDate(&hrtc,&RTC_DateStruct_SetValue,RTC_FORMAT_BIN);
}

// 设置日历
static void Myrtc_Set_Current_Time(void)
{
    RTC_TimeTypeDef RTC_TimeStruct_SetValue;
    uint8_t SetValue;
    
    printf("=========================DWB时间设置==================\n");
    printf("请输入时钟(00-23):  \n");
    SetValue = 0xFF;
    while (SetValue == 0xFF)
    {
        SetValue = Input_RTC_SetValue(23);
    }
    printf("时钟被设置为:  %02u\n", SetValue);
    RTC_TimeStruct_SetValue.Hours = SetValue;
    getchar();

    printf("请输入分钟(00-59):  \n");
    SetValue = 0xFF;
    while (SetValue == 0xFF)
    {
        SetValue = Input_RTC_SetValue(59);
    }
    printf("分钟被设置为:  %02u\n", SetValue);
    RTC_TimeStruct_SetValue.Minutes = SetValue;
    getchar();

    printf("请输入秒钟(00-59):  \n");
    SetValue = 0xFF;
    while (SetValue == 0xFF)
    {
        SetValue = Input_RTC_SetValue(59);
    }
    printf("秒钟被设置为:  %02u\n", SetValue);
    RTC_TimeStruct_SetValue.Seconds = SetValue;
    getchar();
    //设置时间
    HAL_RTC_SetTime(&hrtc,&RTC_TimeStruct_SetValue,RTC_FORMAT_BIN);
}

static void Myrtc_Set_Current_Time_Date(void)
{
    Myrtc_Set_Current_Date();
    Myrtc_Set_Current_Time();
}

(4)设置闹钟时间

// 设置闹钟
static void Myrtc_Set_Alarm_Time_Date(void)
{
    RTC_AlarmTypeDef RTC_AlarmStruct_SetValue;
    uint8_t SetValue;

    printf("=========================DWB闹钟时间设置==================\n");
    printf("请输入时钟(00-23):  \n");
    SetValue = 0xFF;
    while (SetValue == 0xFF)
    {
        SetValue = Input_RTC_SetValue(23);
    }
    printf("时钟被设置为:  %02u\n", SetValue);
    RTC_AlarmStruct_SetValue.AlarmTime.Hours = SetValue;
    getchar();

    printf("请输入分钟(00-59):  \n");
    SetValue = 0xFF;
    while (SetValue == 0xFF)
    {
        SetValue = Input_RTC_SetValue(59);
    }
    printf("分钟被设置为:  %02u\n", SetValue);
    RTC_AlarmStruct_SetValue.AlarmTime.Minutes = SetValue;
    getchar();

    printf("请输入秒钟(00-59):  \n");
    SetValue = 0xFF;
    while (SetValue == 0xFF)
    {
        SetValue = Input_RTC_SetValue(59);
    }
    printf("秒钟被设置为:  %02u\n", SetValue);
    RTC_AlarmStruct_SetValue.AlarmTime.Seconds = SetValue;
    getchar();

    HAL_RTC_SetAlarm_IT(&hrtc, &RTC_AlarmStruct_SetValue, RTC_FORMAT_BIN);
}


五、结果演示

请添加图片描述

串口显示乱码解决方案

现象:实验过程中出现与串口通讯中文乱码现象,如下图所示

原因: vscode 编写代码默认是以UTF-8格式编写的,但是SSCOM串口工具是以GBK格式显示的。
因此代码里的需要在串口中显示的中文,会以UTF-8的形式编码。由于SSCOM串口工具只能用GBK格式译码显示,则出现乱码现象。

解决方案:
在编写代码的时候用GBK格式编写,这样就和SSCOM译码格式相符合
在这里插入图片描述

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

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

相关文章

maven总结

maven maven1.构建依赖2.依赖冲突的规则3.可选依赖和排除依赖可选依赖排除依赖 4.依赖范围5.项目构建生命周期6.插件7.模块聚合8.模块继承9.属性(类似常量)(1) 自定义属性(2)直接调用内置属性 10.多个环境配…

PingPingPing

拿到题的时候我是没有丝毫的思路,可能是没有做过太多命令注入的题目,所以反应不过来 还是查看的别人的wp,得知这是一道有关命令注入的题目 通过页面提示传入ip并且利用管道符查看所有文件 但是当我们查看flag.php的时候发现页面过滤掉了空格 …

诊断DTC故障码两种形式的转换:符号转数字

诊断DTC code数据由3个字节组成:HighByte + MiddleByte + LowByte。有两种表现形式: 数字:三个字节值用16进制表示,比如0xC07304符号:这种形式更直观地用字符描述该DTC故障所属的系统,故障类型等信息我们重点讲一下符号的形式: 字符形式的DTC故障码,由7个字符组成,代…

Chatbox - 一款适用于 GPT-4 / GPT-3.5 (OpenAI API) 的桌面应用程序

简介 给大家推荐一款适用于 GPT-4 / GPT-3.5 (OpenAI API) 的桌面应用程 ChatBox,开源的 ChatGPT API (OpenAI API) 跨平台桌面客户端,Prompt 的调试与管理工具,也可以用作 ChatGPT Plus 平替。 下载 ► chatBox 下载安装 ⇲ 为什么不直接…

3D目标检测--PointPillars论文和OpenPCDet代码解读

文章目录 1. 论文动机2. PointPillars概述3. PointPillars模型3.1 Pillar Feature Net3.1.1 Pillar Feature Net模块理论解析3.1.2 Pillar Feature Net模块代码解析 3.2 Backbone(2D CNN)3.2.1 Backbone(2D CNN)模块理论解析3.2.2…

LeetCode 312. Burst Balloons【区间DP】困难

本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章…

校验规则引擎

目录 一 架构设计图 二 表设计及数据展示 三 顶层接口 四 压测结果 五 其他规则引擎比较 适用场景:校验场景以及使用该思想进行可视化配置化开发(可大幅提高开发效率,长期维护简单) 例如:履约系统下单中的校验&…

C++(初识结束)

目录 4缺省参数 4.1缺省参数的概念 4.2缺省参数分类 4.3缺省参数的应用 5.函数重载 5.1函数重载概念 5.2c支持函数重载的原理-名字修饰(name Mangling) 6.引用 6.1引用概念 6.2引用特性 6.3常引用 6.4使用场景 6.4.1做参数 6.4.2做返…

2023年4月-近期看书

复习书记 用于读书 文章目录 复习书记一、(2001)控制工程基础二、(3001)交通管理与控制三、(1001)英语 一、(2001)控制工程基础 学习这本书的前6章节。 参看视频链接: https://www.bilibili.com/video/BV1Sb411q7jU?p8&spm_id_frompageDriver&vd_source…

构建完善的帮助中心:降低企业客户服务成本,提高客户满意度

客户服务是企业成功的关键之一,一家公司的成功不仅仅取决于产品或服务的质量,还在于能否为客户提供优质的客户服务。随着现代科技的发展,企业需要面对越来越多的客户服务需求,不良的客户服务将对企业的声誉和业务产生严重的影响。…

马斯克爆料Twitter裁了八成员工;OpenAI CEO:GPT-5根本不存在;小鹏被曝年终奖打0.5折 | AI一周资讯

来源: AI前线 微信号:ai-front 整理 | 凌敏 微软宣布开源 Deep Speed Chat;消息称软银旗下 Arm 启动赴美 IPO;国家网信办出台生成式 AI 管理办法;前理想 AI 芯片一号位骄旸加入三星,负责组建 GPU 团队…… 资 讯 Op…

KHS灌装机西门子触摸屏维修6AV6545-6DB10-0BS0

KHS设备维修范围包括:KHS无菌灌装设备,KHS包装设备,PET瓶装机, KHS码垛设备, KHS灌装机。 科埃斯KHS灌装机西门子P350工控机常见故障现象 1、工控机开机有显示,但是屏幕很暗,用调亮度功能键调…

熵、贝叶斯、极大似然

熵及熵在机器学习中的作用 熵 reference:https://blog.csdn.net/tsyccnh/article/details/79163834 香农给熵的定义:无损编码事件信息的最小平均编码长度 直观理解熵的定义:表示某一件事的不确定性 I ( x 0 ) − l o g ( p ( x 0 ) ) I(…

【Java版oj】day37数据库连接池、mkdir

目录 一、数据库连接池 (1)原题再现 (2)问题分析 (3)完整代码 二、mkdir (1)原题再现 (2)问题分析 (3)完整代码 一、数据库连接…

ChatGPT会如何改变制造业?

来源 | Smart Industry Edgenesis编译 ChatGPT最新版本的发布成为热门头条。OpenAI表示该版本的ChatGPT能够在多个专业测试中达到“人类水平”的表现,例如司法考试和SAT考试。不过,在工业领域中,ChatGPT能够发挥怎样的作用呢?Sma…

升级OpenSSH版本(安装telnet远程管理主机

目录 一.OpenSSH是什么? 二.升级OpenSSH版本至8.9 1.环境介绍 2.检查是否安装telnet 3.安装telnet服务 4.启动telnet服务 5.安全文件关闭或者修改(否则root无法telnet登录) 6.安装依赖包 7.备份原有SSH服务版本 8.下载OpenSSH升级所需安装包 9.删除现有…

MySQL索引失效的七大场景

文章目录 口诀初始化数据库索引失效七大场景模(模糊查询)型(数据类型)数(函数)或(OR)运(运算)最(最左原则)快(查询数据量大…

接口自动化测试系统知识大全,你想要的全都有

目录 接口自动化测试的前景 接口自动化测试的方法 接口自动化测试怎么做 接口自动化测试工具有哪些? 接口自动化测试框架 接口自动化测试的前景 随着移动互联网、云计算和大数据等技术的不断发展,接口自动化测试在软件开发中的重要性越来越凸显。尤其是随着微…

typora导出PDF很慢的解决办法

Typora导出PDF文件一直卡住 以前可以导出,但突然导出错误 1、首先,查看服务中的Print Spooler是否打开,没有打开进行服务打开 2、打开后,再进行导出,不行的话,就是前面的打印进程阻塞 解决方法&#xff…

软件测试?月薪20k+?不会自动化测试的我真的很难....

做自动化测试后悔吗? 后悔,真的后悔! 后悔没有早点学..... 虽然现在网上到处都在散播35的焦虑,姑且信之,那么反问你,如果你30岁了,那么给你5年,能够在某个领域成为专家呢&#xf…