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

STM32 定时器介绍--通用、高级定时器

目录

高级定时器

1.功能框图

1-时钟源

2-时基单元

3-输入捕获

4-输出比较

2.输入捕获的应用

3.输出比较的应用

4.初始化结构体

1-时基初始化结构体

2-输出比较结构体

3-PWM信号 周期和占空比的计算--以通用定时器为例

4-输入捕获结构体

5-断路和死区初始化结构体

5.程序设计

1-高级定时器定时功能设计

2-通用定时器PWM输出功能设计


前面文章中说过,STM32F103系列单片机中除了有系统定时器SysTick外,还有2个高级定时器TIM1和TIM8,4个通用定时器TIM2/3/4/5,2个基本定时器TIM6和TIM7。通用定时器的功能在高级定时器中都存在,不做赘述,这篇文章主要介绍STM32中的高级定时器。对于系统定时器SysTick和基本定时器的介绍分别如下:

STM32 系统定时器--SysTick_systick中断_Haohao fighting!的博客-CSDN博客

STM32 定时器介绍--基本定时器_Haohao fighting!的博客-CSDN博客

高级定时器简介

计数器16bit,可从上/下/两边计数,上:从0计数到用户配置的值;下:从用户配置的值倒数到0;两边:从0计数到用户配置的值,再从用户配置的值倒数到0。TIM1和TIM8,时基单元里还有一个重复计数器RCR,独有。

相比基本定时器,通用定时器和高级定时器有4个GPIO,其中通道1~3还有互补输出GPIO,加起来共有7个。

时钟来自PCLK2,为72M(所有的定时器都是72M),可实现1~65536分频。

高级定时器

1.功能框图

1-时钟源  2-控制器 3-时基 4-输入捕获 5-输出比较 6-断路功能

1-时钟源

内部时钟源

时钟源有四种模式,我们最常用的就是CK_INT:来自RCC的TIMx_CLK

高级定时器挂载到APB2总线上,APB2的预分频系数是1,所以不变,还是72M。

外部时钟模式1—外部的GPIO Tix(x=1 2 3 4)和外部时钟模式2—外部的GPIO ETR不常用。外部时钟模式1可以从外部的引脚(功能框图左侧的TIMx_CH1、2、3、4引脚)给计数器提供时钟;外部时钟模式2可以从外部的特殊引脚(功能框图左侧的TIMx_ETR引脚)给计数器提供时钟。

这些引脚对应哪些具体引脚,参考下图

外部时钟1:

虽然有4个引脚,但不能同时使用两个,只能使用1个。

①时钟信号输入引脚 外部的GPIO Tix,对应:TIMx_CH1/2/3/4,TIM_CCMRx寄存器的位CCxS[1:0]配置,其中CCMR1控制TI1/2,CCMR2控制TI3/4。

②滤波器 如果来自外部的时钟信号的频率过高或者混杂有高频干扰信号的话,我们就需要使用滤波器对ETRP信号重新采样,来达到降频或者去除高频干扰的目的,由TIMx_CCMRx寄存器的位ICxF[3:0]配置。

③边沿检测 边沿检测的信号来自于滤波器的输出,在成为触发信号之前,需要进行边沿检测,决定是上升沿有效还是下降沿有效。由TIMx_CCER寄存器的位CCxP和CCxNP 配置。

④触发选择 当使用外部时钟模式1时,触发源有两个,一个是滤波后的定时器输入1(TI1FP1)和滤波后的定时器输入2(TI2FP2)。由TIMx_SMCR寄存器的位TS[2:0]配置。

⑤从模式选择 选定了触发源信号后,最后我们需把信号连接到TRGI引脚,让触发信号成为外部时钟模式1的输入,最终等于 CK_PSC,然后驱动计数器CNT计数。具体的配置TIMx_SMCR寄存器的位SMS[2:0]为 000 即可选择外部时钟模式1。

经过上面的5个步骤之后, 最后我们只需使能计数器开始计数,外部时钟模式1的配置就算完成。使能计数器由TIMx_CR1寄存器的位CEN 配置。

外部时钟2

①时钟信号输入引脚 当使用外部时钟模式2的时候,时钟信号来自于定时器的特定输入通道TIMx_ETR,只有1个。

②外部触发极性 来自ETR引脚输入的信号可以选择为上升沿或者下降沿有效。具体的由TIMx_SMCR寄存器的位ETP 配置。

③外部触发预分频器 由于ETRP的信号的频率不能超过TIMx_CLK(180M)的 1/4,当触发信号的频率很高的情况下,就必须使用分频器来降频。具体的由TIMx_SMCR寄存器的位ETPS[1:0]配置。

④滤波器 如果ETRP的信号的频率过高或者混杂有高频干扰信号的,需要使用滤波器对ETRP信号重新采样,来达到降频或者去除高频干扰的目的。具体的由TIMx_SMCR寄存器的位ETF[3:0]配置,其中的fDTS是由内部时钟CK_INT分频得到,具体的由TIMx_CR1寄存器的位CKD[1:0]配置。

⑤从模式选择 经过滤波器滤波的信号连接到ETRF引脚后,触发信号成为外部时钟模式2的输入,最终等于CK_PSC,然后驱动计数器 CNT 计数。具体的配置TIMx_SMCR寄存器的位ECE为 1即可选择外部时钟模式2。

经过上面的5个步骤之后,最后我们只需使能计数器开始计数,外部时钟模式2的配置就算完成。使能计数器由TIMx_CR1寄存器的位CEN配置。

2-时基单元

预分频器 PSC

16位,由预分频器(TIMx_PSC)控制。有一个输入时钟CK_PSC和一个输出时钟CK_CNT。输入时钟CK_PSC就是上面时钟源的输出,输出CK_CNT则用来驱动计数器CNT计数。通过设置预分频器PSC的值可以得到不同的CK_CNT。计数器的时钟频率(CK_CNT)=fck_psc/( PSC[15:0]+1)

计数器CNT

16位,由计数器(TIMx_CNT)控制。

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

递减计数模式下,计数器从自动重载寄存器ARR值开始计数,每来一个CK CNT脉冲计数器就减1,直到计数器值为0,然后计数器又从自动重载寄存器ARR值开始递减计数并生成计数器下溢事件,计数器总是如此循环计数。如果禁用重复计数器,在计数器生成下溢事件就马上生成更新事件:如果使能重复计数器,每生成一次下溢事件重复计数器内容就减1,直到重复计数器内容为0时才会生成更新事件。

