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

STM32单片机入门学习——第14节: [6-2] 定时器定时中断定时器外部时钟

写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难,但我还是想去做!

本文写于:2025.04.04

STM32开发板学习——第14节: [6-2] 定时器定时中断&定时器外部时钟

  • 前言
  • 开发板说明
  • 引用
  • 解答和科普
  • 一、定时器中断代码
  • 二、外部时钟
  • 问题
  • 总结

前言

   本次笔记是用来记录我的学习过程,同时把我需要的困难和思考记下来,有助于我的学习,同时也作为一种习惯,可以督促我学习,是一个激励自己的过程,让我们开始32单片机的学习之路。
   欢迎大家给我提意见,能给我的嵌入式之旅提供方向和路线,现在作为小白,我就先学习32单片机了,就跟着B站上的江协科技开始学习了.
   在这里会记录下江协科技32单片机开发板的配套视频教程所作的实验和学习笔记内容,因为我之前有一个开发板,我大概率会用我的板子模仿着来做.让我们一起加油!
   另外为了增强我的学习效果:每次笔记把我不知道或者问题在后面提出来,再下一篇开头作为解答!

开发板说明

   本人采用的是慧净的开发板,因为这个板子是我N年前就买的板子,索性就拿来用了。另外我也购买了江科大的学习套间。
   原理图如下
1、开发板原理图
在这里插入图片描述
2、STM32F103C6和51对比
在这里插入图片描述
3、STM32F103C6核心板
在这里插入图片描述

视频中的都用这个开发板来实现,如果有资源就利用起来。另外也计划实现江协科技的套件。

下图是实物图
在这里插入图片描述

引用

【STM32入门教程-2023版 细致讲解 中文字幕】
还参考了下图中的书籍:
STM32库开发实战指南:基于STM32F103(第2版)
在这里插入图片描述
数据手册
在这里插入图片描述

解答和科普

一、定时器中断代码

定时器不涉及外部硬件,所以放在了System文件夹下,
在这里插入图片描述
在这里插入图片描述
第一步:RCC开启时钟,这个基本上每个代码都是第一步,不用想
定时器的基准时钟和整个外设的工作时钟就都会同时打开了。
第二步:选择时基单元的时钟源,对于定时中断,我们就选择内部时钟源
第三步:配置时基单元:包括这里的预分频器、自动重装定时器、技术模式等等
第四步:配置输出中断控制,允许更新中断输出到NVIC
第五步:配置NVIC,在NVIC中打开定时器中断的通道,并分配一个优先级
第六步:运行控制了,
整个模块配置完成后,我们还需要是能一下计数器,要不然计数器不会运行的.当定时器使能后,计数器就会开始计数了,当计数器更新时,触发中断,
最后在写一个定时器中断函数。这样这个中断函数每隔一段时间就能自动执行一次了。

标记一下
在这里插入图片描述

在这里插入图片描述

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

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
因为在初始化结构体里有很多关键的参数,比如自动重装值和预分频值等,这些参数可能会在初始化之后还需呀更改,如果为了更改某个参数还要再调用一次初始化函数,那太麻烦了,所有这有一些单独的函数,可以方便地更改这些关键参数,比如

TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode);

单独写预分频值的:第一个为那个定时器,第二个为值,第三个为模式,写入的值在更新事件后才有效

void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode);

改变计数器的技术模式

void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);

自动重装器预装功能配置:有预装还是物预装

void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter);

给计数器写入一个值:如果你想手动写一个计数值,就可以用这个函数;

void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint16_t Autoreload);

给自动重装值写入一个值:手动给一个自动重装值,用这个函数;

uint16_t TIM_GetCounter(TIM_TypeDef* TIMx);

获取当前计数器计数值:如果你想看当前计数器计到哪里了,调用这个函数,返回值就是当前计数器的值;

uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx);

获取当前预分频器值:如果想看预分频器值,就调用这个函数;

FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);
void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);

这四个和之前的一样:获取标志位和清除标志位的。

初始化TIM2,第一步开启时钟

void Timer_Init(void)
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
}

选择时基单元的时钟

void Timer_Init(void)
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);TIM_InternalClockConfig(TIM2);		//好多人不写,默认的是内部时钟}

配置时基单元

TIM_TimeBaseInitStructure.TIM_ClockDivision=;

