嵌入式开发二十一:定时器之通用定时器

news2024/11/27 4:20:49

        通用定时器是在基本定时器的基础上扩展而来,增加了输入捕获与输出比较等功能。高级定时器又是在通用定时器基础上扩展而来,增加了可编程死区互补输出、重复计数器、带刹车(断路)功能,这些功能主要针对工业电机控制方面。 本篇博客我们主要来学习通用定时器,通过上一次的学习,我们知道 STM32F407 有 10 个通用定时器(TIM2~TIM5 和 TIM9~TIM14)。这些定时器彼此完全独立,不共享任何资源。

目录

一、STM32F4 通用定时器简介

二、通用定时器框图

2.0  预备知识

2.0.1 触发信号

2.0.2  从模式控制器

2.1 时钟源(重要)

2.1.1 内部时钟(CK_INT)

2.1.2 外部时钟模式 1(TI1、TI2)

2.1.3 外部时钟模式 2(ETR)

2.1.4 内部触发输入(ITRx)

2.2 控制器

2.3 时基单元

2.4 输入捕获

2.5 输入捕获和输出比较公共部分

2.6 输出比较


一、STM32F4 通用定时器简介

        STM32F407 的通用定时器有 10 个,为了更好的区别各个定时器的特性,我们列了一个表 格,如下所示:

        STM32F4 的通用定时器包含一个 16 位或 32 位自动重载计数器(CNT),该计数器由可编 程预分频器(PSC)驱动。STM32F4 的通用定时器可以被用于:测量输入信号的脉冲长度(输入 捕获)或者产生输出波形(输出比较和 PWM)等。 使用定时器预分频器和 RCC 时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。STM32F4 的每个通用定时器都是完全独立的,没有互相共享的任何资源。

STM32 的通用 TIMx (TIM2~TIM5 和 TIM9~TIM14)定时器功能包括:

  1. 16 位/32 位(仅 TIM2 和 TIM5)向上、向下、向上/向下自动装载计数器(TIMx_CNT),注意:TIM9~TIM14 只支持向上(递增)计数方式。
  2. 16 位可编程(可以实时修改)预分频器(TIMx_PSC),计数器时钟频率的分频系数为 1~ 65535 之间的任意数值。
  3. 4 个独立通道(TIMx_CH1~4,TIM9~TIM14 最多 2 个通道),这些通道可以用来作为:
  4. A.输入捕获 B.输出比较 C.PWM 生成(边缘或中间对齐模式) ,注意:TIM9~TIM14 不支持中间对齐模式 D.单脉冲模式输出
  5. 可使用外部信号(TIMx_ETR)控制定时器和定时器互连(可以用 1 个定时器控制另外 一个定时器)的同步电路。
  6. 如下事件发生时产生中断/DMA(TIM9~TIM14 不支持 DMA):
  • A.更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)
  • B.触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)
  • C.输入捕获
  • D.输出比较
  • E.支持针对定位的增量(正交)编码器和霍尔传感器电路(TIM9~TIM14 不支持)
  • F.触发输入作为外部时钟或者按周期的电流管理(TIM9~TIM14 不支持)

        由以上分析知道:该 STM32 芯片的计数器都是 16 位/32位的。通用定时器和高级定时器其实也就是在基本定时器的基础上,添加了一些其他功能,如:输入捕获、输出比较、输出 PWM 和单脉冲模式等。而通用定时器数量较多,其特性也有一些的差异,但是基本原理都一样。

二、通用定时器框图

      下面先来学习通用定时器框图,通过学习通用定时器框图会有一个很好的整体掌握,同时对之后的编程也会有一个清晰的思路。如下图,通用定时器的框图比基本定时器的框图复杂许多,为了方便介绍,我们将其分成六个部分讲解:

2.0  预备知识

