【STM32单片机】#13 RTC实时时钟

主要参考学习资料:

B站@江协科技

STM32入门教程-2023版 细致讲解 中文字幕

开发资料下载链接:https://pan.baidu.com/s/1h_UjuQKDX9IpP-U1Effbsw?pwd=dspb

单片机套装:STM32F103C8T6开发板单片机C6T6核心板 实验板最小系统板套件科协

目录

  • Unix时间戳
    • UTC/GMT
    • 时间戳转换
  • BKP简介
    • BKP基本结构
  • RTC简介
    • RTC框图
    • RTC基本结构
    • 硬件电路
    • RTC操作注意事项
  • 函数详解
    • BKP库函数
      • BKP_DeInit函数
      • BKP_TamperPinLevelConfig函数
      • BKP_TamperPinCmd函数
      • BKP_ITConfig函数
      • BKP_RTCOutputConfig函数
      • BKP_SetRTCCalibrationValue函数
      • BKP_WriteBackupRegister函数
      • BKP_ReadBackupRegister函数
      • 中断标志位函数
    • PWR_BackupAccessCmd函数
    • RCC库函数
      • RCC_LSEConfig函数
      • RCC_LSICmd函数
      • RCC_RTCCLKConfig函数
      • RCC_RTCCLKCmd函数
      • RCC_GetFlagStatus函数
    • RTC库函数
      • RTC_ITConfig函数
      • RTC_EnterConfigMode函数
      • RTC_ExitConfigMode函数
      • RTC_GetCounter函数
      • RTC_SetCounter函数
      • RTC_SetPrescaler函数
      • RTC_SetAlarm函数
      • RTC_GetDivider函数
      • RTC_WaitForLastTask函数
      • RTC_WaitForSynchro函数
      • 中断标志位函数
  • 实验28 读写备份寄存器
    • 接线图
    • 主程序
  • 实验29 实时时钟
    • MyRTC驱动
    • 主程序

Unix时间戳

  • Unix时间戳定义为从UTC/GMT的1970年1月1日0时0分0秒开始所经过的秒数,不考虑闰秒。
  • 时间戳存储在一个秒计数器中,秒计数器为32位/64位的整型变量。只使用秒而不采取进位的优点是硬件电路简单,仅需秒寄存器和一个变量,且便于计算时间间隔。
  • 世界上所有时区的秒计数器相同,不同时区通过添加偏移来得到当地时间。
  • 32位(有符号)时间戳将在2038年1月19日溢出,现今的电子设备基本采用64位时间戳,可以运作上千亿年。

UTC/GMT

  • GMT(Greenwich Mean Time)格林尼治标准时间是一种以地球自转为基础的时间计量系统,它将地球自转一周的时间间隔等分为24小时,以此确定计时标准。但由于地球自转周期不固定,GMT定义的时间基准也将不断变化,不利于科学研究,因此UTC作为新的时间系统被提出。
  • UTC(Universal Time Coordinated)协调世界时是一种以原子钟为基础的时间计量系统,它规定铯133原子基态的两个超精细能级间在零磁场下跃迁辐射9192631770周所持续的时间为1秒。当原子钟计时一天的时间与地球自转一周的时间相差超过0.9秒时,UTC会执行闰秒来保证其计时与地球自转协调一致。
  • 日常生活中大多不会追求极致的严谨,GMT和UTC可视作相同的时间系统。

时间戳转换

C语言的time.h模块提供了时间获取和时间戳转换的相关函数,可以方便地进行秒计数器、日期时间和字符串之间的转换。本节使用表中localtime和mktime函数。

其中time_t默认为有符号64位整型,char*指向表示时间的字符串,struct tm结构体成员如下:

struct tm {int tm_sec;         /* 秒,范围从 0 到 59        */int tm_min;         /* 分,范围从 0 到 59        */int tm_hour;        /* 小时,范围从 0 到 23        */int tm_mday;        /* 一月中的第几天,范围从 1 到 31    */int tm_mon;         /* 月,范围从 0 到 11        */int tm_year;        /* 自 1900 年起的年数        */int tm_wday;        /* 一周中的第几天,范围从 0 到 6    */int tm_yday;        /* 一年中的第几天,范围从 0 到 365    */int tm_isdst;       /* 夏令时                */
};