这个时钟分频的参数在之前的原理一直没出现过,那它是用来干啥的,
在这里插入图片描述
关键点来了,这个采样频率f从哪来,手册写的是它可以由内部时钟直接而来,也可以是由内部时钟加一个时钟分频而来,那分频多少,就由我们这个参数ClockDivision决定的;可加这个参数和时基单元关系不大,在这里我们随便配一个。

TIM_TimeBaseInitStructure.TIM_Period=;
TIM_TimeBaseInitStructure.TIM_Prescaler=;
TIM_TimeBaseInitStructure.TIM_RepetitionCounter=;

TIM_Period:周期,就是ARR自动重装器的值;
TIM_Prescaler: PSC就是预分频器的值;
TIM_RepetitionCounter:就是重复计数器的值;只有高级定时器才有。给0;
不过这里面并没有CNT计数器的参数,如果我们之后需要的话,需要用SetCounter和GetCounter这两个函数来操作计数器;
在这里插入图片描述
定时频率=72M/(PSC+1)(ARR+1),定时1s,也就是定时频率1Hz,那么PSC给一个7200,ARR给一个10000,然后两个参数都再减一个1,这样就完成了。因为预分频器和计数器都有一个数的偏差,所以这里要减个1,然后注意PSC和ARR的取值都在0 ~ 65535,不要超范围了。
你可以预分频器给少点,自动重装给多点,这样就是一个较高的频率计比较多的数(说明预分频后的时间短),也可以预分频器给多点,自动重装给少点,这样就是一个较低的频率计比较少的数(说明预分频后的时间长);预分频对72M进行7200分频,得到的就是10k的计数频率,在10K的频率下,计10000个数,那不就是1s的时间吗?

	TIM_TimeBaseInitTypeDef  TIM_TimeBaseInitStructure;TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;			//滤波的分频关系不大TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up ;		//向上计数TIM_TimeBaseInitStructure.TIM_Period=7200-1;						//ARRTIM_TimeBaseInitStructure.TIM_Prescaler=10000-1;					//PSCTIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);

使能更新中断

TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);			//更新中断到NVIC的通路

配置NVIC

	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);

定时器初始化

void Timer_Init(void)
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);TIM_InternalClockConfig(TIM2);		//好多人不写,默认的是内部时钟TIM_TimeBaseInitTypeDef  TIM_TimeBaseInitStructure;TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;			//滤波的分频关系不大TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up ;		//向上计数TIM_TimeBaseInitStructure.TIM_Period=7200-1;						//ARRTIM_TimeBaseInitStructure.TIM_Prescaler=10000-1;					//PSCTIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);			//更新中断到NVIC的通路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);
}

接下来写中断函数
在这里插入图片描述

void TIM2_IRQHandler(void)
{if(TIM_GetITStatus(TIM2,TIM_IT_Update)== SET){TIM_ClearITPendingBit(TIM2,TIM_IT_Update);}}

我们现在想让显示1s进行计数,uint16_t Num;然后这个Num要在中断函数里执行++;但是中断函数是在Timer模块里的,如果直接在主程序写Num++,那Num就是跨越不同.C文件的变量了,会报错;Num++:在主函数中会跨文件,所以我们有这几种方法:
1、 如果你想跨文件使用变量,那可以在使用变量的那个文件上面,用external unit6_t Num,这样就行了,使用extern声明;就是告诉编译器,我现在有Num这个变量,他在别的文件定义了,至于在哪里,你自己帮我找好,最终在main。c找到,那编译器就知道了,他就会把这个external声明的变量,当作main.C变量的一个引用,注意这个过程没有新定义变量,他操作的还是main.c里的这个Num,其实我们头文件里面的函数声明,也是用extern 实现的。在这个函数的前面,是有一个extern的,只不过这个extern可以省略,所以我们一般不写。
当我们用extern声明了主函数的Num变量时,就可以在这里直接使用主函数的Num变量了,
在这里插入图片描述

在这里插入图片描述

2、 把定时器中断函数移动到主函数中去。这样变量就这一个.c文件里了,就不用再使用extern了;

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "Timer.h"
#include "OLED.h"uint16_t Num;
int main(void)
{OLED_Init();Timer_Init();OLED_ShowString(1,2,"Hello STM32 MCU");OLED_ShowString(2,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);}}