2.0.1 触发信号

        触发信号:可以理解为脉冲信号。在STM32中触发信号分为两大类:TRGI 和 TRGO,即触发输⼊信号和触发输出信号。

  1. 触发输入信号TRGI : 可以理解为从外部引⼊到定时器中的信号。
  2. 触发输出信号TRGO:定时器输出给其它定时器或外设的信号。

 触发输入信号:

  1. 第⼀类:TI1F_ED/TI1FP1/TI2FP2,来自输入通道1或通道2的触发信号,连接到从模式控制器,从而控制计数器的工作。
  2. 第⼆类:来自外部触发脚[ETR]的信号经过处理后,连接到从模式控制器。
  3. 第三类:来自其他定时器的触发信号(ITR),通过内部线路连接到从模式控制器。

触发输出信号:

   触发输出信号是定时器自身产生的,那么他是如何产生的并有哪些触发输出信号

  1. 定时器更新事件;
  2. 定时器的输入捕获和输出比较事件;
  3. 复位;
  4. 使能;
  5. 更新:选择更新事件作为触发输出 (TRGO)。例如,主定时器可⽤作从定时器的预分频器。

2.0.2  从模式控制器

从模式控制器的几种模式:

  1. 复位模式:当有效触发信号出现时,将会复位计数器,并产生更新事件。向上计数的将会复位到0,向下计数的将会复位到ARR的值。 
  2. 门控模式:定时器根据触发输入信号的电平来启动或停止计数器的计数;
  3. 触发模式:当有效触发输入信号出现时,会将本来处于未使能状态的计数器使能激活,让计数器开始计数;
  4. 外部时钟模式1:由所选触发信号 (TRGI) 的上升沿提供计数器时钟。
  • 小结:
  • (1)不论来自本定时器外部的哪⼀类触发输入信号,它们有个共同特点,就是都要经过触发输入选择器而连接到从模式控制器,从而使得计数器的工作受到从模式控制器的控制或影响。
  • (2)从模式控制器可以对定时器作如下操控:对计数器复位、启动或停⽌计数动作、使能计数器、通过触发信号为计数器提供时钟源。

2.1 时钟源(重要)

      通用定时器时钟可以选择下面四类时钟源之一:

  1. 内部时钟(CK_INT)
  2. 外部时钟模式 1:外部输入引脚(TIx),x=1,2(即只能来自于通道1或者通道 2);
  3. 外部时钟模式 2:外部触发输入(ETR);
  4. 内部触发输入(ITRx):使用一个定时器作为另一定时器的预分频器;

       通用定时器时钟源的设置方法如下表所示:

2.1.1 内部时钟(CK_INT)

      STM32F4 系列的定时器 TIM2/TIM3/TIM4/TIM5/ TIM6/TIM7/ TIM12/ TIM13/ TIM14 都是挂载在 APB1 总线上,这些定时器的内部时钟(CK_INT)实际上来自于 APB1 总线提供的时钟。 但是这些定时器时钟不是由 APB1 总线直接提供,而是要先经过一个倍频器。在源码中,已经设置 APB1 总线时钟频率为 42MHz,APB1 预分频器的预分频系数为4,所以这些定时器时钟源频率为 84MHz。因为 当 APB1 预分频器的预分频系数≥2 分频时,挂载在 APB1 总线上的定时器时钟频率是该总线时钟频率的两倍。这个和基本定时器一样,可回顾基本定时器这部分内容。APB2 总线上挂载的通用定时器 TIM9/TIM10/TIM11,以及高级定时器 TIM1 和 TIM8,它 们的情况是上面的描述是一样的,不同点是:定时器挂载的总线变成了 APB2,在系统时钟初始化函数已经设置 APB2 总线时钟频率为 84MHz,预分频器的预分频系数为 2,所以上述的定时器时钟源频率为168MHz。

内部时钟:

  1. TIM2/TIM3/TIM4/TIM5/ TIM6/TIM7/ TIM12/ TIM13/ TIM14定时器挂载在APB1上:84MHZ;
  2. TIM9/TIM10/TIM11,以及高级定时器 TIM1 和 TIM8挂载在APB2上:168MHZ;

