51单片机(十)DS1302实时时钟

news2024/11/22 10:36:10

❤️ 专栏简介:本专栏记录了从零学习单片机的过程,其中包括51单片机和STM32单片机两部分;建议先学习51单片机,其是STM32等高级单片机的基础;这样再学习STM32时才能融会贯通。
☀️ 专栏适用人群 :适用于想要从零基础开始学习入门单片机,且有一定C语言基础的的童鞋。
🌙专栏目标:实现从零基础入门51单片机和STM32单片机,力求在玩好单片机的同时,能够了解一些计算机的基本概念,了解电路及其元器件的基本理论等。

⭐️ 专栏主要内容: 主要学习51单片机的功能、各个模块、单片机的外设、驱动等,最终玩好单片机和单片机的外设,全程手敲代码,实现我们所要实现的功能。
🌴 专栏说明 :如果文章知识点有错误的地方,欢迎大家随时在文章下面评论,我会第一时间改正。让我们一起学习,一起进步。
💑专栏主页:http://t.csdn.cn/HCD8v

本学习过程参考:https://space.bilibili.com/383400717

单片机安装软件、各种资料以及源码的路径:
https://pan.baidu.com/s/1vDTN2o8ffvczzNQGfyjHng
提取码:gdzf

本节主要介绍学习DS1302实时时钟的相关知识,包括DS1302实时时钟基础知识介绍、本节目标等;并利用两个小实验来写程序进行练习,分别是DS1302时钟以及DS1302可调时钟,最后附上相关代码。

文章目录

  • 一、DS1302实时时钟和本节目标
    • 1.1 DS1302基础知识
    • 1.2 本节目标
  • 二、DS1302时钟
  • 三、DS1302可调时钟

一、DS1302实时时钟和本节目标

1.1 DS1302基础知识

在这里插入图片描述

DS1302在开发版上的位置:

在这里插入图片描述

一定要学会通过看手册来学习和使用一款新的芯片,这里以DS1302为例,来学习一下看手册:

DS1302手册的路径:51单片机入门教程资料\开发板资料包\HC6800-ES V2.0\开发板芯片资料\DS1302中文手册.pdf

DS1302芯片是用来计时的,引脚定义和应用电路如下图所示

在这里插入图片描述

DIP是直插式,直接通过引脚插在MCU上的;SO是贴片式,贴在MCU上的;虽然方式不一样,但是内部芯片是一样的。
在这里插入图片描述

Vcc2是主电源,由MCU通电后对其进行供电;Vcc1是备用电源,MCU掉电时使用电池进行备用使用。

X1、X2接的是32.768KHz晶振;晶振给负责给实时时钟系统提供稳定的计数脉冲;

CE、I/O、SCLK三个引脚是通信引脚,MCU通过这三个引脚对时钟系统进行时间的读取和写入。

内部结构框图

在这里插入图片描述
在这里插入图片描述

CE为时钟使能开关,当CE为高电平时,对时钟的读写等操作才有效。

寄存器定义

在这里插入图片描述

上图中每个寄存器都有一个地址,各个寄存器的功能如下图所示:

在这里插入图片描述

而左边的READ和WRITE则表示读和写的命令字;例如,对于秒控制器,当命令字设置为0x81时,表示要对秒寄存器进行读操作;反之,当命令字设置为0x80,则表示对秒寄存器进行写操作。

那什么是命令字呢?

在这里插入图片描述

在这里插入图片描述

在时钟芯片上,我们如果想要对以上寄存器进行读写时操作,需要有三个条件,一是在哪里,二是什么操作,三是读/写什么;也就是说要确认,在哪个寄存器进行什么操作(读呢还是写呢?),读/写的内容是什么;

那么命令字就可以解决前两个条件,通过命令字就可以确认时在哪个寄存器进行什么操作,比如命令字设置为0x81,则表示对秒寄存器进行读操作;再比如命令字设置为0x84,则表示对时寄存器进行写操作。

