【STM32单片机】#5 定时中断
主要参考学习资料:
B站@江协科技
STM32入门教程-2023版 细致讲解 中文字幕
开发资料下载链接:https://pan.baidu.com/s/1h_UjuQKDX9IpP-U1Effbsw?pwd=dspb
单片机套装:STM32F103C8T6开发板单片机C6T6核心板 实验板最小系统板套件科协
实验:
- 定时器定时中断
- 定时器外部时钟
新函数:
- 定时器库函数(部分)
目录
- TIM简介
- 定时器类型
- 定时器结构
- 基本定时器
- 通用定时器
- 高级定时器
- 定时中断
- 定时中断基本结构
- 时基单元时序图
- 预分频器时序
- 计数器时序
- RCC时钟树
- 函数详解
- 定时中断初始化
- TIM_DeInit函数
- TIM_TimeBaseInit函数
- TIM_TimeBaseInitTypeDef结构体
- TIM_TimeBaseStructInit函数
- TIM_Cmd函数
- TIM_ITConfig函数
- 时钟选择
- TIM_InternalClockConfig函数
- TIM_ITRxExternalClockConfig函数
- TIM_TIxExternalClockConfig函数
- TIM_ETRClockMode1Config函数
- TIM_ETRClockMode2Config函数
- TIM_ETRConfig函数
- 定时器配置
- TIM_PrescalerConfig函数
- TIM_CounterModeConfig函数
- TIM_ARRPreloadConfig函数
- 定时器读写
- TIM_SetCounter函数
- TIM_SetAutoreload函数
- TIM_GetCounter函数
- TIM_GetPrescaler函数
- 中断标志位
- 实验8 定时器定时中断
- 接线图
- 定时器驱动
- 主程序
- 实验9 定时器外部时钟
- 接线图
- 定时器驱动
- 主程序
TIM简介
- TIM(Timer)定时器
- 定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断。
- STM32的定时器拥有16位计数器、预分频器、自动重装寄存器的时基单元,在72MHz计数时钟下可以实现最大59.65s的定时。
- 定时器不仅具备基本的定时中断功能,而且还包含内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等多种功能。
- 根据复杂度和应用场景,定时器分为高级定时器、通用定时器、基本定时器三种类型。
定时器类型

STM32F103C8T6定时器资源:TIM1、TIM2、TIM3、TIM4
定时器结构
基本定时器

基本定时器只能以内部时钟为时钟源,其信号来源于RCC的TIMxCLK,频率值一般为系统主频72MHz。
预分频器对72MHz的计数时钟进行预分频。预分频器写入n则分频系数为n+1,此时输出频率=输入频率/(n+1)。该预分频器为16位,最大可进行65536分频。
计数器对预分频后的计数时钟进行计数,每到达一个上升沿,计数器的值加一。该计数器为16位,其目标值最大为65535,目标值由自动重装载寄存器存储。计数器到达目标值继续计数将重新从零开始,并产生通往NVIC的更新中断,同时还可以产生更新事件,触发内部其他电路的工作。
除了上述向上计数方式,定时器还有向下计数(从目标值倒数到零后产生中断,重新从目标值倒数)和中央计数(向上计数和向下计数交替),一般使用向上计数方式。
通用定时器

通用定时器的时钟源除了内部时钟还可以选择外部时钟。
TIMx_ETR来自相应的引脚,可接入外部方波时钟,并通过配置极性选择、边沿检测、预分频和输入滤波对外部时钟进行整形。整形后的时钟信号一路由ETRF通往时基单元,为“外部时钟模式2”;另一路由TRGI用于触发定时器从模式,后续补充,若将其作为外部时钟使用,则为“外部时钟模式1”。两种模式对时钟输入等价,只是模式1会占用触发输入通道。
ITR来自其他定时器的TRGO输出,连接方式参考数据手册。通过将其他定时器的更新事件映射到TRGO上,可以实现定时器级联,从而对更长的时间计数。
TI1F_ED来自输入捕获单元的TIMx_CH1引脚,ED(edge)意为边沿,即通过这一路输入的时钟上升沿和下降沿均有效。TI1FP1和TI2FP2来自输入捕获单元的TIMx_CH1和TIMx_CH2引脚。以上为外部时钟模式1的内容,一般情况使用TIMx_ETR即可,其余情况为扩大时钟输入范围和其余特殊应用场景设计,后续补充。
下方右侧为四通道输出比较电路,可用于输出PWM波形驱动电机。左侧为四通道输入捕获电路,可用于测量输入方波的频率。输出比较和输入捕获不会同时使用,它们共用中间的捕获/比较寄存器。
高级定时器