2.1.2 外部时钟模式 1(TI1、TI2)

       外部时钟模式 1 这类时钟源,顾名思义时钟信号来自芯片外部

时钟源进入定时器的流程如下:外部时钟源信号→IO→TIMx_CH1(或者 TIMx_CH2);

       注意:外部时钟模式 1 下,时钟源信号只能从 CH1 或者 CH2 输入到定时器,CH3 和 CH4 都是不可以的。

       从 IO 到 TIMx_CH1(或者 TIMx_CH2),就需要我们配置 IO 的复用功能,才能使 IO 和定时器通道相连通。时钟源信号来到定时器 CH1 或 CH2 后,需要经过什么“关卡”才能到达计数器作为计数的时钟频率的,下面通过外部时钟模式 1 框图给大家解答。

 图 21.1.2 中是以 CH2(通道 2)为例的,时钟源信号到达 CH2 后,那么这里我们把这个时钟源信号用 TI2 表示,因为它只是个信号,来到定时器内部,那我们就按定时器内部的信号来命名,所谓入乡随俗。

  1.  TI2首先经过一个滤波器,由 ICF[3:0]位来设置滤波方式,也可以设置不使用滤波器。(如果来自外部的时钟信号的频率过高或者混杂有高频干扰信号的话,我们就需要使用滤波器对 ETRP 信号重新采样,来达到降频或者去除高频干扰的目的)
  2.  接着经过边沿检测器,由 CC2P 位来设置检测的边沿,可以上升沿或者下降沿检测。
  3.  然后经过触发输入选择器,由 TS[4:0]位来选择 TRGI(触发输入信号)的来源。可以看到图 21.1.2 中框出了 TI1F_ED、TI1FP1 和 TI2FP2 三个触发输入信号(TRGI)。TI1F_ED 表示来自于 CH1,并且没有经过边沿检测器过滤的信号,所以它是 CH1 的双边沿信号,即上升沿或者下降沿都是有效的TI1FP1 表示来自 CH1 并经过边沿检测器后的信号,可以是上升沿或者下降沿TI2FP2 表示来自 CH2 并经过边沿检测器后的信号,可以是上升沿或者下降沿。这里以 CH2 为例,那只能选择 TI2FP2。如果是 CH1 为例,那就可以选择 TI1F_ED 或者 TI1FP1。
  4. 最后经过从模式选择器,由 ECE 位和 SMS[2:0]位来选择定时器的时钟源。这里我们介绍的是外部时钟模式 1,所以 ECE 位置 0,SMS[2:0] = 111 即可。CK_PSC 需要经过定时器的预分频器分频后,最终就能到达计数器进行计数了。

2.1.3 外部时钟模式 2(ETR)

        外部时钟模式 2,顾名思义时钟信号来自芯片外部

时钟源进入定时器的流程如下:外部时钟源信号→IO→TIMx_ETR。

       从 IO 到 TIMx_ETR,就需要我们配置 IO 的复用功能,才能使IO和定时器相连通。 时钟源信号来到定时器 TIMx_ETR 后,需要经过什么“关卡”才能到达计数器作为计数的时钟频率的,下面通过外部时钟模式 2 框图给大家解答。

图 21.1.3 中,可以看到在外部时钟模式 2 下:

  1. 定时器时钟信号首先从 ETR 引脚进来。
  2.  接着经过外部触发极性选择器,由 ETP 位来设置上升沿有效还是下降沿有效,选择下降沿有效的话,信号会经过反相器。
  3. 然后经过外部触发预分频器,由 ETPS[1:0]位来设置预分频系数,系数范围:1、2、4、8。 紧接着经过滤波器,由 ETF[3:0]位来设置滤波方式,也可以设置不使用滤波器。fDTS 由 TIMx_CR1 寄存器的 CKD 位设置。
  4. 最后经过从模式选择器,由 ECE 位和 SMS[2:0]位来选择定时器的时钟源。这里我们介绍的是外部时钟模式 2,直接把 ECE 位置 1 即可。CK_PSC 需要经过定时器的预分频器分频后, 最终就能到达计数器进行计数了。