至于第三个条件,读/写的内容怎么确认?命令字和写入的数据是怎么对应起来的呢?就要通过时序图:

在这里插入图片描述

时序图中是对CE(操作使能)、SCLK(时钟)、I/O(数据)三个引脚的操作,我们要学会看时序图,上面是单字符读的时序图,下面是单字符写的时序图;

以写的时序图为例,来解释一下,

可以看到,再下面写的时序图里,CE引脚,开始写时从零变为1,然后全程是高电平的,写完后右边为低电平0;

SCLK时钟引脚,是一个高电平,一个低电平,再一个高电平,再一个低电平,如此循环,即时钟信号先来一个上升沿,在一个下降沿,再一个上升沿,再一个下降沿,如此往复;且时钟里规定,在SCLK的上升沿,I/O口将写入一个对应的数据;在SCLK的下降沿,DS1302就会将数据输出到MCU;总结一句话就是,在SCLK的上升沿,MCU向时钟写入数据,在SCLK的下降沿,时钟向MCU写入数据,也等价于MCU向时钟读取数据;这种方式跟之前提到的SPI通信方式很类似。

I/O引脚,左边半部分是表示命令字,从左到右是命令字八个位的从低位到高位;右边半部分表示要写入的字节,从左到右也是字节的从低位到高位。

下面详细介绍一下时序图的过程(以写数据为例):

首先将CE置为高电平1;然后对于写数据来说,需要给到时钟输入两个字节,第一个字节是命令字,第二个字节表示要写入的字节数据;
在这里插入图片描述
我们首先取第一个字节的最低位,然后将SCLK置为高电平1(对应上升沿),此时就将第一个字节的最低位给到了R/W,然后将SCLK置为低电平0(对应下降沿);然后取第一个字节的第二位,然后将SCLK置为高电平1(对应上升沿),此时就将第二个字节的第二位给到了A0,然后将SCLK置为低电平0(对应下降沿);如此循环8次,直到将第一个字节的所有位都给到了命令字;然后同样的方法,将第二个字节的每一位写入到D0-D7;此时就完成了整个单字节写的过程。

1.2 本节目标

目标1:实现一个DS1302时钟,显示在LCD1602上,效果如下:
在这里插入图片描述
目标2:实现一个DS1302时钟,并能通过按键对时间进行修改

其中第一个按键功能是在显示模式和调节时间模式间进行切换

比如当按下按键第一个按键时,时钟由显示模式改为了调节时间模式,即年时间在闪烁:
在这里插入图片描述
第二个按键的功能是选择调节的位,比如上图已经到了调节年,按下第二个键时,可以发现到了调节月,即月时间在闪烁:
在这里插入图片描述
同样的,再按下第二个按键时,可以发现到了调节日,即日时间在闪烁:

在这里插入图片描述

第三个按键是对时间进行加操作,第四个按键是对时间进行减操作。

并且逻辑里加入了闰年、闰月、每个月是28天还是29天还是30天还是31天等等逻辑进行了判断,所以逻辑比较复杂。

二、DS1302时钟

代码路径:51单片机入门教程资料\课件及程序源码\程序源码\KeilProject\10-1 DS1302时钟
具体代码:

#include <REGX52.H>
#include "LCD1602.h"
#include "DS1302.h"

void main()
{
	LCD_Init();
	DS1302_Init();
	LCD_ShowString(1,1,"  -  -  ");//静态字符初始化显示
	LCD_ShowString(2,1,"  :  :  ");
	
	DS1302_SetTime();//设置时间
	
	while(1)
	{
		DS1302_ReadTime();//读取时间
		LCD_ShowNum(1,1,DS1302_Time[0],2);//显示年
		LCD_ShowNum(1,4,DS1302_Time[1],2);//显示月
		LCD_ShowNum(1,7,DS1302_Time[2],2);//显示日
		LCD_ShowNum(2,1,DS1302_Time[3],2);//显示时
		LCD_ShowNum(2,4,DS1302_Time[4],2);//显示分
		LCD_ShowNum(2,7,DS1302_Time[5],2);//显示秒
	}
}