高级定时器在通用定时器基础上有如下改动:
申请中断处增加重复次数计数器,可以实现每隔几个计数周期发生一次更新中断和更新事件。
输出比较模块升级,暂时不必深入了解。三个通道的输出引脚由一个变成两个,可以输出一对互补的PWM波,用于驱动三相无刷电机。三相无刷电机有三个桥臂,每个桥臂由两个大功率开关管控制。DTG死区生成电路用于在开关切换瞬间产生一定时长的死区使桥臂上下管全都关断,防止直通现象。
增加刹车输入功能,为电机驱动提供安全保障。如果外部引脚TIMx_BKIN产生刹车信号或内部时钟失效,控制电路将自动切断电机输出防止意外发生。
定时中断
定时中断基本结构

以上为定时中断用到的结构,其中中断输出控制位中断输出的允许位。
时基单元时序图
预分频器时序

CK_PSC为输入时钟。CNT_EN为计数器使能,高电平计数器正常运行,低电平计数器停止。CK_CNT是预分频器的时钟输出和计数器的时钟输入。一开始计数器未使能,计数器时钟不运行。使能后,前半段预分频器系数为1,计数器时钟等于输入时钟。后半段预分频器系数为2,计数器时钟变为输入时钟的一半。计数器寄存器跟随时钟上升沿自增,在达到图中情况的自动重装值FC后重新从零开始计数,并产生一个更新事件。
后三行时序为预分频寄存器的缓存机制。预分频控制寄存器供我们读写,预分频缓冲器决定预分频器的分频系数。在写入新的分频系数后,缓冲器会等待当前计数周期完成再接收控制寄存器的值,以保证一个计数周期内频率的统一性。预分频计数器在分频系数为0时始终为0,预分频器直接输出原频率;分频系数不为0时,预分频计数器以分频系数为目标值计数,并在回到0时,CK_CNT输出一个脉冲。
计数器计数频率:CK_CNT=CK_PSC/(PSC+1)
CK_PSC:输入时钟频率;PSC:预分频控制寄存器写入值。
计数器时序

当计数器寄存器到达自动重装值时,下一次计数清零,产生计数器溢出和更新事件,并将更新中断标志位置一以申请中断,中断响应后需要再中断程序中手动清零。
计数器溢出频率:CK_CNT_OV=CK_CNT/(ARR+1)
ARR:自动重装值。
自动重装寄存器也有与预分频器类似的缓存机制,并且可以设置是否使用(预装入)。无预装时,向自动重装寄存器写入新值即改变当前计数周期的自动重装值:

但如果计数器计数已经超过更新的自动重装值,计数器只能计数到其本身的最大值再重新从零开始计数到自动重装值。有预装时,自动重装值会在当前计数周期结束后再更新到计数器中:

RCC时钟树