2.1.4 内部触发输入(ITRx)

      内部触发输入是使用一个定时器作为另一个定时器的预分频器,即实现定时器的级联

下 面以 TIM1 作为 TIM2 的预分频器为例,给大家介绍。

上图中,TIM1 作为 TIM2 的预分频器,需要完成的配置步骤如下:

  1. TIM1_CR2 寄存器的 MMS[2:0]位设置为 010,即 TIM1 的主模式选择为更新(选择更新事件作为触发输出 (TRGO))。
  2. TIM2_SMCR 寄存器的 TS[2:0]位设置为 000,即使用 ITR1 作为内部触发
  3. TIM2_SMCR 寄存器的 SMS[2:0]位设置为 111,即从模式控制器选择外部时钟模式 1
  4. TIM1 和 TIM2 的 CEN 位都要置 1,即启动计数器

       定时器的时钟源这部分内容是非常重要的,因为这计数器工作的基础。虽然定时器有四类时钟源之多,但是我们最常用的还是内部时钟。 

TS[2:0]位用于配置触发选择,除了 ITR1,还有其他的选择,详细描述如下图所示:

      上图中的触发选择中,我们在讲解外部时钟模式 1 的时候说过 TI1F_ED、TI1FP1 和 TI2FP2, 以及外部时钟模式 2 讲的 ETRF,它们都是属于外部的,其余的都是内部触发了。那么这内部触发都代表什么意思呢?大家打开《STM32F4xx 参考手册_V4(中文版).pdf》的 428 页,就可以找下面这个表。

在步骤 2 中,TS[2:0]位设置为 000,使用 ITR0 作为内部触发,这个 ITR0 什么意思?由表 21.1.3 可以知道,当从模式定时器为 TIM2 时,ITR0 表示主模式定时器就是 TIM1。这里只是 TIM2~5 的内部触发连接情况,其他定时器请查看参考手册的相应章节。

2.2 控制器

        控制器包括:从模式控制器、编码器接口和触发控制器(TRGO)。

  1. 从模式控制器:可以控制计数器复位、启动、递增/递减、计数。
  2. 编码器接口:针对编码器计数而设计。
  3. 触发控制器:用来针对片内外设提供触发信号给别的外设,比如为其它定时器提供时钟或者为 DAC/ADC 的触发转换提供信号。

2.3 时基单元

      时基单元包括:计数器寄存器(TIMx_CNT)、预分频器寄存器(TIMx_PSC)、自动重载寄存器 (TIMx_ARR)。这部分内容和基本定时器基本一样的,大家可以参考基本定时器的介绍。不同点是:通用定时器的计数模式有三种:递增计数模式、递减计数模式和中心对齐模式

  1. 递增计数模式下,计数器从 0 开始计数,每来一个 CK_CNT 脉冲计数器就增加 1,直 到计数器的值与自动重载寄存器 ARR 值相等,然后计数器又从 0 开始计数并生成计数 器上溢事件,计数器总是如此循环计数。如果禁用重复计数器,在计数器生成上溢事 件就马上生成更新事件(UEV);如果使能重复计数器,每生成一次上溢事件重复计数器内容就减 1,直到重复计数器内容为 0 时才会生成更新事件。
  2.  递减计数模式下,计数器从自动重载寄存器 ARR 值开始计数,每来一个 CK_CNT 脉 冲计数器就减 1,直到计数器值为 0,然后计数器又从自动重载寄存器 ARR 值开始递 减计数并生成计数器下溢事件,计数器总是如此循环计数。如果禁用重复计数器,在 计数器生成下溢事件就马上生成更新事件;如果使能重复计数器,每生成一次下溢事 件重复计数器内容就减 1,直到重复计数器内容为 0 时才会生成更新事件。
  3. 中心对齐模式下,计数器从 0 开始递增计数,直到计数值等于(ARR-1)值生成计数器上 溢事件,然后从 ARR 值开始递减计数直到 1 生成计数器下溢事件。然后又从 0 开始计 数,如此循环。每次发生计数器上溢和下溢事件都会生成更新事件。

      计数器的计数模式的设置请参考 TIMx_CR1 寄存器的位 CMS 和位 DIR。 下面通过一张图给大家展示定时器工作在不同计数模式下,更新事件发生的情况。定时器溢出就 会伴随着更新事件的发生。