DS1302.c:

#include <REGX52.H>

//引脚定义
sbit DS1302_SCLK=P3^6;
sbit DS1302_IO=P3^4;
sbit DS1302_CE=P3^5;

//寄存器写入地址/指令定义
#define DS1302_SECOND		0x80
#define DS1302_MINUTE		0x82
#define DS1302_HOUR			0x84
#define DS1302_DATE			0x86
#define DS1302_MONTH		0x88
#define DS1302_DAY			0x8A
#define DS1302_YEAR			0x8C
#define DS1302_WP			0x8E

//时间数组,索引0~6分别为年、月、日、时、分、秒、星期
unsigned char DS1302_Time[]={19,11,16,12,59,55,6};

/**
  * @brief  DS1302初始化
  * @param  无
  * @retval 无
  */
void DS1302_Init(void)
{
	DS1302_CE=0;
	DS1302_SCLK=0;
}

/**
  * @brief  DS1302写一个字节
  * @param  Command 命令字/地址
  * @param  Data 要写入的数据
  * @retval 无
  */
void DS1302_WriteByte(unsigned char Command,Data)
{
	unsigned char i;
	DS1302_CE=1;
	for(i=0;i<8;i++)
	{
		DS1302_IO=Command&(0x01<<i);
		DS1302_SCLK=1;
		DS1302_SCLK=0;
	}
	for(i=0;i<8;i++)
	{
		DS1302_IO=Data&(0x01<<i);
		DS1302_SCLK=1;
		DS1302_SCLK=0;
	}
	DS1302_CE=0;
}

/**
  * @brief  DS1302读一个字节
  * @param  Command 命令字/地址
  * @retval 读出的数据
  */
unsigned char DS1302_ReadByte(unsigned char Command)
{
	unsigned char i,Data=0x00;
	Command|=0x01;	//将指令转换为读指令
	DS1302_CE=1;
	for(i=0;i<8;i++)
	{
		DS1302_IO=Command&(0x01<<i);
		DS1302_SCLK=0;
		DS1302_SCLK=1;
	}
	for(i=0;i<8;i++)
	{
		DS1302_SCLK=1;
		DS1302_SCLK=0;
		if(DS1302_IO){Data|=(0x01<<i);}
	}
	DS1302_CE=0;
	DS1302_IO=0;	//读取后将IO设置为0,否则读出的数据会出错
	return Data;
}

/**
  * @brief  DS1302设置时间,调用之后,DS1302_Time数组的数字会被设置到DS1302中
  * @param  无
  * @retval 无
  */
void DS1302_SetTime(void)
{
	DS1302_WriteByte(DS1302_WP,0x00);
	DS1302_WriteByte(DS1302_YEAR,DS1302_Time[0]/10*16+DS1302_Time[0]%10);//十进制转BCD码后写入
	DS1302_WriteByte(DS1302_MONTH,DS1302_Time[1]/10*16+DS1302_Time[1]%10);
	DS1302_WriteByte(DS1302_DATE,DS1302_Time[2]/10*16+DS1302_Time[2]%10);
	DS1302_WriteByte(DS1302_HOUR,DS1302_Time[3]/10*16+DS1302_Time[3]%10);
	DS1302_WriteByte(DS1302_MINUTE,DS1302_Time[4]/10*16+DS1302_Time[4]%10);
	DS1302_WriteByte(DS1302_SECOND,DS1302_Time[5]/10*16+DS1302_Time[5]%10);
	DS1302_WriteByte(DS1302_DAY,DS1302_Time[6]/10*16+DS1302_Time[6]%10);
	DS1302_WriteByte(DS1302_WP,0x80);
}

/**
  * @brief  DS1302读取时间,调用之后,DS1302中的数据会被读取到DS1302_Time数组中
  * @param  无
  * @retval 无
  */