RCC时钟树是STM32中用来产生和配置时钟,并且把配置好的时钟发送到各个外设的系统。时钟是所有外设运行的基础,因此也是最先需要配置的东西。程序在主函数之前会隐式执行ST公司提供的SystemInit函数以配置时钟树。RCC时钟树以AHB预分频器为界,左侧为时钟产生电路,右侧为时钟分配电路,SYSCLK即72MHz系统时钟。
时钟产生电路有8MHz HSI RC(内部)、4-16MHz HSE OSC(外部)、32.768kHz LSE OSC(提供给RTC)和40kHz LSI RC(提供给看门狗)四个晶振。前两个高速晶振用于提供AHB、APB2、APB1的系统时钟,外部石英振荡器比内部RC振荡器更稳定,故一般使用外部晶振。若系统简单、不需要精确的时钟,可使用内部晶振以省下外部晶振电路。SystemInit函数会先选择启动内部时钟为系统时钟,再启动外部时钟,经PLL锁相环倍频9倍后得到72MHz,待锁相环输出稳定后选择锁相环输出为系统输出。CSS时钟安全系统检测外部时钟状态,一旦外部时钟失效则自动把外部时钟切换回内部时钟,保证系统时钟运行,防止程序卡死造成事故。
时钟分配电路中,系统时钟进入AHB总线,在AHB预分频器中根据SystemInit函数配置的分频系数一分频。时钟进入APB1总线再由APB1预分频器二分频至ABP1外设,而定时器仍将时钟还原为72MHz作为内部基准时钟(前提是不随意更改SystemInit函数配置)。APB2预分频器分频系数为1,因此时钟也为72MHz。每个时钟输出还会与外设时钟使能经过一个与门,外设时钟使能即为程序中RCC_APB2/1PeriphClockCmd作用的地方,只有使能后时钟才能通过与门输出给外设。
函数详解
本次介绍将要使用的部分定时器库函数。
定时中断初始化
TIM_DeInit函数
简介:恢复定时器初始配置。
参数:定时器名称
TIM1, ..., TIM17
TIM_TimeBaseInit函数
简介:时基单元初始化。
参数一:定时器名称
参数二:指向初始化信息TIM_TimeBaseInitTypeDef结构体的指针
TIM_TimeBaseInitTypeDef结构体
成员TIM_ClockDivision:内部时钟分频,提供滤波器采样频率。
TIM_CKD_DIV1, TIM_CKD_DIV2, TIM_CKD_DIV4
成员TIM_CounterMode:计数器模式。
TIM_CounterMode_Up(向上计数),
TIM_CounterMode_Down(向下计数),
TIM_CounterMode_CenterAligned1(先上后下中央计数),
TIM_CounterMode_CenterAligned2(先下后上中央计数),
TIM_CounterMode_CenterAligned3(交替使用两种中央计数)
成员TIM_Period:自动重装值。
成员TIM_Prescaler:预分频寄存器值。
成员TIM_RepetitionCounter:重复计数器值。
TIM_TimeBaseStructInit函数
简介:为TIM_TimeBaseInitTypeDef结构体变量赋默认值。
参数:指向初始化信息TIM_TimeBaseInitTypeDef结构体的指针
TIM_Cmd函数
简介:使能计数器。
参数一:定时器名称
参数二:使能/失能
TIM_ITConfig函数
简介:使能中断输出信号。
参数一:定时器名称
参数二:选择中断输出
TIM_IT_Update(更新中断)
TIM_IT_CC1, ..., TIM_IT_CC4(捕获/比较通道中断)
TIM_IT_COM(电机换相中断)(高级定时器)
TIM_IT_Trigger(触发中断)
TIM_IT_Break(刹车中断)(高级定时器)
参数三:使能/失能
时钟选择
TIM_InternalClockConfig函数
简介:选择内部时钟。
参数:定时器名称
TIM_ITRxExternalClockConfig函数
简介:选择ITRx其他定时器的时钟。
参数一:定时器名称
参数二:选择的ITR通道
TIM_TS_ITR0, ..., TIM_TS_ITR3
TIM_TIxExternalClockConfig函数
简介:选择TIx捕获通道的时钟。
参数一:定时器名称
参数二:选择的TI引脚
TIM_TIxExternalCLK1Source_TI1ED, TIM_TIxExternalCLK1Source_TI1
TIM_TIxExternalCLK1Source_TI2
参数三:极性(边沿触发方式)
TIM_ICPolarity_Rising, TIM_ICPolarity_Falling
参数四:滤波器(每个值对应一个采样频率和确认电平信号有效的连续采样次数,详见数据手册)
0x00~0x0F
TIM_ETRClockMode1Config函数
简介:选择ETR通过外部时钟模式1输入的时钟。
参数一:定时器名称
参数二:外部触发预分频器(以下分别为一/二/四/八分频)
TIM_ExtTRGPSC_OFF
TIM_ExtTRGPSC_DIV2, TIM_ExtTRGPSC_DIV4, TIM_ExtTRGPSC_DIV8
参数三:极性
TIM_ExtTRGPolarity_Inverted(上升沿), TIM_ExtTRGPolarity_NonInverted(下降沿)
参数四:滤波器
TIM_ETRClockMode2Config函数
简介:选择ETR通过外部时钟模式2输入的时钟。
参数一:定时器名称
参数二:外部触发预分频器
参数三:极性(同TIM_ETRClockMode1Config函数)
参数四:滤波器
TIM_ETRConfig函数
简介:单独配置ETR引脚的预分频器、极性和滤波器。
参数一:定时器名称
参数二:外部触发预分频器
参数三:极性(同TIM_ETRClockMode1Config函数)
参数四:滤波器
定时器配置
TIM_PrescalerConfig函数
简介:配置定时器的预分频器。
参数一:定时器名称
参数二:预分频控制寄存器写入值
参数三:是否预装
TIM_PSCReloadMode_Update(预装), TIM_PSCReloadMode_Immediate(无预装)
TIM_CounterModeConfig函数
简介:配置计数器的计数模式。
参数一:定时器名称
参数二:计数器模式
TIM_ARRPreloadConfig函数
简介:配置自动重装器预装功能。
参数一:定时器名称
参数二:使能/失能
定时器读写
TIM_SetCounter函数
简介:给计数器写入一个值。
参数一:定时器名称
参数二:写入值
TIM_SetAutoreload函数
简介:给自动重装器写入一个值。
参数一:定时器名称
参数二:自动重装值
TIM_GetCounter函数
简介:获取当前计数器的值。
参数:定时器名称
TIM_GetPrescaler函数
简介:获取当前预分频器的值。
参数:定时器名称
中断标志位
主程序读取、清除中断标志位:
TIM_GetFlagStatus
TIM_ClearFlag
中断程序读取、清除中断标志位:
TIM_GetITStatus
TIM_ClearITPendingBit
参数一:定时器名称
参数二:中断线路
实验8 定时器定时中断
实现功能:OLED显示数字从零开始每秒加一。
接线图