上图中,纵轴表示计数器的计数值,横轴表示时间,ARR 表示自动重载寄存器的值,小红点就是更新事件发生的时间点。举个例子,递增计数模式下,当计数值等于 ARR 时,计数器的值被复位为 0,定时器溢出,并伴随着更新事件的发生,后面继续递增计数。递减计数模式和中心对齐模式请参考前面的描述。 上表的描述属于硬件更新事件发生条件,我们还可以通过 UG 位产生软件更新事件。 关于影子寄存器和定时器溢出时间计算公式等内容可以参考基本定时器的相关内容。

2.4 输入捕获(重要)

       图 21.1.1.1 中的第④部分是输入捕获,一般应用是要和第⑤部分一起完成测量功能。 TIMx_CH1~ TIMx_CH4 表示定时器的 4 个通道,这 4 个通道都是可以独立工作的。IO 端口通过复用功能与这些通道相连。配置好 IO 端口的复用功能后,将需要测量的信号输入到相应的 IO 端口,输入捕获部分可以对输入的信号的上升沿,下降沿或者双边沿进行捕获,常见的测量有:测量输入信号的脉冲宽度、测量 PWM 输入信号的频率和占空比等。后续有相应的实验。

简单介绍:测量高电平脉冲宽度的工作原理,方便大家的理解:

       一般先要设置输入捕获的边沿检测极性,如:我们设置上升沿检测,那么当检测到上升沿时,定时器会把计数器 CNT 的值锁存到相应的捕获/比较寄存器 TIMx_CCRy 里,y=1~4。然后我们再设置边沿检测为下降沿检测,当检测到下降沿时,定时器会把计数器 CNT 的值再次锁存到相应的捕获/比较寄存器TIMx_CCRy 里。最后,我们将前后两次锁存的 CNT 的值相减,就可以算出高电平脉冲期间内计数器的计数个数,再根据定时器的计数频率就可以计算出这个高电平脉冲的时间。如果要测量的高电平脉宽时间长度超过定时器的溢出时间周期,就会发生溢出,这时候我们还需要做定时器溢出的额外处理。低电平脉冲捕获同理。

      上面的描述是第④部分输入捕获整体上的一个应用情况,下面我们来看第④部分的细节。 当需要测量的信号进入通道后,需要经过哪些“关卡”?我们用图 21.1.7 给大家讲解。

图 21.1.7 是图 21.1.1 第④部分通道 1 的“放大版”,这里是以通道 1 输入捕获为例进行介绍,其他通道同理。 待测量信号到达 TIMx_CH1 后,那么这里我们把这个待测量信号用 TI1 表示,原因在讲解外部时钟模式 1 的时候说过,所谓“入乡随俗”。

  1. TI1 首先经过一个滤波器,由 ICF[3:0]位来设置滤波方式,也可以设置不使用滤波器。fDTS 由 TIMx_CR1 寄存器的 CKD 位设置。
  2. 接着经过边沿检测器,由 CC1P 位来设置检测的边沿,可以上升沿或者下降沿检测。CC1NP 是配置互补通道的边沿检测的,在高级定时器才有,通用定时器没有。
  3. 然后经过输入捕获映射选择器,由 CC1S[1:0]位来选择把 IC1 映射到 TI1、TI2 还是 TRC。 这里我们的待测量信号从通道 1 进来,所以选择 IC1 映射到 TI1 上即可。 紧接着经过输入捕获 1 预分频器,由 ICPS[1:0]位来设置预分频系数,范围:1、2、4、8。
  4. 最后需要把 CC1E 位置 1,使能输入捕获,IC1PS 就是分频后的捕获信号。这个信号将会到达图 21.1.1 的第⑤部分。