void DS1302_ReadTime(void)
{
	unsigned char Temp;
	Temp=DS1302_ReadByte(DS1302_YEAR);
	DS1302_Time[0]=Temp/16*10+Temp%16;//BCD码转十进制后读取
	Temp=DS1302_ReadByte(DS1302_MONTH);
	DS1302_Time[1]=Temp/16*10+Temp%16;
	Temp=DS1302_ReadByte(DS1302_DATE);
	DS1302_Time[2]=Temp/16*10+Temp%16;
	Temp=DS1302_ReadByte(DS1302_HOUR);
	DS1302_Time[3]=Temp/16*10+Temp%16;
	Temp=DS1302_ReadByte(DS1302_MINUTE);
	DS1302_Time[4]=Temp/16*10+Temp%16;
	Temp=DS1302_ReadByte(DS1302_SECOND);
	DS1302_Time[5]=Temp/16*10+Temp%16;
	Temp=DS1302_ReadByte(DS1302_DAY);
	DS1302_Time[6]=Temp/16*10+Temp%16;
}

三、DS1302可调时钟

代码路径:51单片机入门教程资料\课件及程序源码\程序源码\KeilProject\10-2 DS1302可调时钟
具体代码:

#include <REGX52.H>
#include "LCD1602.h"
#include "DS1302.h"
#include "Key.h"
#include "Timer0.h"

unsigned char KeyNum,MODE,TimeSetSelect,TimeSetFlashFlag;

void TimeShow(void)//时间显示功能
{
	DS1302_ReadTime();//读取时间
	LCD_ShowNum(1,1,DS1302_Time[0],2);//显示年
	LCD_ShowNum(1,4,DS1302_Time[1],2);//显示月
	LCD_ShowNum(1,7,DS1302_Time[2],2);//显示日
	LCD_ShowNum(2,1,DS1302_Time[3],2);//显示时
	LCD_ShowNum(2,4,DS1302_Time[4],2);//显示分
	LCD_ShowNum(2,7,DS1302_Time[5],2);//显示秒
}