中心对齐模式下,计数器从0开始递增计数,直到计数值等于(ARR-1)值生成计数器上溢事件,然后从ARR值开始递减计数直到1生成计数器下溢事件。然后又从0开始计数,如此循环。每次发生计数器上溢和下溢事件都会生成更新事件。

自动重装载寄存器ARR

16位,由自动重装载寄存器(TIMx_ARR)控制,与前面基本定时器的ARR基本相同。

重复计数器RCR

8位。由重复计数寄存器(TIMx_RCR)控制。基本/通用定时器,发生上/下溢事件时,直接生成更新事件。高级控制定时器多出了重复计数器。定时器发生上溢、下溢事件时,递减重复计数器的值。当重复计数器为0时,才会生成更新事件。发生N+1个上溢、下溢事件(N为RCR的值)时,产生更新事件。

3-输入捕获

输入捕获可以对输入的信号的上升沿,下降沿或者双边沿进行捕获,常用的有测量输入信号的脉宽和测量PWM输入信号的频率和占空比这两种。

 

输入捕获的大概的原理就是,当捕获到信号的跳变沿(上升或者下降沿)的时候,把计数器CNT的值锁存到捕获寄存器CCR中,把前后两次捕获到的CCR寄存器中的值相减,就可以算出脉宽或者频率。如果捕获的脉宽的时间长度超过你的捕获定时器的周期,就会发生溢出,这个我们需要做额外的处理。

①输入通道 当使用需要被测量的信号从定时器的外部引脚 TIMx_CH1/2/3/4进入,通常叫TI1/2/3/4,我们称被测量的信号为Tix。

②输入滤波和边沿检测 当输入的信号存在高频干扰的时候,我们需要对输入信号进行滤波,即进行重新采样,根据采样定律,采样的频率必须大于等于两倍的输入信号。比如输入的信号为1M,又存在高频的信号干扰,那么此时就很有必要进行滤波,我们可以设置采样频率为2M,这样可以在保证采样到有效信号的基础上把高于2M的高频干扰信号过滤掉。

    滤波器的配置由CR1寄存器的位CKD[1:O]和CCMR1/2的位ICxF[3:0]控制。从ICxF位的描述可知,采样频率fSAMPLE可以由fCK INT和fDTs分频后的时钟提供,其中是fCK_INT内部时钟,Ds是fCK INT经过分频后得到的频率,分频因子由CKD[1:O]决定,可以是不分频,2分频或者是4分频。

边沿检测器用来设置信号在捕获的时候是什么边沿有效,可以是上升沿,下降沿,或者是双边沿,具体的由CCER寄存器的位CCxP和CCxNP决定。

③捕获通道 捕获通道就是图中的IC1/2/3/4,每个捕获通道都有相对应的捕获寄存器CCR1/2/3/4,当发生捕获的时候,计数器CNT的值就会被锁存到捕获寄存器中。

这里我们要搞清楚输入通道和捕获通道的区别,输入通道是用来输入信号的,捕获通道是用来捕获输入信号的通道,一个输入通道的信号可以同时输入给两个捕获通道。比如输入通道TI1的信号经过滤波边沿检测器之后的TIIFP1和TIIFP2可以进入到捕获通道IC1和IC2,其实这就是我们后面要讲的PWM输入捕获,只有一路输入信号(TI1)却占用了两个捕获通道(IC1和IC2),一路测量周期,一路测量占空比。PWM信号输入只能通道12有这种功能。PWM信号可以分为TIxFP1TIxFP2,分别和两个捕获寄存器联系起来,要选择一路作为触发从模式,哪一路触发从模式,哪一路就是测量周期;另外一路测量占空比。TIxFP1触发从模式,测量周期称为直连;TIxFP2触发从模式,测量周期称为非直连。

当只需要测量输入信号的脉宽时候,用一个捕获通道即可。输入通道和捕获通道的映射关系具体由寄存器CCMRx的位CCxS[1:0]配置。

④预分频器 一般不分频。

⑤捕获寄存器 经过预分频器的信号ICxPS是最终被捕获的信号,当发生捕获时(第一次),计数器CNT的值会被锁存到捕获寄存器CCR中,还会产生CCxI中断,相应的中断位CCxIF(在SR寄存器中)会被置位,通过软件或者读取CCR中的值可以将CCxF清0。如果发生第二次捕获(即重复捕获:CCR寄存器中已捕获到计数器值且CCxF标志已置1),则捕获溢出标志位CCxOF(在SR寄存器中)会被置位,CCxOF只能通过软件清零。

4-输出比较

例如:输出一个PWM波信号。

CCR寄存器用于输出信号叫做比较寄存器。计数器从0开始计数,计数到CCR的时候输出高电平或者低电平;从CCR计数到ARR输出低电平或者高电平。然后重新开始计数一轮。占空比就与比较寄存器CCR相关。信号在输出通道输出之前,还要经过一个寄存器的控制:刹车和死区寄存器(TIMx_BDTR)。

什么是死区时间?

MOTORA是用来驱动电机的,由上下两个MOS管来控制,

一路(一个MOS管)高电平转换成低电平之后,延迟一段时间之后另一路(另一个MOS管)才由低电平转换成高电平;反之亦然。这样就不会同时导通,从而避免功率元件烧毁;延迟的那段时间称为死区时间,死区时间控制在通常的单片机所配备的PWM中都有这样的功能。

死区时间由刹车和死区寄存器(TIMx_BDTR)的UTG[7:0]位控制。

其中的Tdts跟内部时钟相关,由TIM1和TIM8控制寄存器 1(TIMx_CR1)的CKD[1:0]位控制。

在刹车和死区寄存器(TIMx_BDTR)中:

2.输入捕获的应用

一是测量脉宽和频率

上升沿捕获到一次之后进入中断,在中断中改变捕获的边沿,改成下降沿捕获;捕获到下降沿之后,进入中断再次改变为上升沿捕获……

二是PWM输入模式

只能通过通道12进行捕获,3、4通道不能捕获。

3.输出比较的应用

1-输出比较模式总共有 8 种,常用的是PWM模式。

2-由寄存器CCMRx的位OCxM[2:0]配置。