下面我们接着看图 21.1.1 的第⑤部分的“放大版”,如下图所示:

 图 21.1.8 中,灰色阴影部分是输出比较功能部分,讲到第⑥部分输出比较的时候再介绍。 左边没有阴影部分就是输入捕获功能部分了。

       首先看到捕获/比较预装载寄存器,我们以通道 1 为例,那么它就是 CCR1 寄存器,通道 2、 通道 3、通道 4 就分别对应 CCR2、CCR3、CCR4。在图 21.1.1 中就可以看到 CCR1~4 是有影子寄存器的,所以这里就可以看到图 21.1.8 中有捕获/比较影子寄存器,该寄存器不可直接访问。

        图 21.1.8 左下角的 CC1G 位可以产生软件捕获事件,那么硬件捕获事件如何产生的?这里 我们还是以通道 1 输入为例,CC1S[1:0] = 01,即 IC1 映射到 TI1 上;CC1E 位置 1,使能输入 捕获;比如不滤波、不分频,ICF[3:0] = 00,ICPS[1:0] = 00;比如检测上升沿,CC1P 位置 0; 接着就是等待测量信号的上升沿到来。当上升沿到来时,IC1PS 信号就会触发输入捕获事件发生,计数器的值就会被锁存到捕获/比较影子寄存器里。当 CCR1 寄存器没有被进行读操作的时 候,捕获/比较影子寄存器里的值就会锁存到 CCR1 寄存器中,那么程序员就可以读取 CCR1 寄存器,得到计数器的计数值。检测下降沿同理。

 

2.5 输入捕获和输出比较公共部分

    该部分需要结合第④部分或者第⑥部分共同完成相应功能

2.6 输出比较(重要)

        图21.1.1.1中的第⑥部分是输出比较,一般应用是要和第⑤部分一起完成定时器输出功能。 TIMx_CH1~ TIMx_CH4 表示定时器的 4 个通道,这 4 个通道都是可以独立工作的。IO 端口通 过复用功能与这些通道相连。 下面我们按照输出信号产生过程顺序给大家介绍定时器如何实现输出功能的?首先看到第 ⑤部分的“放大版”图,如下图所示:

图 21.1.9 中,灰色阴影部分是输入捕获功能部分,前面已经讲过。这里我们看到右边没有 阴影部分就是输出比较功能部分了。下面以通道 1 输出比较功能为例给大家介绍定时器如何实 现输出功能的。

     首先程序员写 CCR1 寄存器,即写入比较值。这个比较值需要转移到对应的捕获/比较影子 寄存器后才会真正生效。什么条件下才能转移?图 21.1.9 中可以看到 compare_transfer 旁边的 与门,需要满足三个条件:CCR1 不在写入操作期间、CC1S[1:0] = 0 配置为输出、OC1PE 位置 0(或者 OC1PE 位置 1,并且需要发生更新事件,这个更新事件可以软件产生或者硬件产生)。 当 CCR1 寄存器的值转移到其影子寄存器后,新的值就会和计数器的值进行比较,它们的比较结果将会通过第⑥部分影响定时器的输出。

下面来看看第⑥部分通道 1 的“放大版”,如下图所示