初始化后看到直接进入中断1次,为什么:
在这里插入图片描述
有个缓存寄存器,这时为了我们写的值只有在更新事件时,才会真正起作用,所以这里为了让值立刻起作用,就在这最后,手动生成了一个更新事件,这样预分频器的值就有效了,但同时,它的副作用就是,更新事件和更新中断是同时发生的,,更新中断会置更新中断标志位,当我们之后一但初始化
完了,更新中断就会立刻进入,这就是我们刚一上电,就立刻进中断的原因,解决方案也很简单,在TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure)的后面,开启中断的前面,再手动调用一下,TIM_ClearFlag(TIM2,TIM_FLAG_Update);手动把更新标志位清除一下,就能避免刚初始化完就进中断的问题了。

TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);TIM_ClearFlag(TIM2,TIM_FLAG_Update);			//手动把更新标志位清除一下,就能避免刚初始化完就进中断的问题了

ARR和PSC

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "Timer.h"
#include "OLED.h"uint16_t Num;
int main(void)
{OLED_Init();Timer_Init();OLED_ShowString(1,2,"Hello STM32 MCU");OLED_ShowString(2,1,"Num:");while(1){OLED_ShowNum(2,5,Num,5);OLED_ShowNum(3,5,TIM_GetCounter (TIM2),5);		//查看CNT计数器值的变化}
}void TIM2_IRQHandler(void)
{if(TIM_GetITStatus(TIM2,TIM_IT_Update)== SET){Num++;TIM_ClearITPendingBit(TIM2,TIM_IT_Update);}}

代码

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "Timer.h"
#include "OLED.h"uint16_t Num;
int main(void)
{OLED_Init();Timer_Init();OLED_ShowString(1,2,"Hello STM32 MCU");OLED_ShowString(2,1,"Num:");while(1){OLED_ShowNum(2,5,Num,5);}
}void TIM2_IRQHandler(void)
{if(TIM_GetITStatus(TIM2,TIM_IT_Update)== SET){Num++;TIM_ClearITPendingBit(TIM2,TIM_IT_Update);}}

Timer.Ch

#include "stm32f10x.h"                  // Device headerextern uint16_t Num;void Timer_Init(void)
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);TIM_InternalClockConfig(TIM2);		//好多人不写,默认的是内部时钟TIM_TimeBaseInitTypeDef  TIM_TimeBaseInitStructure;TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;			//滤波的分频关系不大TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up ;		//向上计数TIM_TimeBaseInitStructure.TIM_Period=7200-1;						//ARRTIM_TimeBaseInitStructure.TIM_Prescaler=10000-1;					//PSCTIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);TIM_ClearFlag(TIM2,TIM_FLAG_Update);			//手动把更新标志位清除一下,就能避免刚初始化完就进中断的问题了TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);			//更新中断到NVIC的通路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);
}/*
void TIM2_IRQHandler(void)
{if(TIM_GetITStatus(TIM2,TIM_IT_Update)== SET){Num++;TIM_ClearITPendingBit(TIM2,TIM_IT_Update);}}
*/
#ifndef  __TIMER_H
#define  __TIMER_H
void Timer_Init(void);#endif

实验现象

定时器中断Num++

二、外部时钟

在这里插入图片描述

TIM_ETRClockMode2Config();
通过ETR引脚的外部时钟模式2配置,

TIM_ETRClockMode2Config(TIM2,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0x00);

引脚要用到GOIO,在这之前还要配置GPIO,
在这里插入图片描述
给了上啦输入,也是可以的。浮空输入时外部功率很小,内部的上拉电阻可能影响到这个输入信号,这时候就可以用浮空输入,防止影响外部输入的电平,

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "Timer.h"
#include "OLED.h"uint16_t Num;
int main(void)
{OLED_Init();Timer_Init();OLED_ShowString(1,2,"Hello STM32 MCU");OLED_ShowString(2,1,"Num:");OLED_ShowString(3,1,"CNT:");while(1){OLED_ShowNum(2,5,Num,5);OLED_ShowNum(3,5,Timer_GetCounter(),5);}
}void TIM2_IRQHandler(void)
{if(TIM_GetITStatus(TIM2,TIM_IT_Update)== SET){Num++;TIM_ClearITPendingBit(TIM2,TIM_IT_Update);}}