PWM 输出就是对外输出脉宽(即占空比)可调的方波信号,信号频率由自动重装寄存器 ARR 的值决定,占空比由比较寄存器 CCR 的值决定。

PWM的输出模式:

有效:高电平;无效:低电平

边沿对齐与中心对齐的不同

最常用的是边沿对齐

1-根据CNT的计数方向,PWM波形分成边沿对齐和中心对齐两种。边沿对齐主要用于直流电机,中心对齐主要用于交流电机。

2-边沿对齐时,CNT只工作在递增或者递减。

3-中心对齐时,CNT工作在递增和递减。

4.初始化结构体

1-时基初始化结构体

TIM_TimeBaseInitTypeDef,也就是前面功能框图里面的时基单元。

typedef struct 
{uint16_t TIM_Prescaler;         // 预分频器uint16_t TIM_CounterMode;       // 计数模式uint32_t TIM_Period;            // 定时器周期uint16_t TIM_ClockDivision;     // 时钟分频uint8_t TIM_RepetitionCounter;  // 重复计算器
} TIM_TimeBaseInitTypeDef;

TIM_Prescaler:定时器预分频器设置,时钟源经该预分频器才是定时器计数时钟CK_CNT,它设定 PSC 寄存器的值。计算公式为: 计数器时钟频率 (fCK_CNT) 等于fCK_PSC / (PSC[15:0] + 1)【对应TIMx_PSC寄存器】,可实现 1 至 65536 分频。

TIM_CounterMode:定时器计数方式,可设置为向上计数、向下计数以及中心对齐。高级控制定时器允许选择任意一种。基本定时器只能选择向上计数,配置基本定时器时不用配置此成员。对应TIM_CR1寄存器的DIR位。

TIM_Period:定时器周期,实际就是设定自动重载寄存器ARR的值,ARR为要装载到实际自动重载寄存器(即影子寄存器) 的值, 可设置范围为0至65535。(具体介绍看基本定时器)

TIM_ClockDivision:时钟分频,设置定时器时钟 CK_INT 频率与死区发生器以及数字滤波器采样时钟频率分频比。可以选择1、2、4 分频。

TIM_RepetitionCounter:重复计数器,只有 8 位,只存在于高级定时器。

2-输出比较结构体

TIM_OCInitTypeDef

typedef struct 
{uint16_t TIM_OCMode;            // 比较输出模式uint16_t TIM_OutputState;       // 比较输出使能uint16_t TIM_OutputNState;      // 比较互补输出使能uint32_t TIM_Pulse;             // 脉冲宽度uint16_t TIM_OCPolarity;        // 输出极性uint16_t TIM_OCNPolarity;       // 互补输出极性uint16_t TIM_OCIdleState;       // 空闲状态下比较输出状态uint16_t TIM_OCNIdleState;      // 空闲状态下比较互补输出状态
} TIM_OCInitTypeDef;

TIM_OCMode:比较输出模式选择,总共有八种,常用的为 PWM1/PWM2。它设定CCMRx(x控制1或2通道)寄存器OCxM[2:0]位的值。

TIM_OutputState:比较输出使能,决定最终的输出比较信号OCx 是否通过外部引脚输出。它设定TIMx_CCER寄存器CCxE位的值。也就是说启用之后可以产生PWM波信号。

TIM_OutputNState:比较互补输出使能,决定 OCx 的互补信号 OCxN 是否通过外部引脚输出。它设定 CCER 寄存器 CCxNE 位的值。

TIM_Pulse:比较输出脉冲宽度,实际设定比较寄存器 CCR 的值,决定脉冲宽度。可设置范围为 0 至 65535。

TIM_OCPolarity:比较输出极性,可选 OCx 为高电平有效或低电平有效。它决定着定时器通道有效电平。它设定 CCER 寄存器的 CCxP 位的值。也就是正周期的电平是高/低。

TIM_OCNPolarity:比较互补输出极性,可选OCxN 为高电平有效或低电平有效。它设定 TIMx_CCER 寄存器的 CCxNP 位的值。

当我们需要输出PWM波时(小车电机驱动),就需要配置时基结构体和输出比较结构体即可,而输出比较结构体只需要配置三个加粗的成员即可。

3-PWM信号 周期和占空比的计算--以通用定时器为例

这一部分在时基结构体初始化中配置

ARR :自动重装载寄存器的值

CLK_cnt:计数器的时钟(驱动CNT计数器的时钟周期),等于 Fck_int / (psc+1) = 72M/(psc+1)  psc = GENERAL_TIM_Prescaler 宏定义的值为 71。CLK_cnt = 1 MHZ

PWM 信号的周期 T = ARR * (1/CLK_cnt) = ARR*(PSC+1) / 72M。这里的ARR代表的是自动重装载寄存器的值,累计TIM_Period+1,TIM_Period在宏定义中为9,也就是9+1=10。周期 = 10 * (1 / 1 MHZ) = 10 us

占空比 P = CCR/ARR = CCR/(TIM_Period+1)  TIM_Period就是宏定义中 GENERAL_TIM_Period 值为9,也就是说,占空比为 = CCR / 10


详细例程如下,这是一个定时器3,四路PWM通道不同输出值的配置程序,主要是看一下PWM周期和占空比是如何配置的:

.c文件内容,定时器3配置函数:

static void GENERAL_TIM3_Mode_Config(void)
{// 开启定时器时钟,即内部时钟CK_INT=72MGENERAL_TIM3_APBxClock_FUN(GENERAL_TIM3_CLK,ENABLE);/*--------------------时基结构体初始化-------------------------*/// 配置周期,这里配置为100KTIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;// 自动重装载寄存器的值ARR,累计TIM_Period+1个频率后产生一个更新或者中断  	TIM_Period+1  9+1=10TIM_TimeBaseStructure.TIM_Period=GENERAL_TIM3_Period;	// 驱动CNT计数器的时钟 = Fck_int/(psc+1)TIM_TimeBaseStructure.TIM_Prescaler= GENERAL_TIM3_Prescaler;	// 时钟分频因子 ,配置死区时间时需要用到TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;		// 计数器计数模式,设置为向上计数TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;		// 重复计数器的值,没用到不用管TIM_TimeBaseStructure.TIM_RepetitionCounter=0;	// 初始化定时器TIM_TimeBaseInit(GENERAL_TIM3, &TIM_TimeBaseStructure);/*--------------------输出比较结构体初始化-------------------*/	 // 需要 PWM波 输出的就需要配置此结构体// 占空比配置uint16_t CCR1_Val = 9;  // 占空比 = CCR1_Val / (GENERAL_TIM_Period + 1)uint16_t CCR2_Val = 6;uint16_t CCR3_Val = 3;uint16_t CCR4_Val = 1;TIM_OCInitTypeDef  TIM_OCInitStructure;// 配置为PWM模式1TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;  //比较输出模式选择.常用的为 PWM1/PWM2// 输出使能TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;  //比较输出使能,决定最终的输出比较信号OCx是否通过外部引脚输出,也就是说启用之后可以产生PWM波信号// 输出通道电平极性配置	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;  //比较输出极性,可选 OCx 为高电平有效或低电平有效。它决定着定时器通道有效电平。也就是正周期的电平是高/低// 输出比较通道 1TIM_OCInitStructure.TIM_Pulse = CCR1_Val;TIM_OC1Init(GENERAL_TIM3, &TIM_OCInitStructure);TIM_OC1PreloadConfig(GENERAL_TIM3, TIM_OCPreload_Enable);// 输出比较通道 2TIM_OCInitStructure.TIM_Pulse = CCR2_Val;TIM_OC2Init(GENERAL_TIM3, &TIM_OCInitStructure);TIM_OC2PreloadConfig(GENERAL_TIM3, TIM_OCPreload_Enable);// 输出比较通道 3TIM_OCInitStructure.TIM_Pulse = CCR3_Val;TIM_OC3Init(GENERAL_TIM3, &TIM_OCInitStructure);TIM_OC3PreloadConfig(GENERAL_TIM3, TIM_OCPreload_Enable);// 输出比较通道 4TIM_OCInitStructure.TIM_Pulse = CCR4_Val;TIM_OC4Init(GENERAL_TIM3, &TIM_OCInitStructure);TIM_OC4PreloadConfig(GENERAL_TIM3, TIM_OCPreload_Enable);// 使能计数器TIM_Cmd(GENERAL_TIM3, ENABLE);
}

.h文件内容,一些宏定义:

/************************************通用定时器TIM参数定义,只限TIM2、3、4、5********************************/
// 当使用不同的定时器的时候,对应的GPIO是不一样的,这点要注意
/******************************* TIM3 ***************************************/#define            GENERAL_TIM3                   TIM3
#define            GENERAL_TIM3_APBxClock_FUN     RCC_APB1PeriphClockCmd
#define            GENERAL_TIM3_CLK               RCC_APB1Periph_TIM3
#define            GENERAL_TIM3_Period            9
#define            GENERAL_TIM3_Prescaler         71
// TIM3 输出比较通道1
#define            GENERAL_TIM3_CH1_GPIO_CLK      RCC_APB2Periph_GPIOA
#define            GENERAL_TIM3_CH1_PORT          GPIOA
#define            GENERAL_TIM3_CH1_PIN           GPIO_Pin_6// TIM3 输出比较通道2
#define            GENERAL_TIM3_CH2_GPIO_CLK      RCC_APB2Periph_GPIOA
#define            GENERAL_TIM3_CH2_PORT          GPIOA
#define            GENERAL_TIM3_CH2_PIN           GPIO_Pin_7// TIM3 输出比较通道3
#define            GENERAL_TIM3_CH3_GPIO_CLK      RCC_APB2Periph_GPIOB
#define            GENERAL_TIM3_CH3_PORT          GPIOB
#define            GENERAL_TIM3_CH3_PIN           GPIO_Pin_0// TIM3 输出比较通道4
#define            GENERAL_TIM3_CH4_GPIO_CLK      RCC_APB2Periph_GPIOB
#define            GENERAL_TIM3_CH4_PORT          GPIOB
#define            GENERAL_TIM3_CH4_PIN           GPIO_Pin_1

整个工程的详细代码在文末有下载链接。参照  5.2-通用定时器PWM输出功能设计

4-输入捕获结构体

typedef struct 
{uint16_t TIM_Channel; // 输入通道选择uint16_t TIM_ICPolarity; // 输入捕获触发选择uint16_t TIM_ICSelection; // 输入捕获选择uint16_t TIM_ICPrescaler; // 输入捕获预分频器uint16_t TIM_ICFilter; // 输入捕获滤波器
} TIM_ICInitTypeDef;

TIM_Channel:捕获通道ICx选择,可选 TIM_Channel_1、 TIM_Channel_2、TIM_Channel_3 或 TIM_Channel_4 四个通道。它设定 CCMRx 寄存器 CCxS 位 的值。

TIM_ICPolarity:输入捕获边沿触发选择,可选上升沿触发、下降沿触发或边沿跳变触发。它设定 CCER 寄存器 CCxP 位和 CCxNP 位的值。

TIM_ICSelection:输入通道选择,捕获通道 ICx 的信号可来自三个输入通道,分别为:TIM_ICSelection_DirectTI、TIM_ICSelection_IndirectTI 或 TIM_ICSelection_TRC。它设定 CCRMx 寄存器的 CCxS[1:0]位的值。

TIM_ICPrescaler:输入捕获通道预分频器,可设置 1、 2、 4、 8 分频,它设定 CCMRx寄存器的 ICxPSC[1:0]位的值。如果需要捕获输入信号的每个有效边沿,则设置 1 分频即可。

TIM_ICFilter:输入捕获滤波器设置,可选设置 0x0 至 0x0F。它设定 CCMRx 寄存器ICxF[3:0]位的值。一般我们不使用滤波器,即设置为 0。

5-断路和死区初始化结构体

 TIM_BDTRInitTypeDef

断路和死区结构体 TIM_BDTRInitTypeDef 用于断路和死区参数的设置,属于高级定时器专用,用 于配置断路时通道输出状态,以及死区时间。它与 TIM_BDTRConfig 函数配置使用完成参数配置。 这个结构体的成员只对应寄存器断路和死区寄存器:TIMx_BDTR。 