上图中,可以看到输出模式控制器,由 OC1M[2:0]位配置输出比较模式,F4 系 列有 8 种输出比较模式之多。oc1ref 是输出参考信号,高电平有效,为高电平时称之为有效电平,为低电平时称之为无效电平。它的高低电平受到三个方面的影响:OC1M[3:0]位配置的输出比较模式、第⑤部分比较 器的比较结果、还有就是 OC1CE 位配置的 ETRF 信号。ETRF 信号可以将 oc1ref 电平强制清 零,该信号来自 IO 外部。 一般来说,当计数器的值和捕获/比较寄存器的值相等时,输出参考信号 oc1ref 的极性就会 根据我们选择的输出比较模式而改变。如果开启了比较中断,还会发生比较中断。 CC1P 位用于选择通道输出极性。 CC1E 位置 1 使能通道输出。 OC1 信号就会从 TIMx_CH1 输出到 IO 端口,再到 IO 外部。

输出比较可以通过比较CNT与CCR寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形。

       至此,我们的本次的学习就结束了。相信对基本定时器有了深入的理解,这一节我们就讲解到这里,希望能对大家的开发有帮助。 如有兴趣,感谢点赞、关注、收藏,若有不正地方,还请各位大佬多多指教!

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

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

相关文章

Opencv学习项目5——pyzbar,numpy

上一次我们使用pyzbar进行解码二维码并将其内容显示在图像上,使用的是rect barcode.rect来获取图像的坐标,这次我们使用另一种方法来获取坐标进行画框。 Numpy介绍 NumPy 是一个用于科学计算的开源 Python 库,提供了对大量数值数据进行高效操…

【泛微系统】解决启动非标功能时提示客户ID不一致的问题

解决启动非标时提示CID不一致的问题 泛微OA系统是一个非常丰富的系统,我们在日常工作中会经常遇到很多业务需求,我们会用到很多功能来承载这些需求的实现;OA系统里有标准功能,也有非标准的功能;对于非标准的功能需要打非标补丁包; 有些同学在个人学习系统的过程中会安装本…

STM32项目分享:家庭环境监测系统

目录 一、前言 二、项目简介 1.功能详解 2.主要器件 三、原理图设计 四、PCB硬件设计 1.PCB图 2.PCB板打样焊接图 五、程序设计 六、实验效果 七、资料内容 项目分享 一、前言 项目成品图片: 哔哩哔哩视频链接: https://www.bilibili.…

【性能优化】表分桶实践最佳案例

分桶背景 随着企业的数据不断增长,数据的分布和访问模式变得越来越复杂。我们前面介绍了如何通过对表进行分区来提高查询效率,但对于某些特定的查询模式,特别是需要频繁地进行数据联接查或取样的场景,仍然可能面临性能瓶颈。此外…

VisualBox 虚拟机 Ubunut 18.04 在大显示器上黑屏的问题

在小屏幕上显示没有问题,但是移动到大显示器上就黑屏了,并且不能铺满,如下所示 如果我希望它铺满整个屏幕,如何解决呢? 下面是解决方法: 虚拟机底部这个按钮,右键 产生菜单,按这个选…

基于STM8系列单片机驱动74HC595驱动两个3位一体的数码管

1)单片机/ARM硬件设计小知识,分享给将要学习或者正在学习单片机/ARM开发的同学。 2)内容属于原创,若转载,请说明出处。 3)提供相关问题有偿答疑和支持。 为了节省单片机MCU的IO口资源驱动6个数码管&…

mongodb嵌套聚合