BKP简介

  • BKP(Backup Registers)备份寄存器
  • BKP可用于存储用户应用程序数据。当VDD(2.0~3.6V)电源被切断,它们仍由VBAT(1.8~3.6V)维持供电。当系统在待机模式下被唤醒,或系统/电源复位时,它们也不会被复位。
  • 以下是BKP的主要功能,其中后两个与RTC关联:
    • TAMPER引脚(PC13)产生的侵入事件将所有备份寄存器内容清除。
    • RTC引脚(PC13)输出RTC校准时钟、RTC闹钟脉冲或者秒脉冲。外部设备测量RTC校准脉冲可以对其内部RTC微小误差进行校准,闹钟脉冲和秒脉冲可以为别的设备提供信号。
    • 存储RTC时钟校准寄存器。
  • 用户数据存储容量:20字节(中小容量)/84字节(大容量和互联型)

BKP基本结构

图中橙色部分为后备区域,包括BKP和RTC相关电路。后备区域在VDD主电源掉电时,仍然可以由VBAT的备用电池供电;当VDD主电源上电时,后备区域供电会由VBAT切换到VDD。

BKP的数据寄存器用于存储数据,每个DR可存储两个字节,中小容量有10个DR,大容量和互联型有42个DR。侵入检测从TAMPER引脚引入一个检测信号,当TAMPER产生上升/下降沿时,BKP所有内容被清除以保证安全。时钟输出将RTC相关时钟从RTC引脚输出供外部使用,输出校准时钟时配合RTC时钟校准寄存器可以对RTC的误差进行校准。

RTC简介

  • RTC(Real Time Clock)实时时钟
  • RTC是一个独立的定时器,可为系统提供时钟和日历功能。
  • RTC和时钟配置系统处于后备区域,系统复位时数据不清零,VDD断电后可借助VBAT供电继续走时。
  • 32位可编程计数器,可对应Unix时间戳的秒计数器。
  • 20位可编程预分频器,可适配不同频率的输入时钟,分频为1Hz可用于驱动秒计数器。
  • 可选择三种RTC时钟源:
    • HSE时钟(高速外部时钟信号,8MHz)除以128
    • LSE振荡器时钟(低速外部时钟信号,通常为32.768KHz)
    • LSI振荡器时钟(低速内部时钟信号,40KHz)
    • 最常用的时钟源为LSE,32.768KHz经 2 15 2^{15} 215分频即可得到1Hz,且只有LSE可以通过VBAT备用电池供电。

RTC框图

框图左侧为核心的分频计数计时部分,右侧为中断输出使能和NVIC部分,上方为APB1总线读写部分,下方为PWR关联部分,灰色背景部分均处于后备区域。睡眠、停机、待机等低功耗相关内容将在下一节PWR部分讲解。

输入时钟为RTCCLK,由于可选时钟源的频率各不相同,且远大于所需的1Hz秒计数频率,因此RTCCLK需要首先经过RTC预分频器进行分频。分频器由重装载寄存器RTC_PRL和余数寄存器RTC_DIV(自减计数器)组成,本质上和定时器中的重装值ARR和计数器CNT作用相同,计几个数溢出一次即为几分频,由于计数器包含0,因此分频系数为重装值加一。

32位可编程计数器RTC_CNT为计时最核心的部分,可视为Unix时间戳的秒计数器。RTC_ALR为32位闹钟寄存器,可在ALR写入一个秒数设定闹钟,当CNT的值与ALR设定值相等时产生RTC_Alarm信号通往中断系统,或使STM32退出待机模式。其余两个中断信号,秒中断RTC_Second每秒触发,溢出中断RTC_Overflow在32位CNT计满溢出时触发。RTC_CR中,F后缀为中断标志位,IE后缀为中断使能,三个中断信号通过或门前往NVIC中断控制器。