typedef struct 
{uint16_t TIM_OSSRState;         // 运行模式下的关闭状态选择uint16_t TIM_OSSIState;         // 空闲模式下的关闭状态选择uint16_t TIM_LOCKLevel;         // 锁定配置uint16_t TIM_DeadTime;          // 死区时间uint16_t TIM_Break;             // 断路输入使能控制uint16_t TIM_BreakPolarity;     // 断路输入极性uint16_t TIM_AutomaticOutput;   // 自动输出使能
} TIM_BDTRInitTypeDef;

 (1) TIM_OSSRState:运行模式下的关闭状态选择,它设定 BDTR 寄存器 OSSR 位的值。

 (2) TIM_OSSIState:空闲模式下的关闭状态选择,它设定 BDTR 寄存器 OSSI 位的值。

 (3) TIM_LOCKLevel:锁定级别配置,BDTR 寄存器 LOCK[1:0] 位的值。

 (4) TIM_DeadTime:配置死区发生器,定义死区持续时间,可选设置范围为 0x0 至 0xFF。它设定 BDTR 寄存器 DTG[7:0] 位的值。

 (5) TIM_Break:断路输入功能选择,可选使能或禁止。它设定 BDTR 寄存器 BKE 位的值。

 (6) TIM_BreakPolarity:断路输入通道 BRK 极性选择,可选高电平有效或低电平有效。它设定 BDTR 寄存器 BKP 位的值。

 (7) TIM_AutomaticOutput:自动输出使能,可选使能或禁止,它设定 BDTR 寄存器 AOE 位的值。

这个在我平常做的时候用不到这个功能,就不做相应配置了。

5.程序设计

1-高级定时器定时功能设计

功能设计:使用高级定时器实现双色LED灯间隔1秒完成红绿颜色切换(高级定时器的定时功能)

配置过程:

首先进行定时器和中断优先级的配置:

#include "bsp_AdvanceTim.h" // 中断优先级配置
static void ADVANCE_TIM_NVIC_Config(void)
{NVIC_InitTypeDef NVIC_InitStructure; // 设置中断组为0NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);		// 设置中断来源NVIC_InitStructure.NVIC_IRQChannel = ADVANCE_TIM_IRQ ;	// 设置主优先级为 0NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;	 // 设置抢占优先级为3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);
}///*
// * 注意:TIM_TimeBaseInitTypeDef结构体里面有5个成员,TIM6和TIM7的寄存器里面只有
// * TIM_Prescaler和TIM_Period,所以使用TIM6和TIM7的时候只需初始化这两个成员即可,
// * 另外三个成员是通用定时器和高级定时器才有.
// *-----------------------------------------------------------------------------
// *typedef struct
// *{ TIM_Prescaler            都有
// *	TIM_CounterMode			     TIMx,x[6,7]没有,其他都有
// *  TIM_Period               都有
// *  TIM_ClockDivision        TIMx,x[6,7]没有,其他都有
// *  TIM_RepetitionCounter    TIMx,x[1,8,15,16,17]才有
// *}TIM_TimeBaseInitTypeDef; 
// *-----------------------------------------------------------------------------
// */
static void ADVANCE_TIM_Mode_Config(void)
{TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;		// 开启定时器时钟,即内部时钟CK_INT=72MADVANCE_TIM_APBxClock_FUN(ADVANCE_TIM_CLK, ENABLE);	// 自动重装载寄存器的值,累计TIM_Period+1个频率后产生一个更新或者中断TIM_TimeBaseStructure.TIM_Period=ADVANCE_TIM_Period;// 时钟预分频数TIM_TimeBaseStructure.TIM_Prescaler= ADVANCE_TIM_Prescaler;	// 时钟分频因子 ,没用到不用管TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;		// 计数器计数模式,设置为向上计数TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; 		// 重复计数器的值,没用到不用管TIM_TimeBaseStructure.TIM_RepetitionCounter=0;	// 初始化定时器TIM_TimeBaseInit(ADVANCE_TIM, &TIM_TimeBaseStructure);// 清除计数器中断标志位TIM_ClearFlag(ADVANCE_TIM, TIM_FLAG_Update);// 开启计数器中断TIM_ITConfig(ADVANCE_TIM,TIM_IT_Update,ENABLE);// 使能计数器TIM_Cmd(ADVANCE_TIM, ENABLE);
}void ADVANCE_TIM_Init(void)
{ADVANCE_TIM_NVIC_Config();ADVANCE_TIM_Mode_Config();		
}

关于高级定时器的一些宏定义:

#ifndef __BSP_ADVANCETIME_H
#define __BSP_ADVANCETIME_H#include "stm32f10x.h"/********************高级定时器TIM参数定义,只限TIM1、8************/
#define ADVANCE_TIM1 // 如果使用TIM8,注释掉这个宏即可#ifdef  ADVANCE_TIM1 // 使用高级定时器TIM1#define            ADVANCE_TIM                   TIM1
#define            ADVANCE_TIM_APBxClock_FUN     RCC_APB2PeriphClockCmd
#define            ADVANCE_TIM_CLK               RCC_APB2Periph_TIM1
#define            ADVANCE_TIM_Period            (1000-1)
#define            ADVANCE_TIM_Prescaler         71
#define            ADVANCE_TIM_IRQ               TIM1_UP_IRQn
#define            ADVANCE_TIM_IRQHandler        TIM1_UP_IRQHandler#else  // 使用高级定时器TIM8
#define            ADVANCE_TIM                   TIM8
#define            ADVANCE_TIM_APBxClock_FUN     RCC_APB2PeriphClockCmd
#define            ADVANCE_TIM_CLK               RCC_APB2Periph_TIM8
#define            ADVANCE_TIM_Period            (1000-1)
#define            ADVANCE_TIM_Prescaler         71
#define            ADVANCE_TIM_IRQ               TIM8_UP_IRQn
#define            ADVANCE_TIM_IRQHandler        TIM8_UP_IRQHandler#endif
/**************************函数声明********************************/void ADVANCE_TIM_Init(void);#endif	/* __BSP_ADVANCETIME_H */

高级定时器的中断函数:

void  ADVANCE_TIM_IRQHandler (void)
{if ( TIM_GetITStatus( ADVANCE_TIM, TIM_IT_Update) != RESET ) {	time++;TIM_ClearITPendingBit(ADVANCE_TIM , TIM_FLAG_Update);  		 }		 	
}

主函数程序:

int main(void)
{LED_GPIO_Config();//初始化函数ADVANCE_TIM_Init();while(1){if(time == 1000){	    GPIO_SetBits(LED1_GPIO_PORT,LED1_GPIO_PIN);GPIO_ResetBits(LED2_GPIO_PORT,LED2_GPIO_PIN);}else if(time == 2000){time=0;GPIO_ResetBits(LED1_GPIO_PORT,LED1_GPIO_PIN);GPIO_SetBits(LED2_GPIO_PORT,LED2_GPIO_PIN);}}
}