main.C

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "Timer.h"
#include "OLED.h"uint16_t Num;
int main(void)
{OLED_Init();Timer_Init();OLED_ShowString(1,2,"Hello STM32 MCU");OLED_ShowString(2,1,"Num:");OLED_ShowString(3,1,"CNT:");while(1){OLED_ShowNum(2,5,Num,5);OLED_ShowNum(3,5,Timer_GetCounter(),5);}
}void TIM2_IRQHandler(void)
{if(TIM_GetITStatus(TIM2,TIM_IT_Update)== SET){Num++;TIM_ClearITPendingBit(TIM2,TIM_IT_Update);}}

Timer.CH

#include "stm32f10x.h"                  // Device headerextern uint16_t Num;void Timer_Init(void)
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);RCC_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);//TIM_InternalClockConfig(TIM2);		//好多人不写,默认的是内部时钟TIM_ETRClockMode2Config(TIM2,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0xaa);TIM_TimeBaseInitTypeDef  TIM_TimeBaseInitStructure;TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;			//滤波的分频关系不大TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up ;		//向上计数TIM_TimeBaseInitStructure.TIM_Period=10-1;						//ARRTIM_TimeBaseInitStructure.TIM_Prescaler=1-1;					//PSCTIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);TIM_ClearFlag(TIM2,TIM_FLAG_Update);			//手动把更新标志位清除一下,就能避免刚初始化完就进中断的问题了TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);			//更新中断到NVIC的通路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);
}/*
void TIM2_IRQHandler(void)
{if(TIM_GetITStatus(TIM2,TIM_IT_Update)== SET){Num++;TIM_ClearITPendingBit(TIM2,TIM_IT_Update);}}
*/
#ifndef  __TIMER_H
#define  __TIMER_H
void Timer_Init(void);
uint16_t Timer_GetCounter(void);#endif

实验现象
这时上面是Num,下面是CNT计数器的值,我们用挡光片档一下,CNT加1,因为现在时基单元没有预分频,所以每次遮挡CNT都会加1如果有预分频了就是遮挡几次,才能加1次,然后加到9后,自动清零,同时申请中断,Num++;这里不准需要加滤波。

外部时钟源完成计数

问题

1、复杂凌乱

总结

本节课主要学了了如何配置定时器,首先是定时器中断,其中还多了对滤波器的设置,外部毛刺确实可以设置,主要是按照上一节课的理论也是打通这个线路,第一步:RCC开启时钟,这个基本上每个代码都是第一步,不用想定时器的基准时钟和整个外设的工作时钟就都会同时打开了。第二步:选择时基单元的时钟源,对于定时中断,我们就选择内部时钟源第三步:配置时基单元:包括这里的预分频器、自动重装定时器、技术模式等等;第四步:配置输出中断控制,允许更新中断输出到NVIC;第五步:配置NVIC,在NVIC中打开定时器中断的通道,并分配一个优先级;第六步:运行控制了。整个模块配置完成后,我们还需要是能一下计数器,要不然计数器不会运行的.当定时器使能后,计数器就会开始计数了,当计数器更新时,触发中断,最后在写一个定时器中断函数。这样这个中断函数每隔一段时间就能自动执行一次了。然后是选择外部时钟作为时钟源的设置。

相关文章:

STM32单片机入门学习——第14节: [6-2] 定时器定时中断定时器外部时钟

写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难,但我还是想去做! 本文写于:2025.04.04 STM32开发板学习——第14节: [6-2] 定时器定时中断&定时器外部时钟 前言开发…...

Python 元组

Python 元组 元组的介绍 元组和列表很像,都是用来保存多个数据使用一对小括号()来表示一个元组元组和列表的区别在于,列表是可变数据类型,而元组是不可变数据类型 nums (9, 4, 3, 1, 9, 7, 6, 9, 3, 9) print(nums) # (9, 4, 3, 1, 9, 7…...

Linux系统编程:进程管理、内存对比与树莓派应用

一、认识进程和线程,在Linux系统下查看系统中各进程的编号pid并终止一个进程pid 1.进程和线程 ​​进程​​:操作系统分配资源(如内存、CPU时间片)的基本单位。每个进程有独立的内存空间,进程间通信需要较复杂的机制…...

JSON介绍

JSON 的核心特点​​ ​​易读易写​​:纯文本格式,结构清晰(像“键值对”的集合)。​​通用性强​​:任何语言都能解析或生成 JSON。​​用途广泛​​:常用于前后端数据传输、配置文件、API 接口等。 &am…...

