当前位置: 首页 > news >正文

STM32 F103C8T6学习笔记11:RTC实时时钟—OLED手表日历

之前在 学习笔记10文章 做了一个简易的,使用定时器计时的简单时钟,现在使用RTC实时时钟同步代替定时器来实现一下OLED手表日历,接着上个实验文章进行完善~~

文章提供源码、测试工程下载、测试效果图。

目录

 RTC实时时钟:

简介:

主要特性:

 RTC框图:

UNIX时间戳:

程序设计:

配置RTC初始化过程分为以下几步:

 RTC日历初始化相关代码:

主函数代码:

测试效果:

测试工程下载:


 RTC实时时钟:

简介:

 STM32F10x-中文参考手册 有关于RTC实时时钟的介绍是从 P308页开始的:

 RTC时钟与DS1302时钟芯片不同,DS1302时钟芯片是通过读取寄存器实现读取年月日等信息的

而RTC时钟是作为STM32F103单片机中的一个时钟定时器模块(其余系列不一定),主电源掉电后会继续使用   后备电池(由 Vbat 引脚接 电源 继续供电 )继续运行的模块,它本质是一个32位的向上计数器。

因此我们在STM32F103单片机中 读取RTC时 本质是得到一个计数值,对其进行处理。

主要特性:

 我们一般在LSE接一个 32.768k ( 2^15=32768 )的晶振作为RTC的时钟源,便于分频产生1HZ的时钟基准,

 RTC框图:

 

 我们从RTC的框图可以了解到,它的秒、闹钟都是有中断的,但溢出事件(计数到达最大值)时没有中断。

UNIX时间戳:

在设计到日历时,我们就需要注意这个时间戳:

 

程序设计:

首先注意一下这些头文件,都是需要用到的,别忘记了添加

#include "stm32f10x_rtc.h" //RTC相关库
#include "stm32f10x_pwr.h"  
#include "stm32f10x_bkp.h"

配置RTC初始化过程分为以下几步:

1.配置中断,配置中断优先级

2.检查寄存器BKP_DR1,根据其值确定是否为第一次上电,V BAT是否有后备电池,第一次上电就要初始化时间。(V BAT没电池 以及 V BAT有电池 但寄存器没被写入值都算第一次上电)(后备寄存器区由V BAT引脚供电,因此当V BAT引脚有电时主电源断不会使得后备寄存器区的寄存器BKP_DR1的值丢失 )

3.定义时间结构体,用来存放改变时间等.

4.复制编写RTC_Configuration()函数,配置相关时钟源,外部时钟还是内部,分频等。

5.编写Time_Adjust()函数,给RTC时钟附上初始值(通过将 小时、分钟和秒都转换成秒 加起来 来实现设置当前计数值)(小时是 24小时制)

此处需要注意一个小细节:

就是我的程序设计使用上没用到串口,因此没有初始化串口,但在移植官方代码时,他们使用串口打印测试,各阶段初始化情况,起初我保留了这些printf()语句,认为会跳过,但实际上程序会因为没有初始化串口而在printf那卡住~·

 RTC日历初始化相关代码:

#include "RTC.h"void RTC_init(void)
{NVIC_InitTypeDef NVIC_Initstructure;/*1. NVIC 中断配置 *//*Configure one bit for preemption priority 中断分组*/NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);/*Enable the RTC Interrupt */NVIC_Initstructure.NVIC_IRQChannel = RTC_IRQn;NVIC_Initstructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_Initstructure.NVIC_IRQChannelSubPriority = 0;NVIC_Initstructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init (&NVIC_Initstructure);	/*检查V BAT引脚是否为第一次上电(是否有后备电源)没有就要初始化时间*//*在启动时检查备份寄存器BKP_DR1,如果内容不是0xA5A5,则需重新配置时间并询问用户调整时间*/if (BKP_ReadBackupRegister( BKP_DR1) != 0xA5A5){//配置RTC与设置初值:RTC_Configuration();Time_Adjust(&time1);/*向BKP_DR1寄存器写入标志,说明RTC已在运行,只要后备有电,这个值就不会掉*/BKP_WriteBackupRegister( BKP_DR1, 0xA5A5);}else{/* 使能 PWR 和 Backup 时钟 */RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);/* 允许访问 Backup 区域 */PWR_BackupAccessCmd(ENABLE);		/*LSE启动无需设置新时钟*/		
#ifdef RTC_CLOCK_SOURCE_LSI		/* 使能 LSI */RCC_LSICmd(ENABLE);/* 等待 LSI 准备好 */while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET){}
#endif/*检查是否是系统掉电重启*/if (RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET){ ;}/*检查是否Reset复位引脚引起的 复位*/else if (RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET){;}	/*等待寄存器同步*/RTC_WaitForSynchro();	/*允许RTC秒中断*/RTC_ITConfig(RTC_IT_SEC, ENABLE);	/*等待上次RTC寄存器写操作完成*/RTC_WaitForLastTask();}/*定义了时钟输出宏,则配置校正时钟输出到PC13*/#ifdef RTCClockOutput_Enable/* 使能 PWR 和 Backup 时钟 */RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);/* 允许访问 Backup 区域 */PWR_BackupAccessCmd(ENABLE);/* 禁止 Tamper 引脚 *//* 要输出 RTCCLK/64 到 Tamper 引脚,  tamper 功能必须禁止 */	BKP_TamperPinCmd(DISABLE); /* 使能 RTC 时钟输出到 Tamper 引脚 */BKP_RTCOutputConfig(BKP_RTCOutputSource_CalibClock);#endif/* 清除复位标志 flags */RCC_ClearFlag();
}/** 函数名:RTC_Configuration* 描述  :配置RTC* 输入  :无* 输出  :无* 调用  :外部调用*/
void RTC_Configuration(void)
{/* 使能 PWR 和 Backup 时钟 */RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);/* 允许访问 Backup 区域 */PWR_BackupAccessCmd(ENABLE);	/* 复位 Backup 区域 */BKP_DeInit();	
//使用外部时钟还是内部时钟(在bsp_rtc.h文件定义)	
//使用外部时钟时,在有些情况下晶振不起振
//批量产品的时候,很容易出现外部晶振不起振的情况,不太可靠	
#ifdef 	RTC_CLOCK_SOURCE_LSE/* 使能 LSE */RCC_LSEConfig(RCC_LSE_ON);	/* 等待 LSE 准备好 */while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET){}/* 选择 LSE 作为 RTC 时钟源 */RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);	/* 使能 RTC 时钟 */RCC_RTCCLKCmd(ENABLE);/* 等待 RTC 寄存器 同步* 因为RTC时钟是低速的,内环时钟是高速的,所以要同步*/RTC_WaitForSynchro();	/* 确保上一次 RTC 的操作完成 */RTC_WaitForLastTask();	/* 使能 RTC 秒中断 */RTC_ITConfig(RTC_IT_SEC, ENABLE);/* 确保上一次 RTC 的操作完成 */RTC_WaitForLastTask();	/* 设置 RTC 分频: 使 RTC 周期为1s  *//* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) = 1HZ */RTC_SetPrescaler(32767); 	/* 确保上一次 RTC 的操作完成 */RTC_WaitForLastTask();	
#else/* 使能 LSI */RCC_LSICmd(ENABLE);/* 等待 LSI 准备好 */while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET){}	/* 选择 LSI 作为 RTC 时钟源 */RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);	/* 使能 RTC 时钟 */RCC_RTCCLKCmd(ENABLE);	/* 等待 RTC 寄存器 同步* 因为RTC时钟是低速的,内环时钟是高速的,所以要同步*/RTC_WaitForSynchro();	/* 确保上一次 RTC 的操作完成 */RTC_WaitForLastTask();	/* 使能 RTC 秒中断 */RTC_ITConfig(RTC_IT_SEC, ENABLE);	/* 确保上一次 RTC 的操作完成 */RTC_WaitForLastTask();/* 设置 RTC 分频: 使 RTC 周期为1s ,LSI约为40KHz *//* RTC period = RTCCLK/RTC_PR = (40 KHz)/(40000-1+1) = 1HZ */	RTC_SetPrescaler(40000-1); /* 确保上一次 RTC 的操作完成 */RTC_WaitForLastTask();
#endif}
#ifndef _RTC_h_ 
#define _RTC_h_  #include "headfire.h"//使用LSE外部时钟 或 LSI内部时钟
//#define RTC_CLOCK_SOURCE_LSE      
#define RTC_CLOCK_SOURCE_LSI
//北京时间的时区秒数差
#define TIME_ZOOM						(8*60*60)//初始化时间结构体
extern struct rtc_time time1;void RTC_init(void);           //初始化 与 配置RTC
void RTC_Configuration(void);  //配置RTC#endif
#include "RTC_day.h"/*时间结构体,初始化默认时间 2023-08-21 17:55:55*/
struct rtc_time time1= {55,55,17,21,8,2023,1} ;//初始化时间结构体uint16_t BMP_cnt,BMP_FLAG;#define FEBRUARY		2
#define	STARTOFTIME		1970
#define SECDAY			86400L           /*  一天有多少s */
#define SECYR			(SECDAY * 365)
#define	leapyear(year)		((year) % 4 == 0)
#define	days_in_year(a) 	(leapyear(a) ? 366 : 365)
#define	days_in_month(a) 	(month_days[(a) - 1])static int month_days[12] = {	31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };/** This only works for the Gregorian calendar - i.e. after 1752 (in the UK)*//*计算公历*/
void GregorianDay(struct rtc_time * tm)
{int leapsToDate;int lastYear;int day;int MonthOffset[] = { 0,31,59,90,120,151,181,212,243,273,304,334 };lastYear=tm->tm_year-1;/*计算从公元元年到计数的前一年之中一共经历了多少个闰年*/leapsToDate = lastYear/4 - lastYear/100 + lastYear/400;      /*如若计数的这一年为闰年,且计数的月份在2月之后,则日数加1,否则不加1*/if((tm->tm_year%4==0) &&((tm->tm_year%100!=0) || (tm->tm_year%400==0)) &&(tm->tm_mon>2)) {/** We are past Feb. 29 in a leap year*/day=1;} else {day=0;}day += lastYear*365 + leapsToDate + MonthOffset[tm->tm_mon-1] + tm->tm_mday; /*计算从公元元年元旦到计数日期一共有多少天*/tm->tm_wday=day%7;
}/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.* Assumes input in normal date format, i.e. 1980-12-31 23:59:59* => year=1980, mon=12, day=31, hour=23, min=59, sec=59.** [For the Julian calendar (which was used in Russia before 1917,* Britain & colonies before 1752, anywhere else before 1582,* and is still in use by some communities) leave out the* -year/100+year/400 terms, and add 10.]** This algorithm was first published by Gauss (I think).** WARNING: this function will overflow on 2106-02-07 06:28:16 on* machines were long is 32-bit! (However, as time_t is signed, we* will already get problems at other places on 2038-01-19 03:14:08)**/
u32 mktimev(struct rtc_time *tm)
{if (0 >= (int) (tm->tm_mon -= 2)) {	/* 1..12 -> 11,12,1..10 */tm->tm_mon += 12;		/* Puts Feb last since it has leap day */tm->tm_year -= 1;}return ((((u32) (tm->tm_year/4 - tm->tm_year/100 + tm->tm_year/400 + 367*tm->tm_mon/12 + tm->tm_mday) +tm->tm_year*365 - 719499)*24 + tm->tm_hour /* now have hours */)*60 + tm->tm_min /* now have minutes */)*60 + tm->tm_sec; /* finally seconds */	 
}void to_tm(u32 tim, struct rtc_time * tm)
{register u32    i;register long   hms, day;day = tim / SECDAY;			/* 有多少天 */hms = tim % SECDAY;			/* 今天的时间,单位s *//* Hours, minutes, seconds are easy */tm->tm_hour = hms / 3600;tm->tm_min = (hms % 3600) / 60;tm->tm_sec = (hms % 3600) % 60;/* Number of years in days */ /*算出当前年份,起始的计数年份为1970年*/for (i = STARTOFTIME; day >= days_in_year(i); i++) {day -= days_in_year(i);}tm->tm_year = i;/* Number of months in days left */ /*计算当前的月份*/if (leapyear(tm->tm_year)) {days_in_month(FEBRUARY) = 29;}for (i = 1; day >= days_in_month(i); i++) {day -= days_in_month(i);}days_in_month(FEBRUARY) = 28;tm->tm_mon = i;/* Days are what is left over (+1) from all that. *//*计算当前日期*/tm->tm_mday = day + 1;/** Determine the day of week*/GregorianDay(tm);}/** 函数名:Time_Adjust* 描述  :时间调节* 输入  :用于读取RTC时间的结构体指针(北京时间)* 输出  :无* 调用  :外部调用*/
void Time_Adjust(struct rtc_time* tm)
{/* 等待确保上一次操作完成 */RTC_WaitForLastTask();//更新日期GregorianDay(tm);//	  /* 设置当前时间  通过将 小时、分钟和秒都转换成秒 加起来 来实现设置当前计数值 (小时是 24小时制) */
//	  RTC_SetCounter(tm->tm_hour*3600+tm->tm_min*60+tm->tm_sec);  //Tmp HH*3600 Tmp MM*60 Tmp SS/* 由日期计算时间戳并写入到RTC计数寄存器 */RTC_SetCounter(mktimev(tm)-TIME_ZOOM);	/* 等待确保上一次操作完成 */RTC_WaitForLastTask();
}void Time_Display(uint32_t TimeVar,struct rtc_time *tm)
{char  buf[20];   //用于暂存oled数据uint32_t BJ_TimeVar;/*  把标准时间转换为北京时间*/BJ_TimeVar =TimeVar + TIME_ZOOM;to_tm(BJ_TimeVar,tm);/*把定时器的值转换为北京时间*///打印年sprintf(buf,"%d",tm->tm_year);OLED_ShowString(75,0,(u8 *)buf,16);OLED_ShowCHinese(75+16*2,0,0);  //打印中文“年”//打印时间:sprintf(buf,"%02d:%02d:%02d",tm->tm_hour,tm->tm_min,tm->tm_sec);		OLED_ShowString(64,2,(u8 *)buf,16);		          //打印日期:sprintf(buf,"%02d",tm->tm_mon);	   OLED_ShowString(75,4,(u8 *)buf,12);	//打印月	OLED_ShowCHinese_small(75+14,4,0);  //打印中文月	    sprintf(buf,"%02d",tm->tm_mday);		 OLED_ShowString(75+14+12,4,(u8 *)buf,12);	//打印日OLED_ShowCHinese_small(75+14+12+14,4,1);  //打印中文日//打印星期:OLED_ShowCHinese(70,5,1);     //打印中文“星”		OLED_ShowCHinese(70+16,5,2);  //打印中文“期”				sprintf(buf,"%d",tm->tm_wday);		   OLED_ShowString(70+16+16,5,(u8 *)buf,16);
}
#ifndef _RTC_day_h_
#define _RTC_day_h_#include "headfire.h"typedef unsigned int  u32;//定义时间结构体
struct rtc_time {int tm_sec;int tm_min;int tm_hour;int tm_mday;int tm_mon;int tm_year;int tm_wday;
};//初始化时间结构体
extern struct rtc_time time1;extern uint16_t BMP_cnt,BMP_FLAG;void GregorianDay(struct rtc_time * tm);
uint32_t mktimev(struct rtc_time *tm);
void to_tm(uint32_t tim, struct rtc_time * tm);
void Time_Display(uint32_t TimeVar,struct rtc_time *tm);
void Time_Adjust(struct rtc_time* tm);#endif

 