想要验证这个程序,需要一个双色LED灯,当然也可以用别的外设去替代。完整程序链接如下:

链接:https://pan.baidu.com/s/1ZVEE6FaTZV8grSiQIiQrWg 
提取码:ssun 
--来自百度网盘超级会员V1的分享

2-通用定时器PWM输出功能设计

功能设计:通过四个通用定时器2、3、4、5分别实现LED灯四级亮度等级变化(4个通道有不同的占空比,代表4个不同的亮度等级)。这个程序只是展示了通用定时器的 PWM波输出功能,在使用此功能时,是不需要使用中断的。

配置过程:

单以定时器3为例,其实定时器3做出来了,其他的也就会了,只不过改改引脚即可。

首先配置定时器3:

#include "bsp_GeneralTim.h" /******************************** TIM3 PWM输出配置 ******************************/static void GENERAL_TIM3_GPIO_Config(void) 
{GPIO_InitTypeDef GPIO_InitStructure;// 输出比较通道1 GPIO 初始化RCC_APB2PeriphClockCmd(GENERAL_TIM3_CH1_GPIO_CLK, ENABLE);GPIO_InitStructure.GPIO_Pin =  GENERAL_TIM3_CH1_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GENERAL_TIM3_CH1_PORT, &GPIO_InitStructure);// 输出比较通道2 GPIO 初始化RCC_APB2PeriphClockCmd(GENERAL_TIM3_CH2_GPIO_CLK, ENABLE);GPIO_InitStructure.GPIO_Pin =  GENERAL_TIM3_CH2_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GENERAL_TIM3_CH2_PORT, &GPIO_InitStructure);// 输出比较通道3 GPIO 初始化RCC_APB2PeriphClockCmd(GENERAL_TIM3_CH3_GPIO_CLK, ENABLE);GPIO_InitStructure.GPIO_Pin =  GENERAL_TIM3_CH3_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GENERAL_TIM3_CH3_PORT, &GPIO_InitStructure);// 输出比较通道4 GPIO 初始化RCC_APB2PeriphClockCmd(GENERAL_TIM3_CH4_GPIO_CLK, ENABLE);GPIO_InitStructure.GPIO_Pin =  GENERAL_TIM3_CH4_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GENERAL_TIM3_CH3_PORT, &GPIO_InitStructure);
}///*
// * 注意:TIM_TimeBaseInitTypeDef结构体里面有5个成员,TIM6和TIM7的寄存器里面只有
// * TIM_Prescaler和TIM_Period,所以使用TIM6和TIM7的时候只需初始化这两个成员即可,
// * 另外三个成员是通用定时器和高级定时器才有.
// *-----------------------------------------------------------------------------
// *typedef struct
// *{ TIM_Prescaler            都有   定时器的预分频值。预分频值越大,计数频率越低,定时器的计数周期就越长。
// *	TIM_CounterMode			     TIMx,x[6,7]没有,其他都有   定时器的计数模式(向上、向下、中心对齐)
// *  TIM_Period               都有   定时器的自动重装载值。当计数器达到自动重装载值时,会产生更新事件,并重新从0开始计数。
// *  TIM_ClockDivision        TIMx,x[6,7]没有,其他都有   定时器的时钟分频系数。用于将计数器时钟进一步分频,从而得到一个更低的计数频率。时钟分频系数的取值范围为1到65535。
// *  TIM_RepetitionCounter    TIMx,x[1,8,15,16,17]才有  配置定时器在重复计数模式下的重复计数次数。高级定时器特有
// *}TIM_TimeBaseInitTypeDef; 
// *-----------------------------------------------------------------------------
// *//* ----------------   PWM信号 周期和占空比的计算--------------- */
// ARR :自动重装载寄存器的值
// CLK_cnt:计数器的时钟(驱动CNT计数器的时钟周期),等于 Fck_int / (psc+1) = 72M/(psc+1)  psc = GENERAL_TIM_Prescaler 宏定义的值为 71
//          CLK_cnt = 1 MHZ
// PWM 信号的周期 T = ARR * (1/CLK_cnt) = ARR*(PSC+1) / 72M  
//          这里的ARR代表的是自动重装载寄存器的值,累计TIM_Period+1,也就是9+1=10,跟下面的ARR不一样,下面的ARR没加一
//          周期 = 10 * (1 / 1 MHZ) = 10 us
// 占空比 P = CCR/(GENERAL_TIM_Period+1)  GENERAL_TIM_Period 宏定义中为9,也就是说,占空比为 = CCR / 10static void GENERAL_TIM3_Mode_Config(void)
{// 开启定时器时钟,即内部时钟CK_INT=72MGENERAL_TIM3_APBxClock_FUN(GENERAL_TIM3_CLK,ENABLE);/*--------------------时基结构体初始化-------------------------*/// 配置周期,这里配置为100KTIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;// 自动重装载寄存器的值ARR,累计TIM_Period+1个频率后产生一个更新或者中断  	TIM_Period+1  9+1=10TIM_TimeBaseStructure.TIM_Period=GENERAL_TIM3_Period;	// 驱动CNT计数器的时钟 = Fck_int/(psc+1)TIM_TimeBaseStructure.TIM_Prescaler= GENERAL_TIM3_Prescaler;	// 时钟分频因子 ,配置死区时间时需要用到TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;		// 计数器计数模式,设置为向上计数TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;		// 重复计数器的值,没用到不用管TIM_TimeBaseStructure.TIM_RepetitionCounter=0;	// 初始化定时器TIM_TimeBaseInit(GENERAL_TIM3, &TIM_TimeBaseStructure);/*--------------------输出比较结构体初始化-------------------*/	 // 需要 PWM波 输出的就需要配置此结构体// 占空比配置uint16_t CCR1_Val = 9;  // 占空比 = CCR1_Val / (GENERAL_TIM_Period + 1)uint16_t CCR2_Val = 6;uint16_t CCR3_Val = 3;uint16_t CCR4_Val = 1;TIM_OCInitTypeDef  TIM_OCInitStructure;// 配置为PWM模式1TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;  //比较输出模式选择.常用的为 PWM1/PWM2// 输出使能TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;  //比较输出使能,决定最终的输出比较信号OCx是否通过外部引脚输出,也就是说启用之后可以产生PWM波信号// 输出通道电平极性配置	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;  //比较输出极性,可选 OCx 为高电平有效或低电平有效。它决定着定时器通道有效电平。也就是正周期的电平是高/低// 输出比较通道 1TIM_OCInitStructure.TIM_Pulse = CCR1_Val;TIM_OC1Init(GENERAL_TIM3, &TIM_OCInitStructure);TIM_OC1PreloadConfig(GENERAL_TIM3, TIM_OCPreload_Enable);// 输出比较通道 2TIM_OCInitStructure.TIM_Pulse = CCR2_Val;TIM_OC2Init(GENERAL_TIM3, &TIM_OCInitStructure);TIM_OC2PreloadConfig(GENERAL_TIM3, TIM_OCPreload_Enable);// 输出比较通道 3TIM_OCInitStructure.TIM_Pulse = CCR3_Val;TIM_OC3Init(GENERAL_TIM3, &TIM_OCInitStructure);TIM_OC3PreloadConfig(GENERAL_TIM3, TIM_OCPreload_Enable);// 输出比较通道 4TIM_OCInitStructure.TIM_Pulse = CCR4_Val;TIM_OC4Init(GENERAL_TIM3, &TIM_OCInitStructure);TIM_OC4PreloadConfig(GENERAL_TIM3, TIM_OCPreload_Enable);// 使能计数器TIM_Cmd(GENERAL_TIM3, ENABLE);
}void GENERAL_TIM3_Init(void)
{GENERAL_TIM3_GPIO_Config();  // 通用定时器GPIO口配置GENERAL_TIM3_Mode_Config();	// 通用定时器输出模式等配置	
}