上方APB1总线和APB1接口为程序读写寄存器的地方。下方闹钟信号和WKUP引脚(PA0)均可唤醒STM32,将在下一节学习。

RTC基本结构

除去多余内容,本实验所用到RTC结构如下:

硬件电路

为了配合STM32的RTC,需要连接备用电池供电和外部低速晶振两个外部电路。本节实验最小系统板上已包含外部低速晶振,备用电池使用STLINK的3.3V供电。

备用电池供电中,简单连接直接使用3V电池,负极和系统共地,正极连接VBAT引脚;芯片参考手册的推荐连接同时使用电池和3.3V主电源通过二极管(防止电流倒灌)向VBAT供电,同时使用滤波电容。实验使用简单连接即可,板子绘制和产品设计使用推荐连接更保险。

根据参考手册,外部低速晶振中,X1为32.768KHz晶振,两端分别接在OSC32两个引脚上,并再各自接一个起振电容到GND。

RTC操作注意事项

  • 执行以下操作将使能对BKP和RTC的访问:
    • 设置RCC_APB1ENR的PWREN和BKPEN,使能PWR和BKP时钟(RTC无单独开启时钟选项)
    • 设置PWR_CR的DBP,使能对BKP和RTC的访问
  • 若在读取RTC寄存器时,RTC的APB1接口曾经处于禁止状态,则软件首先必须等待RTC_CRL寄存器中的RSF位(寄存器同步标志)被硬件置1。这是由于RTC由RTCCLK(32.768KHz)驱动,而读取RTC寄存器的APB1总线由PCLK1(36MHz)驱动,存在时钟不同步问题,在APB1刚开启时立刻读取RTC寄存器,有可能RTC寄存器尚未更新到APB1总线上。
  • 必须设置RTC_CRL寄存器中的CNF位,使RTC进入配置模式后,才能写入RTC_PRL、RTC_CNT、RTC_ALR寄存器。该操作在每个写寄存器的库函数中自动配置。
  • 对RTC任何寄存器的写操作,都必须在前一次写操作结束后进行。可以通过查询RTC_CR寄存器中的RTOFF状态位,判断RTC寄存器是否处于更新中。仅当RTOFF状态位是1时,才可以写入RTC寄存器。这也是由于时钟不同步导致APB1写入的值无法立刻更新到RTC寄存器中。

函数详解

BKP库函数

BKP_DeInit函数

简介:恢复缺省配置(手动清空数据寄存器)。

参数:void

BKP_TamperPinLevelConfig函数

简介:配置TAMPER引脚有效电平。

参数:高/低电平

BKP_TamperPinLevel_High/Low

BKP_TamperPinCmd函数

简介:侵入检测使能。

参数:使能/失能

BKP_ITConfig函数

简介:BKP侵入中断配置。

参数:使能/失能

BKP_RTCOutputConfig函数

简介:RTC引脚输出配置。

参数:输出信号

BKP_RTCOutputSource_None(无)
BKP_RTCOutputSource_CalibClock(校准时钟)
BKP_RTCOutputSource_Alarm(闹钟脉冲)
BKP_RTCOutputSource_Second(秒脉冲)

BKP_SetRTCCalibrationValue函数

简介:设置RTC校准值(写入RTC校准寄存器)。

参数:0~0x7F校准值。

BKP_WriteBackupRegister函数

简介:写备份寄存器。

参数一:数据寄存器

BKP_DR1, ..., BKP_DR42

参数二:写入数据

BKP_ReadBackupRegister函数

简介:读备份寄存器。

参数:数据寄存器

中断标志位函数

BKP_GetFlagStatus函数

BKP_ClearFlag函数

BKP_GetITStatus函数

BKP_ClearITPendingBit函数

参数:void(BKP只有侵入检测中断)

PWR_BackupAccessCmd函数

PWR库函数在下一节讲解,本节只使用其中的该函数。

简介:备份寄存器访问使能。

参数:使能/失能

RCC库函数

RCC库函数包含部分RTC时钟相关函数。