【Cursor】切换主题

右键顶部,把菜单栏勾上 首选项-主题-颜色主题 选择和喜欢的颜色主题即可,一般是“现代深色”...

【C++11(上)】—— 我与C++的不解之缘(三十)

一、C11 这里简单了解一下C发展好吧: C11是C的第二个大版本,也是自C98以来最重要的一个版本。 它引入了大量的更改,它曾被人们称为C0x,因为它被期待在2010年之前发布;但在2011年8月12日才被采纳。 C03到C11花了8年时间…...

python如何把列表中所有字符变成小写

在Python中,你可以使用列表推导式(list comprehension)结合字符串的.lower()方法,将列表中的所有字符串元素转换为小写。以下是一个示例: # 定义一个包含字符串的列表 strings ["Hello", "WORLD"…...

DEAP数据集介绍

DEAP数据集介绍 0. 数据集摘要1. 文件列表2. 文件详细信息2.1 Online_ratings2.2 Video_list2.3 Participant_ratings2.4 Participant_questionnaire2.5 Face_video.zip2.6 Data_original.zip2.7 Data_preprocessed_matlab.zip 和 Data_preprocessed_python.zip 3. References欢…...

基于RDK X3的“校史通“机器人:SLAM导航+智能交互,让校史馆活起来!

视频标题: 【校史馆の新晋顶流】RDK X3机器人:导览员看了直呼内卷 视频文案: 跑得贼稳团队用RDK X3整了个大活——给校史馆造了个"社牛"机器人! 基于RDK X3开发板实现智能导航与语音交互SLAM技术让机器人自主避障不…...

JavaScript基础-window.localStorage

在现代Web开发中,数据存储对于提升用户体验至关重要。window.localStorage 是一种简单而强大的客户端存储机制,允许网页以键值对的形式持久化保存数据。与 sessionStorage 不同,localStorage 中的数据不会因浏览器标签页关闭或刷新而丢失&…...

在航电系统中提高可靠性的嵌入式软件设计

1.总线余度设计 数据传输采用双余度总线设计,CANFD为主,RS485为备。发送方将相同的数据分别通过双总线来发送,接收方优先处理主线数据。由于总线上数据频率固定,可设置定时器监控主总线的数据,当定时器超时后&#xff…...

H.266/VVC SCC技术学习:块差分脉冲编码调整(block differential pulse coded modulation, BDPCM)

近年来,屏幕内容视频广泛用于多媒体应用,例如远程桌面,屏幕共享等。由于屏幕内容视频的特性与自然视频有较大区别,VVC中使用了帧内块复制(intra block copy, 即IBC), 调色板(Palette)&#xff0…...

网络编程—Socket套接字(TCP)

上篇文章: 网络编程—Socket套接字(UDP)https://blog.csdn.net/sniper_fandc/article/details/146923670?fromshareblogdetail&sharetypeblogdetail&sharerId146923670&sharereferPC&sharesourcesniper_fandc&sharefro…...

数据结构:二叉树(三)·(重点)

二叉树的存储结构 ⼆叉树⼀般可以使⽤两种结构存储,⼀种顺序结构,⼀种链式结构。 顺序结构 顺序结构存储就是使⽤数组来存储,⼀般使⽤数组只适合表⽰完全⼆叉树,因为不是完全⼆叉树会有 空间的浪费,完全⼆叉树更适合…...

StyleTTS 2:文本到语音(Text-to-Speech, TTS)模型