.h文件进行引脚等宏定义:

#ifndef __BSP_GENERALTIME_H
#define __BSP_GENERALTIME_H#include "stm32f10x.h"/*******************通用定时器TIM参数定义,只限TIM2、3、4、5******************/
// 当使用不同的定时器的时候,对应的GPIO是不一样的,这点要注意
/******************************* TIM3 ***************************************/#define            GENERAL_TIM3                   TIM3
#define            GENERAL_TIM3_APBxClock_FUN     RCC_APB1PeriphClockCmd
#define            GENERAL_TIM3_CLK               RCC_APB1Periph_TIM3
#define            GENERAL_TIM3_Period            9
#define            GENERAL_TIM3_Prescaler         71
// TIM3 输出比较通道1
#define            GENERAL_TIM3_CH1_GPIO_CLK      RCC_APB2Periph_GPIOA
#define            GENERAL_TIM3_CH1_PORT          GPIOA
#define            GENERAL_TIM3_CH1_PIN           GPIO_Pin_6// TIM3 输出比较通道2
#define            GENERAL_TIM3_CH2_GPIO_CLK      RCC_APB2Periph_GPIOA
#define            GENERAL_TIM3_CH2_PORT          GPIOA
#define            GENERAL_TIM3_CH2_PIN           GPIO_Pin_7// TIM3 输出比较通道3
#define            GENERAL_TIM3_CH3_GPIO_CLK      RCC_APB2Periph_GPIOB
#define            GENERAL_TIM3_CH3_PORT          GPIOB
#define            GENERAL_TIM3_CH3_PIN           GPIO_Pin_0// TIM3 输出比较通道4
#define            GENERAL_TIM3_CH4_GPIO_CLK      RCC_APB2Periph_GPIOB
#define            GENERAL_TIM3_CH4_PORT          GPIOB
#define            GENERAL_TIM3_CH4_PIN           GPIO_Pin_1/**************************函数声明********************************/void GENERAL_TIM3_Init(void);#endif	/* __BSP_GENERALTIME_H */

main函数:

int main(void)
{LED_GPIO_Config();//初始化函数//GENERAL_TIM3_Init();//GENERAL_TIM2_Init();//GENERAL_TIM4_Init();GENERAL_TIM5_Init();while(1){GPIO_ResetBits(LED2_GPIO_PORT,LED2_GPIO_PIN);}
}

想要验证这个程序,需要一个LED灯,当然也可以用别的可现实PWM变化的外设去替代。完整程序链接如下:

链接:https://pan.baidu.com/s/1BLrr-MkQEAeBW7fP4Z7O4g 
提取码:wa4e 
--来自百度网盘超级会员V1的分享

相关文章:

STM32 定时器介绍--通用、高级定时器

目录 高级定时器 1.功能框图 1-时钟源 2-时基单元 3-输入捕获 4-输出比较 2.输入捕获的应用 3.输出比较的应用 4.初始化结构体 1-时基初始化结构体 2-输出比较结构体 3-PWM信号 周期和占空比的计算--以通用定时器为例 4-输入捕获结构体 5-断路和死区初始化结构体…...

淘宝天猫渠道会员购是什么意思?如何开通天猫淘宝渠道会员购有什么用?

淘宝天猫渠道会员购是什么意思? 淘宝天猫渠道会员购与淘宝天猫粉丝福利购意思基本相同,都可以领取淘宝天猫大额内部隐藏优惠券、通过草柴APP开通绑定渠道会员还可以获得购物返利。 草柴APP如何绑定开通淘宝天猫渠道会员? 1、手机下载安装「…...

(Note)机器学习面试题

机器学习 1.两位同事从上海出发前往深圳出差,他们在不同时间出发,搭乘的交通工具也不同,能准确描述两者“上海到深圳”距离差别的是: A.欧式距离 B.余弦距离 C.曼哈顿距离 D.切比雪夫距离 S:D 1. 欧几里得距离 计算公式&#x…...

思科:iOS和iOSXe软件存在漏洞

思科警告说,有人试图利用iOS软件和iOSXe软件中的一个安全缺陷,这些缺陷可能会让一个经过认证的远程攻击者在受影响的系统上实现远程代码执行。 中严重程度的脆弱性被追踪为 CVE-2023-20109 ,并以6.6分得分。它会影响启用Gdoi或G-Ikev2协议的软件的所有版本。 国际知名白帽黑客…...

CCF CSP认证 历年题目自练Day19

题目一 试题编号: 201812-1 试题名称: 小明上学 时间限制: 1.0s 内存限制: 512.0MB 问题描述: 题目背景   小明是汉东省政法大学附属中学的一名学生,他每天都要骑自行车往返于家和学校。为了能尽可能充…...