RCC_LSEConfig函数

简介:配置外部低速时钟。

参数:LSE工作状态

RCC_LSE_OFF/ON, 
RCC_LSE_ByPass(使用OSC32_IN引脚输入的外部时钟信号)

RCC_LSICmd函数

简介:配置内部低速时钟。

参数:使能/失能

RCC_RTCCLKConfig函数

简介:配置RCCCLK。

参数:RCCCLK时钟源

RCC_RTCCLKSource_LSE/LSI
RCC_RTCCLKSource_HSE_Div128

RCC_RTCCLKCmd函数

简介:使能RTCCLK。

参数:使能/失能

RCC_GetFlagStatus函数

简介:获取标志位。

参数:标志位,本节只用到一个。

RCC_FLAG_LSERDY(LSE启动完成)

RTC库函数

RTC_ITConfig函数

简介:配置中断输出。

参数一:RTC中断源

RTC_IT_OW/ALE/SEC(溢出/闹钟/秒)

参数二:使能/失能

RTC_EnterConfigMode函数

简介:进入配置模式(对应注意事项第三点)。

参数:void

RTC_ExitConfigMode函数

简介:退出配置模式。

参数:void

RTC_GetCounter函数

简介:读取CNT计数器(读取时钟)。

参数:void

RTC_SetCounter函数

简介:写入CNT计数器(设置时钟)。

参数:计数值

RTC_SetPrescaler函数

简介:写入预分频器中的重装载寄存器。

参数:重装值(分频系数减一)

RTC_SetAlarm函数

简介:写入闹钟。

参数:闹钟值

RTC_GetDivider函数

简介:读取预分频器中的余数寄存器(得到比秒更细致的时间)。

参数:void

RTC_WaitForLastTask函数

简介:等待上次操作完成(对应注意事项第四点)。

参数:void

RTC_WaitForSynchro函数

简介:等待同步(对应注意事项第二点)。

参数:void

中断标志位函数

RTC_GetFlagStatus函数

RTC_ClearFlag函数

参数:RTC标志位

RTC_FLAG_RTOFF(写完成)
RTC_FLAG_RSF(同步)
RTC_FLAG_OW
RTC_FLAG_ALR
RTC_FLAG_SEC

RTC_GetITStatus函数

RTC_ClearITPendingBit函数

参数:RTC中断源

实验28 读写备份寄存器

接线图

主程序

BKP的代码较少,因此不单独进行封装。

#include "stm32f10x.h" 
#include "Delay.h"
#include "OLED.h"
#include "Key.h"uint8_t KeyNum;uint16_t ArrayWrite[] = {0x1234, 0x5678};
uint16_t ArrayRead[2];int main(void)
{OLED_Init();Key_Init();OLED_ShowString(1, 1, "W:");OLED_ShowString(2, 1, "R:");//开启时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP, ENABLE);//使能访问PWR_BackupAccessCmd(ENABLE);while(1){KeyNum = Key_GetNum();if(KeyNum){//按下按键后变换测试数据并写入ArrayWrite[0] ++;ArrayWrite[1] ++;BKP_WriteBackupRegister(BKP_DR1, ArrayWrite[0]);BKP_WriteBackupRegister(BKP_DR2, ArrayWrite[1]);OLED_ShowHexNum(1, 3, ArrayWrite[0], 4);OLED_ShowHexNum(1, 8, ArrayWrite[1], 4);}//读取数据ArrayRead[0] = BKP_ReadBackupRegister(BKP_DR1);ArrayRead[1] = BKP_ReadBackupRegister(BKP_DR2);OLED_ShowHexNum(2, 3, ArrayRead[0], 4);OLED_ShowHexNum(2, 8, ArrayRead[1], 4);}
}

实验29 实时时钟

接线在实验28的基础上去掉按键。

MyRTC驱动

驱动文件放在System中。

MyRTC.h

#ifndef __MYRTC_H
#define __MYRTC_Hextern uint16_t MyRTC_Time[];void MyRTC_Init(void);
void MyRTC_SetTime(void);
void MyRTC_ReadTime(void);#endif