定时器驱动
由于定时器是内部硬件,因此驱动文件放在System中。
Timer.h
#ifndef __TIMER_H
#define __TIMER_Hvoid Timer_Init(void);#endif
Timer.c
#include "stm32f10x.h"void Timer_Init(void)
{//启用TIM2时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//选择内部时钟(定时器上电默认使用内部时钟,可不写)TIM_InternalClockConfig(TIM2);//配置时基单元TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//用不到ETR滤波器,随意配置TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//向上计数TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//定时1s,即计数器溢出频率1Hz,根据公式分配数值//取值不唯一,勿超出65535TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1;TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;//通用定时器无重复计数功能TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);//为了立刻更新定时器配置,TIM_TimeBaseInit会主动触发更新事件//更新事件会将中断标志位置一,每次中断计数变量Num加一//清除中断标志位,否则该程序功能将从1开始计数TIM_ClearFlag(TIM2, TIM_FLAG_Update);//使能更新中断TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);//配置NVICNVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_Init(&NVIC_InitStructure);//启动定时器TIM_Cmd(TIM2, ENABLE);
}
主程序
#include "stm32f10x.h"
#include "Delay.h"
#include "OLED.h"
#include "Timer.h"uint16_t Num;int main(void)
{OLED_Init();Timer_Init();OLED_ShowString(1, 1, "Num:");while(1){OLED_ShowNum(1, 5, Num, 5);}
}//中断函数
void TIM2_IRQHandler(void)
{if(TIM_GetITStatus(TIM2, TIM_IT_Update) == SET){Num ++;TIM_ClearITPendingBit(TIM2, TIM_IT_Update);}
}
实验9 定时器外部时钟
实现功能:每遮挡一次对射式红外传感器计数器加一,每遮挡十次OLED显示Num加一。
接线图