void TimeSet(void)//时间设置功能
{
	if(KeyNum==2)//按键2按下
	{
		TimeSetSelect++;//设置选择位加1
		TimeSetSelect%=6;//越界清零
	}
	if(KeyNum==3)//按键3按下
	{
		DS1302_Time[TimeSetSelect]++;//时间设置位数值加1
		if(DS1302_Time[0]>99){DS1302_Time[0]=0;}//年越界判断
		if(DS1302_Time[1]>12){DS1302_Time[1]=1;}//月越界判断
		if( DS1302_Time[1]==1 || DS1302_Time[1]==3 || DS1302_Time[1]==5 || DS1302_Time[1]==7 || 
			DS1302_Time[1]==8 || DS1302_Time[1]==10 || DS1302_Time[1]==12)//日越界判断
		{
			if(DS1302_Time[2]>31){DS1302_Time[2]=1;}//大月
		}
		else if(DS1302_Time[1]==4 || DS1302_Time[1]==6 || DS1302_Time[1]==9 || DS1302_Time[1]==11)
		{
			if(DS1302_Time[2]>30){DS1302_Time[2]=1;}//小月
		}
		else if(DS1302_Time[1]==2)
		{
			if(DS1302_Time[0]%4==0)
			{
				if(DS1302_Time[2]>29){DS1302_Time[2]=1;}//闰年2月
			}
			else
			{
				if(DS1302_Time[2]>28){DS1302_Time[2]=1;}//平年2月
			}
		}
		if(DS1302_Time[3]>23){DS1302_Time[3]=0;}//时越界判断
		if(DS1302_Time[4]>59){DS1302_Time[4]=0;}//分越界判断
		if(DS1302_Time[5]>59){DS1302_Time[5]=0;}//秒越界判断
	}
	if(KeyNum==4)//按键3按下
	{
		DS1302_Time[TimeSetSelect]--;//时间设置位数值减1
		if(DS1302_Time[0]<0){DS1302_Time[0]=99;}//年越界判断
		if(DS1302_Time[1]<1){DS1302_Time[1]=12;}//月越界判断
		if( DS1302_Time[1]==1 || DS1302_Time[1]==3 || DS1302_Time[1]==5 || DS1302_Time[1]==7 || 
			DS1302_Time[1]==8 || DS1302_Time[1]==10 || DS1302_Time[1]==12)//日越界判断
		{
			if(DS1302_Time[2]<1){DS1302_Time[2]=31;}//大月
			if(DS1302_Time[2]>31){DS1302_Time[2]=1;}
		}
		else if(DS1302_Time[1]==4 || DS1302_Time[1]==6 || DS1302_Time[1]==9 || DS1302_Time[1]==11)
		{
			if(DS1302_Time[2]<1){DS1302_Time[2]=30;}//小月
			if(DS1302_Time[2]>30){DS1302_Time[2]=1;}
		}
		else if(DS1302_Time[1]==2)
		{
			if(DS1302_Time[0]%4==0)
			{
				if(DS1302_Time[2]<1){DS1302_Time[2]=29;}//闰年2月
				if(DS1302_Time[2]>29){DS1302_Time[2]=1;}
			}
			else
			{
				if(DS1302_Time[2]<1){DS1302_Time[2]=28;}//平年2月
				if(DS1302_Time[2]>28){DS1302_Time[2]=1;}
			}
		}
		if(DS1302_Time[3]<0){DS1302_Time[3]=23;}//时越界判断
		if(DS1302_Time[4]<0){DS1302_Time[4]=59;}//分越界判断
		if(DS1302_Time[5]<0){DS1302_Time[5]=59;}//秒越界判断
	}
	//更新显示,根据TimeSetSelect和TimeSetFlashFlag判断可完成闪烁功能
	if(TimeSetSelect==0 && TimeSetFlashFlag==1){LCD_ShowString(1,1,"  ");}
	else {LCD_ShowNum(1,1,DS1302_Time[0],2);}
	if(TimeSetSelect==1 && TimeSetFlashFlag==1){LCD_ShowString(1,4,"  ");}
	else {LCD_ShowNum(1,4,DS1302_Time[1],2);}
	if(TimeSetSelect==2 && TimeSetFlashFlag==1){LCD_ShowString(1,7,"  ");}
	else {LCD_ShowNum(1,7,DS1302_Time[2],2);}
	if(TimeSetSelect==3 && TimeSetFlashFlag==1){LCD_ShowString(2,1,"  ");}
	else {LCD_ShowNum(2,1,DS1302_Time[3],2);}
	if(TimeSetSelect==4 && TimeSetFlashFlag==1){LCD_ShowString(2,4,"  ");}
	else {LCD_ShowNum(2,4,DS1302_Time[4],2);}
	if(TimeSetSelect==5 && TimeSetFlashFlag==1){LCD_ShowString(2,7,"  ");}
	else {LCD_ShowNum(2,7,DS1302_Time[5],2);}
}

void main()
{
	LCD_Init();
	DS1302_Init();
	Timer0Init();
	LCD_ShowString(1,1,"  -  -  ");//静态字符初始化显示
	LCD_ShowString(2,1,"  :  :  ");
	
	DS1302_SetTime();//设置时间
	
	while(1)
	{
		KeyNum=Key();//读取键码
		if(KeyNum==1)//按键1按下
		{
			if(MODE==0){MODE=1;TimeSetSelect=0;}//功能切换
			else if(MODE==1){MODE=0;DS1302_SetTime();}
		}
		switch(MODE)//根据不同的功能执行不同的函数
		{
			case 0:TimeShow();break;
			case 1:TimeSet();break;
		}
	}
}

void Timer0_Routine() interrupt 1
{
	static unsigned int T0Count;
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	T0Count++;
	if(T0Count>=500)//每500ms进入一次
	{
		T0Count=0;
		TimeSetFlashFlag=!TimeSetFlashFlag;//闪烁标志位取反
	}
}

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

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

相关文章

Solon 框架,单月下载量突破100万了!!!