StyleTTS 2 是一种先进的文本到语音(Text-to-Speech, TTS)模型,通过结合风格扩散(style diffusion)和对抗训练(adversarial training),利用大规模语音语言模型(Speech La…...

痉挛性斜颈康复路,饮食要点来相助

痉挛性斜颈患者除了接受正规治疗,合理饮食对缓解症状、促进康复也至关重要。 高蛋白质食物是饮食中的重点。像鸡蛋,富含人体必需的氨基酸,其组成与人体组成模式接近,易于吸收。每天吃 1 - 2 个鸡蛋,能为身体补充修复肌…...

谷歌 Gemini 2.5 Pro 免费开放

2025 年 3 月 30 日,谷歌宣布将最新的 Gemini AI 旗舰模型 Gemini 2.5 Pro 免费向所有 Gemini 应用用户开放。以下是关于此次免费开放的一些具体信息1: 背景:此前,Gemini 2.5 Pro 仅向支付 19.99 美元月费的 Gemini Advanced 用户…...

规则引擎Drools

1.规则引擎概述 1.1 什么是规则引擎 规则引擎 全称为业务规则管理系统,英文名为BRMS,规则引擎的主要思想是将应用程序中的业务决策部分分离出来,并使用预定义的语义模块编写业务规则,由用户或开发者在需要时进行配置和管理。 需…...

第三季:挪威

挪威 挪威是北欧的一个国家,位于斯堪的纳维亚半岛的西部。以下是关于挪威的详细介绍: 地理位置与自然环境 位置:挪威位于北欧,东邻瑞典,东北与芬兰和俄罗斯接壤,西濒挪威海,北临巴伦支海。地…...

搜索与图论 树的深度优先遍历 树的重心

树的一种特殊的图,无环连通图 图还分为有向图,无向图 但是无向图其实也是特殊的有向图 (a指向b,b也指向a,每个连接节点都如此,则是无向图) 那我们只需要讨论有向图 有向图的分类 邻接矩阵 …...

ORA-09925 No space left on device 问题处理全过程记录

本篇文章关键字:linux、oracle、审计、ORA-09925 一、故障现像 朋友找到我说是他们备份软件上报错。 问题比较明显,ORA-09925,看起来就是空间不足导致的 二、问题分析过程 这里说一下逐步的分析思路,有个意外提前说一下就是我…...

Java开发者の模型召唤术:LangChain4j咏唱指南(三)

Java开发者の模型召唤术:LangChain4j咏唱指南(三) 往期回顾: Java开发者の模型召唤术:LangChain4j咏唱指南(一)Java开发者の模型召唤术:LangChain4j咏唱指南(二) 上两期博客中简单的为大家介绍了 langchain4j是什么、java 集成…...

【leetcode100】动态规划Java版本

70. 爬楼梯 题目 思考的时候觉得情况很多,无从下手,卡在了找推导公式这一步。 看了随想录后知道以简单的三个阶梯来推导dp公式,为什么不是四个,五个为一组呢?因为题目要求的只能爬1个阶梯,或者2个阶梯&…...

RSA和ECC在密钥长度相同的情况下哪个更安全?

​现在常见的SSL证书,如:iTrustSSL都支持RSA和ECC的加密算法,正常情况下RAS和ECC算法该如何选择呢?实际上在密钥长度相同的情况下,ECC(椭圆曲线密码学)通常比RSA(Rivest-Shamir-Adle…...

YOLO 获取 COCO 指标终极指南 | 从标签转换到 COCOAPI 评估 (训练/验证) 全覆盖【B 站教程详解】

✅ YOLO 轻松获取论文 COCO 指标:AP(small,medium,large )| 从标签转换到 COCOAPI 评估 (训练/验证) 全覆盖 文章目录 一、摘要二、为什么需要 COCO 指标评估 YOLO 模型?三、核心挑战与解决方案 (视频教程核…...

【算法竞赛】dfs+csp综合应用(蓝桥2023A9像素放置)

目录 一、 题目 二、思路 (1)算法框架选择 (2)剪枝策略 具体来说就是: 三、代码 (1) 数据读取与初始化 (2) 检查当前填充是否符合要求 (3) 递归 DFS 进行填充 (4) 读取输入 & 调用 DFS (5) 完整代码 一…...

3D点云配准RPM-Net模型解读(附论文+源码)

RPM-Net 总体流程代码数据预处理模型计算 α α α和 β β β特征提取变换矩阵计算损失 论文链接:RPM-Net: Robust Point Matching using Learned Features 官方链接:RPMNet 老规矩,先看看效果。 看看论文里给的对比图 总体流程 在学…...

23种设计模式-行为型模式-命令

文章目录 简介问题解决代码核心设计优势 总结 简介 命令是一种行为设计模式, 它能把请求转换为一个包含与请求相关的所有信息 的独立对象。这个转换能让你把请求方法参数化、延迟请求执行或把请求放在队列里,并且能实现可撤销操作。 问题 假如你正在开…...

ngx_cpystrn

定义在 src\core\ngx_string.c u_char * ngx_cpystrn(u_char *dst, u_char *src, size_t n) {if (n 0) {return dst;}while (--n) {*dst *src;if (*dst \0) {return dst;}dst;src;}*dst \0;return dst; } ngx_cpystrn 函数的作用是安全地将源字符串(src&#x…...

常用的国内镜像源

常见的 pip 镜像源 阿里云镜像:https://mirrors.aliyun.com/pypi/simple/ 清华大学镜像:https://pypi.tuna.tsinghua.edu.cn/simple 中国科学技术大学镜像:https://pypi.mirrors.ustc.edu.cn/simple/ 豆瓣镜像:https://pypi.doub…...

【小沐杂货铺】基于Three.JS绘制太阳系Solar System(GIS 、WebGL、vue、react)

🍺三维数字地球系列相关文章如下🍺:1【小沐学GIS】基于C绘制三维数字地球Earth(456:OpenGL、glfw、glut)第一期2【小沐学GIS】基于C绘制三维数字地球Earth(456:OpenGL、glfw、glut)第二期3【小沐…...

Navicat17详细安装教程(附最新版本安装包和补丁)2025最详细图文教程安装手册

目录 前言:为什么选择Navicat 17? 一、下载Navicat17安装包 二、安装Navicat 1.运行安装程序 2.启动安装 3.同意“协议” 4.设置安装位置 5.创建桌面图标 6.开始安装 7.安装完成 三、安装补丁 1.解押补丁包 2.在解压后的补丁包目录下找到“w…...

记忆宫殿APP:全方位脑力与思维训练,助你提升记忆力,预防老年痴呆

记忆宫殿APP,一款专业的记忆训练软件,能去帮你提升自己的记忆能力,多样的训练项目创新的记忆方法,全方面帮你去提升你的记忆能力。 记忆宫殿APP有丰富的记忆训练项目,如瞬间记忆、短时记忆、机械记忆等,以…...

SpringBoot+Spring+MyBatis相关知识点

目录 一、相关概念 1.spring框架 2.springcloud 3.SpringBoot项目 4.注解 5.SpringBoot的文件结构 6.启动类原理 二、相关操作 1.Jar方式打包 2.自定义返回的业务状态码 3.Jackson 4.加载配置文件 5.异常处理 三、优化配置 1.简化sql语句 2.查询操作 复杂查询 一…...

【力扣hot100题】(050)岛屿数量

一开始还以为会很难很难&#xff08;以为暴力搜索会时间超限要用别的办法&#xff09;&#xff0c;没想到并不难。 我最开始是用vector<vector<bool>>记录搜索过的地域&#xff0c;每次递归遍历周围所有地域。 class Solution { public:vector<vector<char…...

Opencv计算机视觉编程攻略-第九节 描述和匹配兴趣点

一般而言&#xff0c;如果一个物体在一幅图像中被检测到关键点&#xff0c;那么同一个物体在其他图像中也会检测到同一个关键点。图像匹配是关键点的常用功能之一&#xff0c;它的作用包括关联同一场景的两幅图像、检测图像中事物的发生地点等等。 1.局部模板匹配 凭单个像素就…...

pat学习笔记

two pointers 双指针 给定一个递增的正整数序列和一个正整数M&#xff0c;求序列中的两个不同位置的数a和b&#xff0c;使得它们的和恰好为M&#xff0c;输出所有满足条件的方案。例如给定序列{1,2,3,4,5,6}和正整数M 8&#xff0c;就存在268和358成立。 容易想到&#xff1…...

MoE Align Sort在医院AI医疗领域的前景分析(代码版)

MoE Align & Sort技术通过优化混合专家模型(MoE)的路由与计算流程,在医疗数据处理、模型推理效率及多模态任务协同中展现出显著优势,其技术价值与应用意义从以下三方面展开分析: 一、方向分析 1、提升医疗数据处理效率 在医疗场景中,多模态数据(如医学影像、文本…...

大数据概念介绍

这节课给大家讲一下大数据的生态架构, 大数据有很多的产品琳琅满目, 大家看到图上就知道产品很多, 那这些产品它们各自的功能是什么, 它们又是怎么样相互配合, 来完成一整套的数据存储, 包括分析计算这样的一些任务, 这节课就要给大家进行一个分析, 那我们按照数据处理…...

Linux(2025.3.15)

1、将/etc/passwd&#xff0c;/etc/shadow,/etc/group文件复制到/ceshi; 操作&#xff1a; &#xff08;1&#xff09;在根目录下创建ceshi目录&#xff1b; &#xff08;2&#xff09;复制&#xff1b; 结果&#xff1a; 2、找到/etc/ssh目录下ssh开头的所有文件并将其复制到…...

centosububntu设置开机自启动

一、centos 1.将脚本放到/etc/rc.d/init.d路径下 2.给脚本授权 sudo chmod -R 777 脚本名称 3.添加脚本至开机启动项中 sudo chkconfig --add 脚本名称 4.开启脚本 sudo chkconfig 脚本名称 on 5.查看开机启动项中是否包含该脚本 ls /etc/rc.d/rc*.d 二、ubuntu 1.在…...

基于大模型与动态接口调用的智能系统(知识库实现)

目录 引言 1、需求背景 2、实现原理 3、实现步骤 3.1 构建知识库接口调用提示模板 3.2 动态接口配置加载 3.3 智能参数提取链 3.4 接口智能路由 3.5 建议生成链 3.6 组合完整工作流 3.7 展示效果 总结 引言 在医疗信息化快速发展的今天,我们开发了一个智能问诊系…...

23种设计模式-行为型模式-迭代器

文章目录 简介问题解决代码设计关键点&#xff1a; 总结 简介 迭代器是一种行为设计模式&#xff0c;让你能在不暴露集合底层表现形式(列表、栈和树等)的情况下遍历集合中所有的元素。 问题 集合是编程中最常使用的数据类型之一。 大部分集合使用简单列表存储元素。但有些集…...

【Java集合】ArrayList源码深度分析

参考笔记&#xff1a; java ArrayList源码分析&#xff08;深度讲解&#xff09;-CSDN博客 【源码篇】ArrayList源码解析-CSDN博客 目录 1.前言 2. ArrayList简介 3. ArrayList类的底层实现 4. ArrayList的源码Debug 4.1 使用空参构造 &#xff08;1&#xff09;开始De…...

ISIS单区域抓包分析

一、通用头部报文 Intra Domain Routing Protocol Discriminator&#xff1a;域内路由选择协议鉴别符&#xff1a;这里是ISIS System ID Length&#xff1a;NSAP地址或NET中System ID区域的长度。值为0时&#xff0c;表示System ID区域的长度为6字节。值为255时&#xff0c;表…...

关键业务数据如何保持一致?主数据管理的最佳实践!

随着业务规模的扩大和系统复杂性的增加&#xff0c;如何确保关键业务数据的一致性成为许多企业面临的重大挑战。数据不一致可能导致决策失误、运营效率低下&#xff0c;甚至影响客户体验。因此&#xff0c;主数据管理&#xff08;Master Data Management&#xff0c;简称MDM&am…...

ISIS单区域配置

一、什么是ISIS单区域 ISIS&#xff08;Intermediate System to Intermediate System&#xff0c;中间系统到中间系统&#xff09;单区域是指使用ISIS路由协议时&#xff0c;所有路由器都位于同一个区域&#xff08;Area&#xff09;内的网络配置。 二、实验拓扑 三、实验目的…...

Visual Basic语言的物联网

Visual Basic语言在物联网中的应用 引言 物联网&#xff08;IoT&#xff09;作为一种新兴的技术趋势&#xff0c;正在深刻地改变我们的生活方式与工业制造过程。在众多编程语言中&#xff0c;Visual Basic&#xff08;VB&#xff09;凭借其简单易用的特性&#xff0c;逐渐成为…...

【小沐杂货铺】基于Three.JS绘制三维数字地球Earth(GIS 、WebGL、vue、react)

&#x1f37a;三维数字地球系列相关文章如下&#x1f37a;&#xff1a;1【小沐学GIS】基于C绘制三维数字地球Earth&#xff08;456:OpenGL、glfw、glut&#xff09;第一期2【小沐学GIS】基于C绘制三维数字地球Earth&#xff08;456:OpenGL、glfw、glut&#xff09;第二期3【小沐…...

Vite环境下解决跨域问题

在 Vite 开发环境中&#xff0c;可以通过配置代理来解决跨域问题。以下是具体步骤&#xff1a; 在项目根目录下找到 vite.config.js 文件&#xff1a;如果没有&#xff0c;则需要创建一个。配置代理&#xff1a;在 vite.config.js 文件中&#xff0c;使用 server.proxy 选项来…...