MyRTC.c

#include "stm32f10x.h"
#include <time.h>//年月日时分秒
uint16_t MyRTC_Time[] = {2025, 5, 5, 17, 29, 00};
//提前声明设置时间函数用于初始化
void MyRTC_SetTime(void);void MyRTC_Init(void)
{//开启外设时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP, ENABLE);//使能访问PWR_BackupAccessCmd(ENABLE);//利用BKP特性判断系统是否完全断电过//仅在完全断电后的复位操作重置时间//自定义一个初始化时保存在BKP中的值if(BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5){//开启LSE时钟RCC_LSEConfig(RCC_LSE_ON);//等待LSE准备完成while(!RCC_GetFlagStatus(RCC_FLAG_LSERDY));//选择RTCCLK时钟源RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);RCC_RTCCLKCmd(ENABLE);//等待同步RTC_WaitForSynchro();//等待上一次操作完成RTC_WaitForLastTask();//配置预分频器//配置函数自带进入/退出配置模式代码,无需额外调用RTC_SetPrescaler(32768 - 1);RTC_WaitForLastTask();//设置时间MyRTC_SetTime();//写入BKPBKP_WriteBackupRegister(BKP_DR1, 0xA5A5);}else{//不初始化时调用等待代码防止意外RTC_WaitForSynchro();RTC_WaitForLastTask();}
}//设置时间
void MyRTC_SetTime(void)
{time_t time_cnt;struct tm time_date;//将数组时间信息转移到结构体//time.h中年份从1900开始计算,月份为0-11time_date.tm_year = MyRTC_Time[0] - 1900;time_date.tm_mon = MyRTC_Time[1] - 1;time_date.tm_mday = MyRTC_Time[2];time_date.tm_hour = MyRTC_Time[3];time_date.tm_min = MyRTC_Time[4];time_date.tm_sec = MyRTC_Time[5];//转换为秒计数值time_cnt = mktime(&time_date);//设置时间RTC_SetCounter(time_cnt);RTC_WaitForLastTask();
}//读取时间,流程与设置时间相反
void MyRTC_ReadTime(void)
{time_t time_cnt;struct tm time_date;time_cnt = RTC_GetCounter();time_date = *localtime(&time_cnt);MyRTC_Time[0] = time_date.tm_year + 1900;MyRTC_Time[1] = time_date.tm_mon + 1;MyRTC_Time[2] = time_date.tm_mday;MyRTC_Time[3] = time_date.tm_hour;MyRTC_Time[4] = time_date.tm_min;MyRTC_Time[5] = time_date.tm_sec;
}

如果严格按照Unix时间戳的规则,需要在伦敦时间的基础上添加偏移来得到不同时区的时间。直接对struct tm结构体的tm_hour成员操作可能导致进位错误,可以通过time_cnt转换到time_date时加上8*60*60(北京时间UTC+8)实现偏移(逆向转换则减去相应的值)。

主程序