db.order.aggregate([{$match: {// 下单时间"createTime": {$gte: ISODate("2024-05-01T00:00:00Z"),$lte: ISODate("2024-05-31T23:59:59Z")}// 商品名称,"goods.productName": /美国皓齿/,//订单状态 2:待发货 3:已发货 4:交易成功…

强化学习中的自我博弈(self-play)

自我博弈(Self-Play)[1]是应用于智能体于智能体之间处于对抗关系的训练方法,这里的对抗关系指的是一方的奖励上升必然导致另一方的奖励下降。通过轮流训练双方的智能体就能使得双方的策略模型的性能得到显著提升,使得整个对抗系统…

13.1.k8s集群的七层代理-ingress资源(进阶知识)

目录 一、ingress概述 1.前言 2.问题 3.ingress资源 二、ingress-nginx是什么 三、ingress-nginx 实现原理 四、部署ingress-nginx 1.获取部署文件 ingress-nginx.yaml 2.部署ingress-nginx 3.检查部署是否成功 五、编写使用Ingress样例代码 1.Ingress资源对象yaml文…

【滚动哈希 二分查找】1044. 最长重复子串

本文涉及知识点 滚动哈希 二分查找算法合集 LeetCode 1044. 最长重复子串 给你一个字符串 s ,考虑其所有 重复子串 :即 s 的(连续)子串,在 s 中出现 2 次或更多次。这些出现之间可能存在重叠。 返回 任意一个 可能具…

深入理解前端缓存

前端缓存是所有前端程序员在成长历程中必须要面临的问题,它会让我们的项目得到非常大的优化提升,同样也会带来一些其它方面的困扰。大部分前端程序员也了解一些缓存相关的知识,比如:强缓存、协商缓存、cookie等,但是我…

攻防世界-5-1

下载文件发现是一个没有尾缀的文件,扔winhex,emmmm还是没看出来 搜了一圈,发现用xortool 得到key之后,跑一下脚本 得到flag: wdflag{You Are Very Smart}

基于uni-app和图鸟UI的智慧农业综合管控平台小程序技术实践

摘要: 随着信息化技术的飞速发展,智慧农业已成为推动农业现代化、提升农业生产效率的重要手段。本文介绍了一款基于uni-app框架和图鸟UI设计的智慧农业综合管控平台小程序,该平台整合了传感器控制、农业数据监测、设施管控、农业新闻传播以及…

【面向就业的Linux基础】从入门到熟练,探索Linux的秘密(三)-shell语法

主要通过讲解shell中的一些基本语法,可以当作日常的笔记来进行查询和记忆。 文章目录 前言 一、shell 二、shell语法 1.运行方式 2.注释 3.变量 4.默认变量 5.数组 总结 前言 主要通过讲解shell中的一些基本语法,可以当作日常的笔记来进行查询和记忆。…

Python | Leetcode Python题解之第172题阶乘后的零

题目: 题解: class Solution:def trailingZeroes(self, n: int) -> int:ans 0while n:n // 5ans nreturn ans

android倒计时封装(活动进入后台,倒计时依然能正常计时)

public class TimeUtils { /倒计时时长 单位:秒/ public static int COUNT 20*60; /当前做/ private static int CURR_COUNT 0; /预计结束的时间/ private static long TIME_END 0; /计时器/ private static Timer countdownTimer; /显示倒计时的textVi…

FLASH闪存

一、FLASH简介 1、FLASH简介 (1)STM32F1系列的FLASH包含程序存储器、系统存储器和选项字节三个部分,通过闪存存储器接口(外设)可以对程序存储器和选项字节进行擦除和编程 (2)读写FLASH的用途…

postman国内外竞争者及使用详解分析

一、postman简介 Postman 是一款广泛使用的 API 开发和测试工具,适用于开发人员和测试人员。它提供了一个直观的界面,用于发送 HTTP 请求、查看响应、创建和管理 API 测试用例,以及自动化 API 测试工作流程。以下是 Postman 的主要功能和特点…

ShareX,屏幕截图、屏幕录制和文件共享,还提供了丰富的高级功能和自定义选项

ShareX是一个免费开源的Windows应用程序,用于屏幕截图、屏幕录制和文件共享。它不仅支持基本的屏幕截图功能,还提供了丰富的高级功能和自定义选项,使其成为提高工作效率和截图体验的利器。以下是ShareX v16.1.0便携版的主要功能和特色&#x…

蓝桥杯 经典算法题 求解完全背包问题

题目: 题解: 和01背包基本完全一样。小局部最优的策略也是一样:是否选当前局部的最后一项。唯一的不同点在于物品是无线的导致在表示选择当前物品的状态写法发生了改变:由dp[i-1][j-w[i]]变为了dp[i][j-w[i]]因为这样能够表示最后…