定时器驱动
该实验驱动在实验8基础上更改,时钟选择外部时钟并配置相应GPIO,添加读取计数器计数值函数。更改部分用注释标明。
Timer.h
#ifndef __TIMER_H
#define __TIMER_Hvoid Timer_Init(void);
uint16_t Timer_GetCounter(void);#endif
Timer.c
#include "stm32f10x.h"void Timer_Init(void)
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//配置GPIORCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);//选择外部时钟//不使用预分频器,下降沿触发,滤波器采样频率来自32分频,连续采样8次TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x0F);TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//从0计到9TIM_TimeBaseInitStructure.TIM_Period = 10 - 1;//遮挡手速慢,无需分频TIM_TimeBaseInitStructure.TIM_Prescaler = 1 - 1;TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);TIM_ClearFlag(TIM2, TIM_FLAG_Update);TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_Init(&NVIC_InitStructure);TIM_Cmd(TIM2, ENABLE);
}//返回计数器计数值
uint16_t Timer_GetCounter(void)
{return TIM_GetCounter(TIM2);
}
主程序
#include "stm32f10x.h"
#include "Delay.h"
#include "OLED.h"
#include "Timer.h"uint16_t Num;int main(void)
{OLED_Init();Timer_Init();OLED_ShowString(1, 1, "Num:");OLED_ShowString(2, 1, "CNT:");while(1){OLED_ShowNum(1, 5, Num, 5);//显示计数器计数值OLED_ShowNum(2, 5, Timer_GetCounter(), 5);}
}//中断函数
void TIM2_IRQHandler(void)
{if(TIM_GetITStatus(TIM2, TIM_IT_Update) == SET){Num ++;TIM_ClearITPendingBit(TIM2, TIM_IT_Update);}
}
相关文章:
【STM32单片机】#5 定时中断
主要参考学习资料: B站江协科技 STM32入门教程-2023版 细致讲解 中文字幕 开发资料下载链接:https://pan.baidu.com/s/1h_UjuQKDX9IpP-U1Effbsw?pwddspb 单片机套装:STM32F103C8T6开发板单片机C6T6核心板 实验板最小系统板套件科协 实验&…...
OrbStack 作为 Mac 用户的 Docker 替代方案
推荐使用 OrbStack 作为 Mac 用户的 Docker 替代方案 在现代开发环境中,容器化技术已经成为了软件开发的重要组成部分。对于 Mac 用户来说,Docker Desktop 是一个广泛使用的工具,但它并不是唯一的选择。本文将推荐 OrbStack 作为 Docker Desktop 的替代方案,并探讨其优势。…...
运行小程序报错
[ app.json 文件内容错误] app.json: ["tabBar"]["list"] 不能超过 5 项(env: Windows,mp,1.06.2206090; lib: 3.7.12) 他的意思大概是,微信小程序 app.json 文件中的 tabBar.list 配置项超过了 5 项。这是微信小程序的限制,tabBar…...
Nature Electronics|一种透气、可拉伸的液态金属基3D电子皮肤系统(健康监测/可穿戴电子/透汗透气性电子/电子皮肤/柔性电子/集成电路)
一、 摘要 穿戴式和皮肤电子设备的发展要求高密度可伸展电子系统能够与软组织共形,持续运行并提供长期的生物相容性。大多数可拉伸电子系统的集成密度低,并且与外部印刷电路板连接,这限制了功能,降低了用户体验并阻碍了长期可用性。在此,作者提出了一种可渗透的三维集成电…...
深入剖析丝杆升降机工作原理,解锁工业传动奥秘
丝杆升降机,在工业设备的大舞台上扮演着不可或缺的角色,被广泛应用于机械制造、自动化生产线、建筑施工等众多领域。它能够精准实现重物的升降、定位等操作,为各类工业生产提供了稳定可靠的支持。想要深入了解丝杆升降机,就必须探…...
【51单片机】2-3【I/O口】震动传感器控制LED灯
1.硬件 51最小系统LED灯模块震动传感器模块 2.软件 #include "reg52.h"sbit led1 P3^7;//根据原理图(电路图),设备变量led1指向P3组IO口的第7口 sbit vibrate P3^3;//震动传感器DO接P3.3口void Delay2000ms() //11.0592MHz {…...
TortoiseSVN设置忽略清单
1.TortoiseSVN > Properties(如果安装了 TortoiseSVN)。 2. 在弹出的属性窗口中,点击 New > Other。 4. 在 Property name 中输入 svn:ignore 。 5. 在 Property value 中输入要忽略的文件夹或文件名称,例如: #…...
大模型持续学习方案解析:灾难性遗忘的工业级解决方案
引言 随着大型语言模型(LLMs)如 GPT 系列、BERT 等在自然语言处理领域取得突破性进展,它们强大的理解和生成能力已经渗透到各行各业。然而,这些模型通常是在海量静态数据集上进行一次性预训练的。现实世界是动态变化的࿰…...
《UNIX网络编程卷1:套接字联网API》第7章:套接字选项深度解析
《UNIX网络编程卷1:套接字联网API》第7章:套接字选项深度解析 一、套接字选项核心原理 1.1 选项层级体系 套接字选项按协议层级划分(图1): SOL_SOCKET:通用套接字层选项IPPROTO_IP:IPv4协议层…...
Debian编译安装mysql8.0.41源码包 笔记250401
Debian编译安装mysql8.0.41源码包 以下是在Debian系统上通过编译源码安装MySQL 8.0.41的完整步骤,包含依赖管理、编译参数优化和常见问题处理: 准备工作 1. 安装编译依赖 sudo apt update sudo apt install -y \cmake gcc g make libssl-dev …...
医疗思维图与数智云融合:从私有云到思维图的AI架构迭代(代码版)
医疗思维图作为AI架构演进的重要方向,其发展路径从传统云计算向融合时空智能、大模型及生态开放的“思维图”架构迭代,体现了技术与场景深度融合的趋势。 以下是其架构迭代的核心路径与关键特征分析: 一、从“智慧云”到“思维图”的架构演进逻辑 以下是针对医疗信息化领域…...
【计算机网络应用层】
文章目录 计算机网络应用层详解一、前言二、应用层的功能三、常见的应用层协议1. HTTP/HTTPS(超文本传输协议)2. DNS(域名系统)3. FTP(文件传输协议)4. SMTP/POP3/IMAP(电子邮件协议)…...
【JS】接雨水题解
题目 思路 首先我们要明确如何计算每条柱子的接水量: 每条柱子对应接到的雨水量该柱子左边最大值和右边最大值中的较小值-该柱子本身的高度。举例:第二条柱子自身高度为0,左边最大值为1,右边最大值为3,取较小值1-自身…...
线代[12]|《高等几何》陈绍菱(1984.9)(文末有对三大空间的分析及一个合格数学系毕业生的要求)
文章目录 一、概述二、平面仿射几何的基本概念三、平面射影几何的基本概念四、变换群和几何学五、二次曲线的射影理论、仿射理论和度量理论六、射影几何公理基础七、非欧几里得几何概要八、自我测试题九、欧氏解析几何、仿射解析几何、射影解析几何与其他(博主借助A…...
第3课:状态管理与事件处理
第3课:状态管理与事件处理 学习目标 掌握useState Hook的使用理解组件事件处理机制实现表单输入与状态绑定完成任务添加功能原型 一、useState基础 1. 创建第一个状态 新建src/Counter.js: import { useState } from react;function Counter() {co…...
提升移动端用户体验:解决输入框被软键盘遮挡的有效方法
解决移动端输入框被软键盘覆盖的问题 在开发移动端网页时,如果页面包含输入框,则可能会遇到输入框被弹出的软键盘遮挡的问题。为了解决这个问题,我们需要理解两种常见的情况以及相应的解决策略。 浏览器未主动聚焦到输入框 现代浏览器和移…...
哈希表(Hashtable)核心知识点详解
1. 基本概念 定义:通过键(Key)直接访问值(Value)的数据结构,基于哈希函数将键映射到存储位置。 核心操作: put(key, value):插入键值对 get(key):获取键对应的值 remo…...
多分类交叉熵
1. 基本概念:熵与交叉熵 要理解多分类交叉熵损失的由来,首先需要掌握信息论中的两个基础概念:熵(Entropy)和交叉熵(Cross-Entropy)。 熵(Entropy) 熵衡量一个随机变量的…...
【速写】Transformer-encoder-decoder深度解析
文章目录 一、理论分析1. Transformers概述2. Transformer的输入部分具体是如何构成?2.1 单词 Embedding2.2 位置 Embedding 3 自注意力原理3.1 自注意力结构3.2 QKV的计算3.3 自注意力的输出3.4 多头注意力 4 Encoder结构4.1 AddNorm4.2 前馈4.3 组成Encoder 二、代…...
MyBatis八股文-执行流程、延迟加载、一级与二级缓存
(一)执行流程 mybatis-config.xml核心配置文件的作用: 在MyBatis框架的核心配置文件中需要去指定当前的环境配置、指定需要操作的是哪个数据库,并且输入当前的用户名与密码,只有配置了他才能真正操作数据库。同时还去加载了SQL映射文件&#…...
Protobuf 的快速使用(四)
Protobuf 还常⽤于通讯协议、服务端数据交换场景。那么在这个⽰例中,我们将实现⼀个⽹络版本的通讯录,模拟实现客⼾端与服务端的交互,通过 Protobuf 来实现各端之间的协议序列化。需求如下: 客⼾端可以选择对通讯录进⾏以下操作&…...
SQL ServerAlways On 可用性组配置失败
问题现象: 配置 Always On 可用性组时,报错 “无法将数据库加入可用性组”(错误 41158),或提示 “WSFC 群集资源无法联机”(错误 19471)。 快速诊断 验证 WSFC 群集状态: # 检查群集…...
Mysql explain中列的解析
EXPLAIN列的解释: table:显示这一行的数据是关于哪张表的 type:这是重要的列,显示连接使用了何种类型。从最好到最差的连接类型为const、eq_reg、ref、range、indexhe和ALL possible_keys:查询可以利用的索引&#…...
基于Spark的哔哩哔哩舆情数据分析系统
【Spark】基于Spark的哔哩哔哩舆情数据分析系统 (完整系统源码开发笔记详细部署教程)✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 本项目基于Python和Django框架进行开发,为了便于广大用户针对舆情进行个性化分析处…...
【Linux】日志模块实现详解
📢博客主页:https://blog.csdn.net/2301_779549673 📢博客仓库:https://gitee.com/JohnKingW/linux_test/tree/master/lesson 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正! &…...
yum list查询时部分包查找不到流程分析
以下是针对 yum list available -c xxx.repo(对应 DNF 的命令行操作)的详细流程解读,包括参数解析、配置初始化、元数据加载、数据库查询,以及读取不到特定包的场景分析。 1. 命令行参数解析与入口函数 代码入口: dnf.cli.main.m…...
MySQL篇(六)MySQL 分库分表:应对数据增长挑战的有效策略
MySQL篇(六)MySQL 分库分表:应对数据增长挑战的有效策略 MySQL篇(六)MySQL 分库分表:应对数据增长挑战的有效策略一、引言二、为什么需要分库分表2.1 性能瓶颈2.2 存储瓶颈2.3 高并发压力 三、分库分表的方…...
Java基础:面向对象高级(四)
内部类(类中五大成分之一) 四种形式 成员内部类【了解】 静态内部类【了解】 局部内部类【了解】 匿名内部类【重点】 枚举 泛型 什么是泛型 泛型类-模拟ArrayList 泛型接口-操作学生,老师增删改查 泛型方法 泛型擦除和注意事项...
easy-poi 一对多导出
1. 需求: 某一列上下两行单元格A,B值一样且这两个单元格, 前面所有列对应单元格值一样的话, 就对A,B 两个单元格进行纵向合并单元格 1. 核心思路: 先对数据集的国家,省份,城市...... id 身份证进行排序…...
python通过调用海康SDK打开工业相机(全流程)
首先打开海康机器人-机器视觉-下载中心 下载最新版的 MVS 安装后打开目录找到 ...\MVS\Development\Samples\Python 将MvImport内所有文件拷贝至工作目录 然后到 C:\Program Files (x86)\Common Files\MVS\Runtime 找到适合自己系统的版本,将整个文件夹拷贝至工…...