Solon 框架&#xff0c;单月下载量突破100万了。感谢开源的力量和社区的支持&#xff0c;我们同喜同荣&#xff01;&#xff01;&#xff01;目前&#xff0c;作为新成员加入了“可信开源共同体”&#xff0c;也积极参与中科院的“开源之夏”计划&#xff0c;也备受某军工服务商…

【C++入门】你知道C++为什么会有内联函数吗?

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前学习C和算法 ✈️专栏&#xff1a;C航路 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac; 点赞&#x1…

深度优先遍历和广度优先遍历

深度优先遍历和广度优先遍历 文章目录 深度优先遍历和广度优先遍历图图的实现遍历方式深度优先遍历基本思想广度优先遍历基本思想 完整代码 图 介绍&#xff1a;用于表示多对多的关系 图是一种数据结构&#xff0c;其中结点可以具有零个或多个相邻元素。两个结点之间的连接称…

FFmpeg AAC 解码 PCM

1. 概要与流程图 1.1 AAC 转 PCM,需要解码库来实现,目前了解有三种方式,当前使用的是 FFmpeg 库解码 1) faad 解码库网址:faadhttps://sourceforge.net/projects/faac/files/faad2-src/ 2) fdk-aac 编解码库网址: fdk-aac

接口测试入门:轻松掌握 ,让你的后端“心甘情愿”地配合你

目录 前言 简介 什么是API测试&#xff1f; API测试的必要性 API测试的类型 优势 API测试的挑战 【自动化测试工程师学习路线】 前言 在这篇文章中&#xff0c;我将带你轻松入门接口测试并掌握实用技巧&#xff0c;让你能够与后端开发人员更加顺畅地合作。相信我&…

【量化分析】用mplfinance显示交易图时,处理 Expect data.index as DatetimeIndex?

目录 一、说明 二、程序代码和出错描述 三、合理化建议 3.1 读入数据时指定索引 3.2 读入数据后&#xff0c;使用数据前指定日期&#xff08;时间戳&#xff09;索引 一、说明 我打算从比特币数据中获取烛台图。这是我在加载 csv 文件后选择我想要的数据框的代码。然而&…

【2】Kaggle:狗的种类识别,基于论文中的 VGG(11)/ResNet(18)/SENet 结构实现

1.数据集格式 在前面【1】中已经对数据集进行过了处理,在自己实现这一模块,训练数据集的统一格式为下图: 2.VGG11结构 根据论文Karen Simonyan, Andrew Zisserman. Very deep convolutional networks for large-scale image recognition. ICLR, 2015. (VGG) 中的结构,根…

如何在华为云服务器安装MindSpore框架

参考链接 一、获取安装命令 我是在华为云租了一个云服务器&#xff0c;然后系统是Ubuntu18.04,如果不知道自己的系统&#xff0c;可以通过以下方式&#xff1a; 第三方依赖安装方法 1.确认安装Ubuntu 18.04是64位操作系统 确认系统版本号&#xff0c;在终端输入lsb_release…

Linux -- 进阶 Web服务器 虚拟主机 --- 基于 IP 地址

虚拟主机 一个Web 服务器&#xff0c;如果只能运行一个网站的话&#xff0c;那么对于一些经费不是很足的小公司来说&#xff0c;那就 有些奢侈了&#xff0c;资源没有办法完全利用上 &#xff08; 无论是 内存&#xff0c;CPU&#xff0c;硬盘&#xff0c;带宽等等 &#xff0…

【网络常用命令汇总】ping和ipconfig命令、nslookup命令、netstat和tracert命令、route和arp命令详解(附图详解)

【写在前面】由于考试将近我也是临时抱个佛脚&#xff0c;之前对网络这块的概念真的只是停留在大学里面学的计算机网络&#xff0c;但是当时并没有接触这些实在的东西&#xff0c;也就只有工作后才会去想那么多&#xff0c;比如网络连通性ping一下就知道&#xff0c;其他的更不…

第07讲:Java High Level Client,读写 ES 利器