主函数代码:

#include "main.h"//时间结构体  在RTC_day.h中初始化了
//时间结构体定义在 RTC_day.h//刷新时间标志uint16_t TimeDisplay_cnt,TimeDisplay;int main(void)
{	init_ALL();     //初始化所有函数while(1){	if(TimeDisplay==1){Time_Display(RTC_GetCounter(),&time1);TimeDisplay=0;}switch(BMP_FLAG){case 1:OLED_DrawBMP(0,0,64,8,BMP1);  break;case 2:OLED_DrawBMP(0,0,64,8,BMP2);  break;case 3:OLED_DrawBMP(0,0,64,8,BMP3);  break;case 4:OLED_DrawBMP(0,0,64,8,BMP4);  break;case 5:OLED_DrawBMP(0,0,64,8,BMP5);  break;case 6:OLED_DrawBMP(0,0,64,8,BMP6);  break;case 7:OLED_DrawBMP(0,0,64,8,BMP7);  break;case 8:OLED_DrawBMP(0,0,64,8,BMP8);  break;case 9:OLED_DrawBMP(0,0,64,8,BMP9);  break;case 10:OLED_DrawBMP(0,0,64,8,BMP10);  break;case 11:OLED_DrawBMP(0,0,64,8,BMP11);  break;case 12:OLED_DrawBMP(0,0,64,8,BMP12);  break;case 13:OLED_DrawBMP(0,0,64,8,BMP13);  break;case 14:OLED_DrawBMP(0,0,64,8,BMP14);  break;case 15:OLED_DrawBMP(0,0,64,8,BMP15);  break;case 16:OLED_DrawBMP(0,0,64,8,BMP16);  break;case 17:OLED_DrawBMP(0,0,64,8,BMP17);  break;case 18:OLED_DrawBMP(0,0,64,8,BMP18);  break;case 19:OLED_DrawBMP(0,0,64,8,BMP19);  break;case 20:OLED_DrawBMP(0,0,64,8,BMP20);  break;		case 21:OLED_DrawBMP(0,0,64,8,BMP21);  break;case 22:OLED_DrawBMP(0,0,64,8,BMP22);  break;case 23:OLED_DrawBMP(0,0,64,8,BMP23);  break;case 24:OLED_DrawBMP(0,0,64,8,BMP24);  break;case 25:OLED_DrawBMP(0,0,64,8,BMP25);  break;case 26:OLED_DrawBMP(0,0,64,8,BMP26);  break;case 27:OLED_DrawBMP(0,0,64,8,BMP27);  break;case 28:OLED_DrawBMP(0,0,64,8,BMP28);  break;}}
}//初始化所有函数:
void init_ALL(void)
{SysTick_Init(72);         //初始化滴答计时器Timer2_Init();						//初始化定时器2i2c_GPIO_Config();	      //IIC初始化OLED_Init();              //初始化OLED屏幕OLED_Clear();             //清空屏幕数据RTC_init();}//定时器2中断服务函数
void TIM2_IRQHandler(void)
{if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET){		if(++TimeDisplay_cnt==100)  //定时器刷新时间{TimeDisplay_cnt=0;TimeDisplay=1;}if(++BMP_cnt==10)		        //定时器   刷新太空人图片{BMP_cnt=0;BMP_FLAG++;if(BMP_FLAG==29){BMP_FLAG=1;}}TIM_ClearITPendingBit(TIM2, TIM_IT_Update);//清出中断寄存器标志位,用于退出中断}
}//RTC每秒进的中断服务函数
void RTC_IRQHandler(void)
{if (RTC_GetITStatus(RTC_IT_SEC) != RESET){/* Clear the RTC Second interrupt */RTC_ClearITPendingBit(RTC_IT_SEC);//	    /* Enable time update */
//	    TimeDisplay = 1;
//	/* Wait until last write operation on RTC registers has finished */RTC_WaitForLastTask();}
}

测试效果:

 

测试工程下载:

https://download.csdn.net/download/qq_64257614/88237879?spm=1001.2014.3001.5503

相关文章:

STM32 F103C8T6学习笔记11:RTC实时时钟—OLED手表日历

之前在 学习笔记10文章 做了一个简易的,使用定时器计时的简单时钟,现在使用RTC实时时钟同步代替定时器来实现一下OLED手表日历,接着上个实验文章进行完善~~ 文章提供源码、测试工程下载、测试效果图。 目录 RTC实时时钟: 简介&…...

无法将“环境变量”项识别为 cmdlet、函数、脚本文件或可运行程序的名称(pycharm)

无法将“配置的任何一个环境变量”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。 记录解决“无法将“C:......conda.exe”项识别为 cmdlet、函数、脚本文件或可运行程序的名称”以及“表达式或语句中包含意外的标记”的系列问题(VSCode开发环境)一、Conda.exe无法正常识…...

基于图像链接的批量下载

1. 获取图像路径 1.1 给定图像链接,这是一张图像 image_url “https://univs-news-1256833609.cos.ap-beijing.myqcloud.com/123/upload/resources/image/7467914.jpg”1.1通过网站规则得到其想要的图像链接 image_urls [ f"https://univs-news-125683360…...

mongodb使用心得

入门 术语 collection:相当于db的表 document:相当于表的记录 启动 单机模式启动mongo server mongod --dbpath D:\programs\mongodb-4.2.8\data\dbreplica set模式启动 replica set模式其实就是主从模式。 做mongo的启动配置文件: …...

学习Vue:响应式原理与性能优化策略

性能优化是Vue.js应用开发中的一个关键方面,而深入了解响应式原理并采用有效的性能优化策略可以显著提升应用的性能。本文将解释响应式原理并介绍一些性能优化策略,旨在帮助您构建高性能的Vue.js应用。 响应式原理 Vue.js的响应式原理是通过利用Object.…...

神经网络基础-神经网络补充概念-43-梯度下降法

概念 梯度下降法(Gradient Descent)是一种优化算法,用于在机器学习和深度学习中最小化(或最大化)目标函数。它通过迭代地调整模型参数,沿着梯度方向更新参数,以逐步接近目标函数的最优解。梯度…...

Reids之Set类型解读

目录 基本介绍 命令概述 SADD key member1 [member2] SCARD key SINTER key1 [key2] SMEMBERS key SPOP key SUNION key1 [key2] 基本介绍 新的存储需求:存储大量的数据 在查询方面提供更高的效率需要的存储结构:能够保存大量的数据&#x…...

【网络基础】数据链路层

【网络基础】数据链路层 文章目录 【网络基础】数据链路层1、对比网络层2、以太网2.1 基本概念2.2 类似技术2.3 以太网帧 3、MAC地址对比IP地址 4、MTU4.1 对IP协议影响4.2 对UDP协议影响4.3 对TCP协议影响4.4 地址、MTU查看 5、ARP协议5.1 协议作用5.2 协议工作流程5.3 数据报…...

云计算|OpenStack|使用VMware安装华为云的R006版CNA和VRM---初步使用(二)

前言: 在前面一篇文章云计算|OpenStack|使用VMware安装华为云的R006版CNA和VRM---初始安装(一)_华为cna_晚风_END的博客-CSDN博客 介绍了基于VMware虚拟机里嵌套部署华为云的云计算,不过仅仅是做到了在VRM的web界面添加计算节点…...

Python typing函式庫和torch.types

Python typing函式庫和torch.types 前言typingSequence vs IterableCallableUnionOptionalFunctionsCallableIterator/generator位置參數 & 關鍵字參數 Classesself自定義類別ClassVar\_\_setattr\_\_ 與 \__getattr\_\_ torch.typesbuiltins 參數前的* …...

UE5 编程规范

官方文档 使用现代C编程标准, 使用前沿C标准库版本. 1. 类中按照先 Public 后 Private 去写 2. 继承自 UObject 的类都以 U 前缀 3. 继承自 AActor 的类都以 A 前缀 4. 继承自 SWidget 的类都以 S 前缀 5. 模板以 T 前缀 6. 接口以 I 前缀 7. 枚举以 E 前缀 8. 布尔值…...

交互消息式IMessage扩展开发记录

IMessage扩展简介 iOS10新加入的基于iMessage的应用扩展,可以丰富发送消息的内容。(分享表情、图片、文字、视频、动态消息;一起完成任务或游戏。) 简单的将发送的数据内型分为三种: 1.贴纸Stickers; 2.交…...

软件团队降本增效-建立需求评估体系

需求对于软件开发来说是非常重要的输入,它们直接决定了软件的产品形态、代码数量和质量。如果需求不清晰、不完善,或者存在逻辑冲突,将会导致软件质量迅速下降,增加代码耦合性和开发成本。 在开发过程中,对需求的产品…...

npm yarn pnpm 命令集

npm 安装依赖 npm install 安装某个依赖 npm install xxx7.6.3 安装到全局(dependencies) npm install xxx7.6.3 -S 安装到线下(devDependencies) npm install xxx7.6.3 -D 卸载某个依赖 npm uninstall xxx 卸载全局依…...

python 开发环境(PyCharm)搭建指南

Python 的下载并安装 参考:Python基础教程——搭建Python编程环境 下载 Python Python 下载地址:官网 (1)点击【Downloads】>>>点击【Windows】>>>点击【Python 3.x.x】下载最新版 Python; Pyt…...

springboot里 运用 easyexcel 导出

引入pom <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.2.6</version> </dependency>运用 import com.alibaba.excel.EasyExcel; import org.springframework.stereotype.Contr…...

一“码”当先,PR大征集!2023 和RT-Thread一起赋能开源!

活动地址&#xff1a;https://club.rt-thread.org/ask/article/3c7cf7345ca47a18.html 活动介绍 「一“码”当先&#xff0c;PR大征集&#xff01;」是一项为了鼓励开发者积极参与开源软件开发维护的活动。 你可在Github RT-Thread&#xff08; https://github.com/RT-Thread …...

jmeter模拟多用户并发

一、100个真实的用户 1、一个账号模拟100虚拟用户同时登录和100账号同时登录 区别 &#xff08;1&#xff09;1个账号100个人用&#xff0c;同时登录&#xff1b; &#xff08;2&#xff09;100个人100个账号&#xff0c;同时登录。 相同 &#xff08;1&#xff09;两个都…...

澎峰科技|邀您关注2023 RISC-V中国峰会!

峰会概览 2023 RISC-V中国峰会&#xff08;RISC-V Summit China 2023&#xff09;将于8月23日至25日在北京香格里拉饭店举行。本届峰会将以“RISC-V生态共建”为主题&#xff0c;结合当下全球新形势&#xff0c;把握全球新时机&#xff0c;呈现RISC-V全球新观点、新趋势。 本…...

【系统架构】系统架构设计之数据同步策略

文章目录 一、介绍1.1、分布式系统中的数据同步定义1.2、为何数据同步如此关键1.3、数据同步策略简介 二、为什么需要数据同步2.1、提高系统可用性2.2、备份与灾难恢复2.3、提高性能2.4、考虑地理位置&#xff08;如使用CDN&#xff09; 三、同步备份3.1、定义和概述3.2、工作原…...

Linux内核学习笔记——ACPI命名空间

所有定义块都加载到单个命名空间中。命名空间 是由名称和路径标识的对象层次结构。 以下命名约定适用于 ACPI 中的对象名称 命名空间&#xff1a; 所有名称的长度均为 32 位。 名称的第一个字节必须是“A”-“Z”、“_”之一。 名称的每个剩余字节必须是“A”-“Z”、“0”之…...

使用 OpenCV Python 实现自动图像注释工具的详细步骤--附完整源码

注释是深度学习项目中最关键的部分。它是模型学习效果的决定因素。然而,这是非常乏味且耗时的。一种解决方案是使用自动图像注释工具,这大大缩短了时间。 本文是pyOpenAnnotate系列的一部分,其中包括以下内容。 1、使用 OpenCV 进行图像注释的路线图。 2、pyOpenAnnotate工…...

RunnerGo中WebSocket、Dubbo、TCP/IP三种协议接口测试详解

大家好&#xff0c;RunnerGo作为一款一站式测试平台不断为用户提供更好的使用体验&#xff0c;最近得知RunnerGo新增对&#xff0c;WebSocket、Dubbo、TCP/IP&#xff0c;三种协议API的测试支持&#xff0c;本篇文章跟大家分享一下使用方法。 WebSocket协议 WebSocket 是一种…...

【Java 动态数据统计图】动态数据统计思路案例(动态,排序,数组)一(112)

需求&#xff1a;&#xff1a; 有一个List<Map<String.Object>>,存储了某年某月的数据&#xff0c; 数据是根据用户查询条件进行显示的&#xff1b;所以查询的数据是动态的&#xff1b;需按月份统计每个年月数据出现的次数&#xff0c;并且按照月份排序&#xff1…...

kafka踩坑

问题&#xff1a;项目中用到kafka作为消息中间件&#xff0c;因为现在是开发阶段&#xff0c;试了一次没问题之后就没在管&#xff0c;今天又要测试kafka相关功能&#xff0c;发现消息发送者能够正常发送消息&#xff0c;但是消费者怎么也就收不到数据。然后经过各种百度进行了…...

让你专注于工作的电脑桌面日程提醒软件

在现代职场中&#xff0c;上班族们常常在繁忙的工作中会遇到各种各样的事情干扰。比如&#xff0c;当我们专注于完成重要的报告时&#xff0c;却又有同事来询问问题&#xff1b;在准备去会议事项时&#xff0c;手机却突然收到了一系列的短信和通知。这些干扰不仅浪费了我们的时…...

62页智慧产业园区数字化综合解决方案PPT

导读&#xff1a;原文《62页智慧产业园区数字化综合解决方案PPT》&#xff08;获取来源见文尾&#xff09;&#xff0c;本文精选其中精华及架构部分&#xff0c;逻辑清晰、内容完整&#xff0c;为快速形成售前方案提供参考。 喜欢文章&#xff0c;您可以关注评论转发本文&#…...

苹果开发者账号注册方法简明指南

注册苹果开发者账号的方法 在2020年以前&#xff0c;注册苹果开发者账号后&#xff0c;就可以生成证书。 但2020年后&#xff0c;因为注册苹果开发者账号需要使用Apple Developer app注册开发者账号&#xff0c;所以需要缴费才能创建ios证书了。 所以新政策出来后&#xff0c;…...

SQL-每日一题【1321. 餐馆营业额变化增长】

题目 表: Customer 你是餐馆的老板&#xff0c;现在你想分析一下可能的营业额变化增长&#xff08;每天至少有一位顾客&#xff09;。 计算以 7 天&#xff08;某日期 该日期前的 6 天&#xff09;为一个时间段的顾客消费平均值。average_amount 要 保留两位小数。 结果按 …...

PyCharm PyQt5 开发环境搭建

环境 python&#xff1a;3.6.x PyCharm&#xff1a;PyCharm 2019.3.5 (Community Edition) 安装PyQT5 pip install PyQt5 -i https://pypi.douban.com/simplepip install PyQt5-tools -i https://pypi.douban.com/simple配置PyCharm PyQtUIC Program &#xff1a;D:\Pytho…...

2023-08-17 Untiy进阶 C#知识补充8——C#中的日期与时间

文章目录 一、名词概念二、DateTime三、TimeSpan 一、名词概念 &#xff08;一&#xff09;格里高利历 ​ 格里高利历一般指公元&#xff0c;即公历纪年法。目前我们所说公历&#xff0c;就是格里高利历。 ​ 比如 2022 年就是从公元元年开始算起的两千二十二年。 &#xf…...

SPSS--如何使用分层分析以及分层分析案例分享

分层分析&#xff1a;将资料按某个或某些需要控制的变量的不同分类进行分层&#xff0c;然后再估计暴露因子与某结局变量之间关系的一种资料分析方法。 分层分析的最重要的用途是评估和控制混杂因子所致的混杂偏倚。通过按混杂因子分层&#xff0c;可使每层内的两个比较组在所控…...

时序数据库influxdb笔记

官方资料 https://docs.influxdata.com/influxdb/v2.7/install/?tLinux https://www.influxdata.com/influxdb/ 安装 1、linux平台下 1&#xff09;下载 2&#xff09;解压 3&#xff09;添加账户&#xff08; adduser influx&#xff09; 4&#xff09;设置目录权限 5…...

8月18日上课内容 Haproxy搭建Web群集

本章结构 课程大纲 Haproxy调度算法 常见的web集群调度器 目前常见的Web集群调度器分为软件和硬件软件 通常使用开源的LVS、Haproxy、Nginx 硬件一般使用比较多的是F5&#xff0c;也有很多人使用国内的一些产品&#xff0c;如梭子鱼、绿盟等 Haproxy应用分析 LVS在企业应用中…...

【高阶数据结构】红黑树详解

文章目录 前言1. 红黑树的概念及性质1.1 红黑树的概念1.2 红黑树的性质1.3 已经学了AVL树&#xff0c;为啥还要学红黑树 2. 红黑树结构的定义3. 插入&#xff08;仅仅是插入过程&#xff09;4. 插入结点之后根据情况进行相应调整4.1 cur为红&#xff0c;p为红&#xff0c;g为黑…...

树莓牌4B安装Centos8

准备工作 镜像&#xff1a;https://people.centos.org/pgreco/CentOS-Userland-8-stream-aarch64-RaspberryPI-Minimal-4/ 烧制工具&#xff1a;https://www.raspberrypi.com/software/ 初始化 将上述工具烧制好的SD卡插入树莓派&#xff0c;通电。通过网线将树莓派与电脑连…...

SQL Monitor Crack,PostgreSQL监控的传入复制图表

SQL Monitor Crack,PostgreSQL监控的传入复制图表  现在&#xff0c;您可以在从Estate页面导出的Microsoft Excel报告的摘要标题中看到UTC偏移量。 添加了PostgreSQL监控的传入复制图表。 Microsoft PowerShell API现在支持将使用New-SqlMonitorWindowsHost和New-SqlMonitorin…...

软件测试技术之单元测试—工程师 Style 的测试方法(3)

如何设计单元测试&#xff1f; 单元测试设计方法 单元测试用例&#xff0c;和普通测试用例的设计&#xff0c;没有太多不同&#xff0c;常见的就是等价类划分、边界值分析等。而测试用例的设计其实也是开发者应该掌握的基本技能。 等价类划分 把所有输入划分为若干分类&…...

Ubuntu中安装OpenSSL

文章目录 一、前期准备1.1 压缩包下载1.2 gcc, make等的安装二、安装配置 一、前期准备 1.1 压缩包下载 在安装openssl之前&#xff0c;我们需要下载对应的压缩包 https://www.openssl.org/source/openssl-3.0.1.tar.gz 此压缩包可以选择win上下载后解压再复制到本地虚拟机中…...

CW4-6A-S、CW4-10A-S、CW4-20A-S、CW4-30A-S螺栓式滤波器

CW3L2-3A-S、CW3L2-6A-S、CW3L2-10A-S、CW3L2-20A-S CW3-3A-S、CW3-6A-S、CW3-10A-S、CW3-20A-S、CW3-30A-S CW4EL2-3A-S、CW4EL2-6A-S、CW4EL2-10A-SCW4EL2-20A-S、CW4EL2-30A-S CW4E-3A-S、CW4E-6A-S、CW4E-10A-S、CW4E-20A-S、CW4E-30A-S CW4E-40A-S(001)、CW4E-50A-S(0…...

课程项目设计--项目设计--宿舍管理系统--vue+springboot完成项目--项目从零开始

写在前面&#xff1a; 本文是从项目设计到完成开始写的&#xff0c;本来这个项目基础功能是做完了的&#xff0c;但是之前时间紧张想从头做起了。之前一周写前端后端累死了. 设计是关键&#xff0c;这一篇主讲设计。可能后面会有修改&#xff0c;本人实力有限,学习的也是别人的…...

【Linux】Linux下常用搜索命令及其常用选项小结

0x00 前言 版本信息&#xff1a;Ubuntu 18.04.6 LTS 最后更新日期&#xff1a;2023.8.18 0x01 Linux下常用搜索命令及其常用选项小结 1.find &#xff08;1&#xff09;find path -name filename &#xff1a;在指定目录path查找名为filename 文件&#xff0c;文件名可用*匹…...

web APIs-练习五

5秒自动关闭的广告&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"…...

MySQL——基础——外连接

一、外连接查询语法&#xff1a;(实际开发中,左外连接的使用频率要高于右外连接) 左外连接 SELECT 字段列表 FROM 表1 LEFT [OUTER] JOIN 表2 ON 条件...; 相当于查询表1(左表)的所有数据 包含 表1和表2交集部分的数据 右外连接 SELECT 字段列表 FROM 表1 RIGHT [OUTER] JOIN …...

spring boot 实现Redisson分布式锁及其读写锁

分布式锁&#xff0c;就是控制分布式系统中不同进程共同访问同一共享资源的一种锁的实现。 1、引入依赖 <dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.15.5</versio…...

java-IONIO

一、JAVA IO 1.1. 阻塞 IO 模型 最传统的一种 IO 模型&#xff0c;即在读写数据过程中会发生阻塞现象。当用户线程发出 IO 请求之后&#xff0c;内 核会去查看数据是否就绪&#xff0c;如果没有就绪就会等待数据就绪&#xff0c;而用户线程就会处于阻塞状态&#xff0c;用户线…...

Python学习笔记_基础篇(十一)_socket编程

python 线程与进程简介 进程与线程的历史 我们都知道计算机是由硬件和软件组成的。硬件中的CPU是计算机的核心&#xff0c;它承担计算机的所有任务。 操作系统是运行在硬件之上的软件&#xff0c;是计算机的管理者&#xff0c;它负责资源的管理和分配、任务的调度。 程序是运行…...

C#8.0本质论第三章--更多数据类型

C#8.0本质论第三章–更多数据类型 3.1类型的划分 一个类型要么是值类型&#xff0c;要么是引用类型。区别在于拷贝方式&#xff1a;值类型数据总是拷贝值&#xff1b;引用类型的数据总是拷贝引用。 3.1.1值类型 3.1.2引用类型 引用类型的变量存储对数据存储位置的引用。 3.…...

浅拷贝与深拷贝

作者简介&#xff1a; zoro-1&#xff0c;目前大一&#xff0c;正在学习Java&#xff0c;数据结构等 作者主页&#xff1a; zoro-1的主页 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01;&#x1f496;&#x1f496; 浅拷贝与深拷贝 浅拷贝浅拷贝定义浅拷贝代码演示浅…...

背包 问题

1、背包问题 1.1、01背包 题目&#xff1a; 有n件物品和一个容量为m的背包&#xff0c;第i件物品的体积是v[ i ]&#xff0c;价值是w[ i ]&#xff0c;每件物品只有一件&#xff0c;求在不超过背包容量的前提下&#xff0c;可以放的物品的最大价值是多少 基本思路&#xff…...