#include "stm32f10x.h" 
#include "Delay.h"
#include "OLED.h"
#include "MyRTC.h"int main(void)
{OLED_Init();MyRTC_Init();OLED_ShowString(1, 1, "Date:XXXX-XX-XX");OLED_ShowString(2, 1, "Time:XX:XX:XX");OLED_ShowString(3, 1, "CNT :");OLED_ShowString(3, 1, "DIV :");while(1){MyRTC_ReadTime();OLED_ShowNum(1, 6, MyRTC_Time[0], 4);OLED_ShowNum(1, 11, MyRTC_Time[1], 2);OLED_ShowNum(1, 14, MyRTC_Time[2], 2);OLED_ShowNum(2, 6, MyRTC_Time[3], 2);OLED_ShowNum(2, 9, MyRTC_Time[4], 2);OLED_ShowNum(2, 12, MyRTC_Time[5], 2);OLED_ShowNum(3, 6, RTC_GetCounter(), 10);//通过对余数寄存器线性变换得到毫秒OLED_ShowNum(4, 6, (32767 - RTC_GetDivider()) / 32767.0 * 999, 10);}
}

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

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

相关文章

SecureCRT 使用指南:安装、设置与高效操作

目录 一、SecureCRT 简介 1.1 什么是 SecureCRT&#xff1f; 1.2 核心功能亮点 1.3 软件特点 二、SecureCRT 安装与激活 2.1 安装步骤&#xff08;Windows 系统&#xff09; 2.2 激活与破解&#xff08;仅供学习参考&#xff09; 三、基础配置与优化 3.1 界面与编码设…

3.5/Q1,GBD数据库最新一区文章解读

文章题目&#xff1a;Global burden of low vision and blindness due to age-related macular degeneration from 1990 to 2021 and projections for 2050 DOI&#xff1a;10.1186/s12889-024-21047-x 中文标题&#xff1a;1990年至2021年因年龄相关性黄斑变性导致的低视力和失…

【Hive入门】Hive安全管理与权限控制:基于SQL标准的授权GRANT REVOKE深度解析

目录 引言 1 Hive权限模型概述 2 SQL标准授权基础 2.1 核心概念解析 2.2 授权模型工作流程 3 GRANT/REVOKE语法详解 3.1 基础授权语法 3.2 权限回收语法 3.3 参数说明 4 授权场景 4.1 基础授权示例 4.2 列级权限控制 4.3 视图权限管理 5 权限查询与验证 5.1 查看…

无缝监控:利用 AWS X-Ray 增强 S3 跨账户复制的可见性

您准备好提升您的云和 DevOps 技能了吗? 🐥《云原生devops》专门为您打造,我们精心打造的 30 篇文章库,这些文章涵盖了 Azure、AWS 和 DevOps 方法论的众多重要主题。无论您是希望精进专业知识的资深专业人士,还是渴望学习相关知识的新手,这套资源库都能满足您的需求。 …

Python Cookbook-7.2 使用 pickle 和 cPickle 模块序列化数据

任务 你想以某种可以接受的速度序列化和重建Python 数据结构&#xff0c;这些数据既包括基本Python 对象也包括类和实例。 解决方案 如果你不想假设你的数据完全由基本 Python 对象组成&#xff0c;或者需要在不同的 Python 版本之间移植&#xff0c;再或者需要将序列化后的…

2025.5.5总结

今日感悟&#xff1a;这假期就这样结束了&#xff0c;玩了一次滑板&#xff0c;打扫了一次租房&#xff0c;出去逛了一次街&#xff0c;看完了一本书&#xff0c;追了一部剧。既没有家人&#xff0c;也没有能一同畅饮的同学&#xff0c;更没有对象&#xff0c;显得确实有些孤独…

MySQL | DQL语句-连接查询

MySQL | DQL语句-连接查询 &#x1fa84;个人博客&#xff1a;https://vite.xingji.fun 什么是连接查询 从一张表中查询数据称为单表查询。从两张或更多张表中联合查询数据称为多表查询&#xff0c;又叫做连接查询。什么时候需要使用连接查询&#xff1f; 比如这样的需求&…

Vite简单介绍

Vite 是一个现代化的前端构建工具&#xff0c;由 Vue.js 的创始人 Evan You 开发&#xff0c;旨在提供更快的开发体验和更高效的构建流程。它的名字来源于法语单词“vite”&#xff0c;意为“快速”&#xff0c;这也反映了它的核心优势——极速的冷启动和热模块替换&#xff08…

C语言-回调函数

回调函数 通过函数指针调用函数&#xff0c;而这个被调用的函数称为回调函数 回调函数是C语言中一种强大的机制&#xff0c;允许将函数作为参数传递给其他函数&#xff0c;从而在特定时机由后者调用。它的核心在于函数指针的使用 以下是回调函数的使用例子 先创建好一个函数…

启发式算法-禁忌搜索算法

禁忌搜索是一种可以用于解决组合优化问题的启发式算法&#xff0c;通过引入记忆机制跳出局部最优&#xff0c;避免重复搜索。该算法从一个初始解开始&#xff0c;通过邻域搜索策略来寻找当前解的邻域解&#xff0c;并在邻域解中选择一个最优解作为下一次迭代的当前解&#xff0…

Python 整理3种查看神经网络结构的方法

1. 网络结构代码 import torch import torch.nn as nn# 定义Actor-Critic模型 class ActorCritic(nn.Module):def __init__(self, state_dim, action_dim):super(ActorCritic, self).__init__()self.actor nn.Sequential(# 全连接层&#xff0c;输入维度为 state_dim&#xf…

Linux 查询CPU飙高的原因

获取进程ID ps -efgrep xxxx查询占用最高的线程ID top -Hp 线程ID线程ID 转 16进制数 printf 0x%x\n 线程ID基于jstack工具 跟踪堆栈定位代码位置 jstack 进程ID | grep 16禁止线程ID -A 20

Oracle OCP认证考试考点详解083系列09

题记&#xff1a; 本系列主要讲解Oracle OCP认证考试考点&#xff08;题目&#xff09;&#xff0c;适用于19C/21C,跟着学OCP考试必过。 41. 第41题&#xff1a; 题目 解析及答案&#xff1a; 关于应用程序容器&#xff0c;以下哪三项是正确的&#xff1f; A) 它可以包含单个…

GESP2024年3月认证C++八级( 第二部分判断题(1-5))

孙子定理参考程序&#xff1a; #include <iostream> #include <vector> using namespace std;// 扩展欧几里得算法&#xff1a;用于求逆元 int extendedGCD(int a, int b, int &x, int &y) {if (b 0) {x 1; y 0;return a;}int x1, y1;int gcd extende…

C 语言比较运算符:程序如何做出“判断”?

各类资料学习下载合集 ​​https://pan.quark.cn/s/8c91ccb5a474​​ 在编写程序时,我们经常需要根据不同的条件来执行不同的代码。比如,如果一个分数大于 60 分,就判断为及格;如果用户的年龄小于 18 岁,就禁止访问某个内容等等。这些“判断”的核心,就依赖于程序能够比…

WITH在MYSQL中的用法

WITH 子句&#xff08;也称为公共表表达式&#xff0c;Common Table Expression&#xff0c;简称 CTE&#xff09;是 SQL 中一种强大的查询构建工具&#xff0c;它可以显著提高复杂查询的可读性和可维护性。 一、基本语法结构 WITH cte_name AS (SELECT ... -- 定义CTE的查询…

多序列比对软件MAFFT介绍

MAFFT(Multiple Alignment using Fast Fourier Transform)是一款广泛使用且高效的多序列比对软件,由日本京都大学的Katoh Kazutaka等人开发,最早发布于2002年,并持续迭代优化至今。 它支持从几十条到上万条核酸或蛋白质序列的快速比对,同时在准确率和计算效率之间提供灵…

APP 设计中的色彩心理学:如何用色彩提升用户体验

在数字化时代&#xff0c;APP 已成为人们日常生活中不可或缺的一部分。用户在打开一个 APP 的瞬间&#xff0c;首先映入眼帘的便是其色彩搭配&#xff0c;而这些色彩并非只是视觉上的装饰&#xff0c;它们蕴含着强大的心理暗示力量&#xff0c;能够潜移默化地影响用户的情绪、行…

Compose 中使用 WebView

在 Jetpack Compose 中&#xff0c;我们可以使用 AndroidView 组件来集成传统的 Android WebView。以下是几种实现方式&#xff1a; 基础 WebView 实现 Composable fun WebViewScreen(url: String) {AndroidView(factory { context ->WebView(context).apply {// 设置布局…

2025年01月03日美蜥(杭州普瑞兼职)二面

目录 为何 nginx 可以实现跨域请求&#xff0c;原理是什么为何 nodejs 可以实现跨域请求&#xff0c;原理是什么浏览器的请求头有哪些浏览器的响应头有哪些浏览器输入网址后发生什么http 协议和 https 有什么区别你的核心优势是什么浏览器缓存机制https 的加密机制tcp 的三次握…