Java 开发环境配置

在本章节中我们将为大家介绍如何搭建Java开发环境。 目录 window系统安装java 下载JDK 配置环境变量 JAVA_HOME 设置 PATH设置 CLASSPATH 设置 测试JDK是否安装成功 Linux,UNIX,Solaris,FreeBSD环境变量设置 流行 Java 开发工具 使…...

[2023.09.26]: JsValue的转换体验与as关键字的浅析

昨天解决了焦点问题,今天就开始搬砖了。本以为可以一帆风顺,但是还是遇到了几个问题,不过还好,都被一一解决,这里我分享一下JsValue的转换体验以及关键字as的使用浅析。 场景描述 我是在什么情况下遇到JsValue的转换…...

SpringBoot Validation入参校验国际化

在 Spring Boot 中,可以使用 Validation 和国际化来实现对入参的校验。 常用的校验 NotNull验证字段值不能为 nullNotEmpty验证字段值不能为 null 或空字符串NotBlank验证字符串字段值不能为空、null,并且必须至少包含一个非空白字符Size验证字符串、…...

树莓集团涉足直播产业园区运营,成都直播产业园区再添黑马

树莓集团涉足成都直播产业园运营领域,这一消息引起了业界的广泛关注。在这个无限可能的直播领域中,树莓集团将与上市公司德商产投紧密合作,立志为成都直播行业的发展注入新的活力。成都天府蜂巢直播产业园推行着一系列创新的政策措施&#xf…...

中小学教师ChatGPT的23种用法

原文:中小学教师ChatGPT的23种用法 近日,ChatGPT引发舆论风暴,火遍全球。作为一款生成式人工智能软件,ChatGPT可以就任何议题生成文本,完成包括回答问题,撰写文章、论文、诗歌在内的多种工作。各界盛赞其“…...

Ubuntu性能分析-ftrace 底层驱动

1、框架介绍 ftrace内核驱动可以分为几部分:ftrace framework,RingBuffer,debugfs,Tracepoint,各种Tracer。 ftrace框架是整个ftrace功能的纽带,包括对内和的修改,Tracer的注册,RingBuffer的控制等等。 RingBuffer是静态动态ftrace的载体。 debugfs则提供了用户空间…...

网盘搜索引擎:点亮知识星空,畅享数字宝藏!

大家好!作为一名资深的网络产品运营人员,我今天要向大家介绍一款让你受益匪浅的神奇工具——网盘搜索引擎!它可以帮助你免费搜索查询各种云盘共享资源,包括影视作品、纪录片、小说、动漫等等。现在,我们急需网络流量&a…...

Mysql以key-val存储、正常存储的区别

场景 你作为一个服务端工程师,假设产品要求设计这么一个页面,页面上包含很多模块,每个模块都可以单独进行变更,有些模块是富文本。 实现方式有很多,我们来聊比较常用的两种,看看mysql的表如何设计。 第一…...

MySQL 索引优化实践(单表)

目录 一、前言二、表数据准备三、常见业务无索引查询耗时测试3.1、通过订单ID / 订单编号 查询指定订单3.2、查询订单列表 四、订单常见业务索引优化实践4.1、通过唯一索引和普通索引优化通过订单编号查询订单信息4.2、通过普通联合索引优化订单列表查询4.2.1、分析查询字段的查…...

react create-react-app v5配置 px2rem (暴露 eject方式)

环境信息: create-react-app v5 “react”: “^18.2.0” “postcss-plugin-px2rem”: “^0.8.1” 配置步骤: 我这个方式是 npm run eject 暴露 webpack配置的方法 1.安装 postcss-plugin-px2rem 和 lib-flexible cnpm install postcss-plugin-px2rem…...

AVL树的实现及原理

目录 AVL树的由来 AVL的实现原理 左单旋 右单旋 先左后右 先右后左 总结 AVL树的由来 查找,无论在什么情况下都与我们息息相关。在我们学习数组阶段学习到了线性查找,可是它的效率很低下,又演变出来了二分查找,它的效率非常…...

NestJs和Vite使用monorepo管理项目中,需要使用共享的文件夹步骤

NestJs和Vite使用monorepo管理项目中,需要使用共享的文件夹步骤 1 首先需要将nest-cli打包的功能通过webpack接管 nest-cli.json文件内容 {"$schema": "https://json.schemastore.org/nest-cli","collection": "nestjs/schematics",…...

我用PYQT5做的第一个实用的上位机项目(三)

基本的程序框架: 因为自己不是专业的程序员,只是一个搞电气控制的“票友”,所以尽量减少手动输入 代码量,能在Qt Dsigner里面完成的组态就不要放在代码里面完成。 在框架的建设方面,尽量做到集中和整合,位…...

代谢组学分析平台(二)

GC/MS分析生物样本为何要衍生化处理?有哪些衍生化的方法? GC的流动相为气体(通常为高纯氦),这就要求被分析物必须能够气化,而生物样本中很多内源性代谢物都含有极性基团,具有沸点高、不易气化特…...

【统计学】Top-down自上而下的角度模型召回率recall,精确率precision,特异性specificity,模型评价

最近在学 logistic regression model,又遇见了几个之前的老面孔。 召回率recall, 精确率precision,特异性spcificity,准确率accuracy,True positive rate,false positive rate等等名词在学习之初遇到的困难在于&#x…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南

点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...

OpenLayers 分屏对比(地图联动)

注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

GC1808高性能24位立体声音频ADC芯片解析

1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率&#xff0c…...

解析奥地利 XARION激光超声检测系统:无膜光学麦克风 + 无耦合剂的技术协同优势及多元应用

在工业制造领域,无损检测(NDT)的精度与效率直接影响产品质量与生产安全。奥地利 XARION开发的激光超声精密检测系统,以非接触式光学麦克风技术为核心,打破传统检测瓶颈,为半导体、航空航天、汽车制造等行业提供了高灵敏…...

Windows电脑能装鸿蒙吗_Windows电脑体验鸿蒙电脑操作系统教程

鸿蒙电脑版操作系统来了,很多小伙伴想体验鸿蒙电脑版操作系统,可惜,鸿蒙系统并不支持你正在使用的传统的电脑来安装。不过可以通过可以使用华为官方提供的虚拟机,来体验大家心心念念的鸿蒙系统啦!注意:虚拟…...