SkyWalking OAP 后端可以使用多种存储对数据进行持久化&#xff0c;例如 MySQL、TiDB 等&#xff0c;默认使用 ElasticSearch 作为持久化存储&#xff0c;在后面的源码分析过程中也将以 ElasticSearch 作为主要存储进行分析。 ElasticSearch 基本概念 本课时将快速介绍一下 E…

【类和对象完结篇】

目录 ❀初始化列表 构造函数体赋值 初始化列表 ❀explicit关键字 ❀static成员 什么是static成员&#xff1f; 特性 ❀友元 友元函数 友元类 ❀内部类 ❀理解类和对象 &#x1f340;​​​​​​​​​​​​​​小结&#x1f340; &#x1f389;博客主页&#xf…

linux环境安装使用mysql详解

01-安装MySQL并启动 1.1 环境准备 # 1.卸载mariadb&#xff0c;否则安装mysql会出现冲突 &#xff08;1&#xff09;.执行命令rpm -qa | grep mariadb 会列出所有被安装的mariadb rpm 包&#xff1b; &#xff08;2&#xff09;.执行命令rpm -e --nodeps mariadb-libs-5.5.56…

super_排列组合lesson08易错题记录

此题用插空法解决&#xff1a;这个是组合的问题&#xff0c;总共10个学生&#xff0c;要分配到7个班级里&#xff0c;也就是要把这十个学生分为7部分&#xff0c;如果让学生们站在一起&#xff0c;就是在9个空位中插入6块木板&#xff0c;也就是C(9,6)也就是84 此题用捆绑法解决…

[Java进阶] 线程池详解

文章目录 前言1. 线程池的作用2. 线程池的应用3. 标准库中创建线程池的方式 前言 本文介绍线程池的作用和实现方法. 1. 线程池的作用 1.我们知道,线程的作用是由于进程的创建和销毁需要分配和回收资源,开销较大.而线程是"轻量级进程",创建销毁更高效. 2.线程池,比线…

汽车发动机点火性能测试仪设计

汽车发动机的点火系统包括上百种电气和机械零部件&#xff0c;生产线分布较广&#xff0c;因此分布式间接监控方式在点火系统的监测与故障诊断系统中得到广泛应用。发动机点火性能测试仪通过测量发动机的闭合角与分火角&#xff0c;对其分电器和点火器性能进行分析。 闭合角、分…

Python接口自动化测试实战系列

本节内容 接口及接口测试 网络基础知识&#xff1a;IP,域名, DNS及端口 网络基础知识&#xff1a;OSI七层模型及TCP协议 HTTP协议 接口及接口测试 这里插播一个段子 上图中&#xff0c;程序员口中提到的接口是什么意思呢&#xff1f; 手机壳有没有颜色这个属性&#xff0…

安全渗透工程师入门最快需要多久?提供具体路线和学习框架

前言 网络渗透这个东西学起来如果没有头绪和路线的话&#xff0c;是非常烧脑的。最快达到入门也要半年 理清网络渗透学习思路&#xff0c;把自己的学习方案和需要学习的点全部整理&#xff0c;你会发现突然渗透思路就有点眉目了。 网络安全好混&#xff0c;但不容易混得好。…

【顶配快速排序】CUTOFF配合三点中值法的三路划分

目录 1引入情境2 形式化描述2-1递归结构2-2 一次划分2-3 C实现 3 在工程中的改进3-1 处理重复元素双向划分三路划分C 实现 3-2 最差情况的改进三点中值法随机选择pivot短序列切回插入排序 4 全部改进技术加持 1引入情境 从低到高排成一队&#xff0c;怎么办&#xff1f; 以大雄…

RIME协议栈解读

// 新坑–contiki rime简介 rime类似于TCP/IP协议栈&#xff0c;属于分层结构。图片来自Adam Dunkels本人的rime论文介绍。 abc为anonymous broadcast&#xff0c;匿名广播。即将数据包通过无线射频驱动(radio driver)发出去&#xff0c;接收来自无线射频驱动所有的包并交给…