【STM32】在标准库中使用定时器

1.TIM简介

各个定时器特性

STM32F407系列控制器有2个高级控制定时器、10个通用定时器和2个基本定时器。通常情况下,先看定时器挂在哪个总线上APB1或者APB2,然后定时器时钟需要在此基础上乘以2。

2.标准库实现定时中断

#ifndef __BSP_TIMER_H
#define __BSP_TIMER_H#ifdef __cplusplus
extern "C"{#endif#include "stm32f4xx.h"#define INT_TIMER_IRQ             TIM3_IRQn
#define INT_TIMER_IRQHandler      TIM3_IRQHandler//我们使用了通用定时器TIM3来实现计时中断
//注意,并不是所有的TIM在向量表中都定义了中断服务函数,所以你得自己去查一查
//TIM3在APB1总线上
#define INT_TIMER               TIM3
#define INT_TIMER_CLK           RCC_APB1Periph_TIM3void Init_INT_TIMER(void);#ifdef __cplusplus
}
#endif#endif
#include "bsp_timer.h"
#include "bsp_led.h"
#include "stdio.h"void Init_INT_TIMER(void)
{//使能定时器时钟RCC_APB1PeriphClockCmd(INT_TIMER_CLK,ENABLE);//初始化定时器,配置ARR,PSCTIM_TimeBaseInitTypeDef TIM_InitStruct;TIM_InitStruct.TIM_ClockDivision=TIM_CKD_DIV1;TIM_InitStruct.TIM_CounterMode=TIM_CounterMode_Up;//选择向上计数的方式/* 累计 TIM_Period个后产生一个更新或者中断*///当定时器从0计数到4999,即为5000次,为一个定时周期TIM_InitStruct.TIM_Period=5000-1;//定时器时钟源TIMxCLK = 2 * PCLK1//        PCLK1 = HCLK / 4//        => TIMxCLK=HCLK/2=SystemCoreClock/2=84MHz// 设定定时器频率为=TIMxCLK/(TIM_Prescaler+1)=10000Hz ==>0.1msTIM_InitStruct.TIM_Prescaler=8400-1;////所以,一个中断产生时间为 0.1ms*5000=500msTIM_InitStruct.TIM_RepetitionCounter=0;//高级定时器才有的参数,这里也无用TIM_TimeBaseInit(INT_TIMER,&TIM_InitStruct);//配置中断控制器并使能中断NVIC_InitTypeDef NVIC_InitStruct;NVIC_InitStruct.NVIC_IRQChannel=INT_TIMER_IRQ;NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=3;NVIC_InitStruct.NVIC_IRQChannelSubPriority=0;NVIC_Init(&NVIC_InitStruct);TIM_ITConfig(INT_TIMER,TIM_IT_Update,ENABLE);//使能定时器TIM_Cmd(INT_TIMER,ENABLE);
}void INT_TIMER_IRQHandler(void)
{if(SET==TIM_GetITStatus(INT_TIMER,TIM_IT_Update)){LED_TOGGLE();TIM_ClearITPendingBit(INT_TIMER,TIM_IT_Update);printf("INT_TIMER_IRQHandler\r\n");}
}
int main(void)
{Init_USART();Init_LED();//设置中断分组NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);Init_INT_TIMER();printf("hello,this is stm32f407\r\n");/* Infinite loop */while (1){}
}

在这里插入图片描述

自动重载寄存器TIMx_ARR用来存放于计数器值比较的数值,如果两个数值相等就生成事件,将相关事件标志位置位,生成DMA和中断输出。 TIMx_ARR有影子寄存器,可以通过TIMx_CR1寄存器的ARPE位控制影子寄存器功能,如果ARPE位置1,影子寄存器有效, 只有在事件更新时才把TIMx_ARR值赋给影子寄存器。如果ARPE位为0,修改TIMx_ARR值马上有效。

void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);

就是标准库中的这个函数,其实就是配置TIMx_CR1寄存器的ARPE位。所以,我们也可以意识到,ARR值是可以热更新的。

3.标准库实现PWM输出

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

PWM模式分为两种,PWM1和PWM2,总得来说是差不多,就看你怎么用而已,具体的区别见表格 PWM1与PWM2模式的区别 。

PWM1与PWM2模式的区别

下面我们以PWM1模式来讲解,以计数器CNT计数的方向不同还分为边沿对齐模式和中心对齐模式。PWM信号主要都是用来控制电机, 一般的电机控制用的都是边沿对齐模式,FOC电机一般用中心对齐模式。我们这里只分析这两种模式在信号感官上(即信号波形)的区别, 具体在电机控制中的区别不做讨论,到了你真正需要使用的时候就会知道了。

在递增计数模式下,计数器从 0 计数到自动重载值( TIMx_ARR寄存器的内容),然后重新从 0 开始计数并生成计数器上溢事件

PWM1模式的边沿对齐波形

在边沿对齐模式下,计数器CNT只工作在一种模式,递增或者递减模式。这里我们以CNT工作在递增模式为例,在中,ARR=8,CCR=4,CNT从0开始计数, 当CNT<CCR的值时,OCxREF为有效的高电平,于此同时,比较中断寄存器CCxIF置位。当CCR=<CNT<=ARR时,OCxREF为无效的低电平。然后CNT又从0开始计数并生成计数器上溢事件,以此循环往复。
在这里插入图片描述

#ifndef __BSP_TIMER_H
#define __BSP_TIMER_H#ifdef __cplusplus
extern "C"{#endif#include "stm32f4xx.h"//我们使用TIM5来输出PWM波形
//这里我们需要查手册,看看TIM5输出通道复用的引脚(TIM5_CH1--PA0)
#define PWM_OUT_TIMER           TIM5
#define PWM_OUT_TIMER_CLK       RCC_APB1Periph_TIM5
#define PWM_OUT_PIN             GPIO_Pin_0
#define PWM_OUT_GPIO_Port       GPIOA
#define PWM_OUT_GPIO_CLK        RCC_AHB1Periph_GPIOA
#define PWM_OUT_AF_SOURCE       GPIO_PinSource0
#define PWM_OUT_AF              GPIO_AF_TIM5void Init_PWM_OUT_TIMER(void);#ifdef __cplusplus
}
#endif#endif
#include "bsp_timer.h"
#include "bsp_led.h"
#include "stdio.h"void Init_PWM_OUT_TIMER(void)
{//使能定时器时钟RCC_APB1PeriphClockCmd(PWM_OUT_TIMER_CLK,ENABLE);//使能pwm输出引脚使能RCC_AHB1PeriphClockCmd(PWM_OUT_GPIO_CLK,ENABLE);//初始化pwm输出GPIOGPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Pin=PWM_OUT_PIN;GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF;//配置为复用推挽输出GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP;//默认拉高GPIO_InitStruct.GPIO_Speed=GPIO_Fast_Speed;GPIO_Init(PWM_OUT_GPIO_Port,&GPIO_InitStruct);//并设置复用映射GPIO_PinAFConfig(PWM_OUT_GPIO_Port,PWM_OUT_AF_SOURCE,PWM_OUT_AF);//初始化定时器,配置ARR,PSCTIM_TimeBaseInitTypeDef TIM_InitStruct;TIM_InitStruct.TIM_ClockDivision=TIM_CKD_DIV1;TIM_InitStruct.TIM_CounterMode=TIM_CounterMode_Up;//选择向上计数的方式/* 累计 TIM_Period个后产生一个更新或者中断*///当定时器从0计数到4999,即为5000次,为一个定时周期TIM_InitStruct.TIM_Period=5000-1;//定时器时钟源TIMxCLK = 2 * PCLK1//        PCLK1 = HCLK / 4//        => TIMxCLK=HCLK/2=SystemCoreClock/2=84MHz// 设定定时器频率为=TIMxCLK/(TIM_Prescaler+1)=10000Hz ==>0.1msTIM_InitStruct.TIM_Prescaler=8400-1;////所以,一个中断产生时间为 0.1ms*5000=500msTIM_InitStruct.TIM_RepetitionCounter=0;//高级定时器才有的参数,这里也无用TIM_TimeBaseInit(PWM_OUT_TIMER,&TIM_InitStruct);TIM_OCInitTypeDef TIM_OCInitStruct;TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1;TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High;TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable;TIM_OCInitStruct.TIM_Pulse=2500;// 设置PWM占空比//其他的参数在高级定时器中才会用到,可以忽视。我们这里使用的通用定时器。TIM_OC1Init(PWM_OUT_TIMER, &TIM_OCInitStruct);//使能定时器TIM_Cmd(PWM_OUT_TIMER,ENABLE);
}

在这里插入图片描述

注意:当把CCR设置为5000的时候,就都是高电平了。设置为4999时,才会出现低电平。

和ARR值一样,CCR值同样可以热更新。

void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);void TIM_SetCompare1(TIM_TypeDef* TIMx, uint32_t Compare1);

我们可以简单做个实验,把该定时器溢出中断也打开,然后在溢出中断中改变CCR的值,其实就是改变占空比。然后看看输出波形。

uint32_t ccr=0;
void TIM5_IRQHandler(void)
{if(SET==TIM_GetITStatus(PWM_OUT_TIMER,TIM_IT_Update)){if(ccr>5000)ccr=0;TIM_SetCompare1(PWM_OUT_TIMER,ccr);TIM_ClearITPendingBit(PWM_OUT_TIMER,TIM_IT_Update);ccr+=1000;}
}

在这里插入图片描述

如果要输出96kHz的PWM波形,则需修改:

	TIM_InitStruct.TIM_Prescaler=8400/96-1;//84MHz/(8400/96)=(10000*96)Hz=960000Hz=960KHzTIM_InitStruct.TIM_Period=10-1;

4.标准库实现PWM输入捕获

在说PWM输入捕获之前,我们还是搞清楚输入捕获吧。输入捕获通过检测外部信号在捕获通道上的边沿变化(上升沿或下降沿)来工作。当设定的边沿到达时,当前定时器的计数值(TIMx_CNT)被立即锁定并存储到相应的捕获/比较寄存器(TIMx_CCRx)中。但是如果只是配置捕获上升沿,那么我们只能够测量周期,因为高电平的下降沿我们没有捕获,导致不能够计算占空比。

那我们可以在捕获到第一个上升沿后,配置捕获下降沿,然后再次配置捕获上升沿,理论上这种方式也是可以的,但是太繁琐了,其实定时器是支持直接配置PWM输入捕获的,通用定时器就可以,具体看下文源码。

说说软件基本思路,因为自己使用的硬件设计有限,其他定时器的通道未引出,所以只能使用一个定时器TIM5。使用一块板输出PWM波形,频率是96KHz,占空比是渐变的。使用另外一块板作为PWM输入捕获。定时器复用的通道引脚直接使用杜邦线连接。

#include "bsp_timer.h"
#include "bsp_led.h"
#include "stdio.h"void Init_PWM_IN_TIMER(void)
{//使能定时器时钟RCC_APB1PeriphClockCmd(PWM_IN_TIMER_CLK,ENABLE);//使能pwm输出引脚使能RCC_AHB1PeriphClockCmd(PWM_IN_GPIO_CLK,ENABLE);//初始化pwm输出GPIOGPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Pin=PWM_IN_PIN;GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF;//配置为复用推挽输出GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP;//默认拉高GPIO_InitStruct.GPIO_Speed=GPIO_Fast_Speed;GPIO_Init(PWM_IN_GPIO_Port,&GPIO_InitStruct);//并设置复用映射GPIO_PinAFConfig(PWM_IN_GPIO_Port,PWM_IN_AF_SOURCE,PWM_IN_AF);//初始化定时器,配置ARR,PSCTIM_TimeBaseInitTypeDef TIM_InitStruct;TIM_InitStruct.TIM_ClockDivision=TIM_CKD_DIV1;TIM_InitStruct.TIM_CounterMode=TIM_CounterMode_Up;//选择向上计数的方式/* 累计 TIM_Period个后产生一个更新或者中断*///当定时器从0计数到4999,即为5000次,为一个定时周期TIM_InitStruct.TIM_Period=5000-1;//定时器时钟源TIMxCLK = 2 * PCLK1//        PCLK1 = HCLK / 4//        => TIMxCLK=HCLK/2=SystemCoreClock/2=84MHz// 设定定时器频率为=TIMxCLK/(TIM_Prescaler+1)=10000Hz ==>0.1msTIM_InitStruct.TIM_Prescaler=8400-1;//所以,一个中断产生时间为 0.1ms*5000=500msTIM_InitStruct.TIM_Prescaler=8400/96-1;//84MHz/(8400/96)=(10000*96)Hz=960000Hz=960KHzTIM_InitStruct.TIM_Period=0xffffffff;TIM_InitStruct.TIM_RepetitionCounter=0;//高级定时器才有的参数,这里也无用TIM_TimeBaseInit(PWM_IN_TIMER,&TIM_InitStruct);/*--------------------输入捕获结构体初始化-------------------*/// 使用PWM输入模式时,需要占用两个捕获寄存器,一个测周期,另外一个测占空比// 捕获通道IC1配置// 选择捕获通道TIM_ICInitTypeDef  TIM_ICInitStructure;TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;// 设置捕获的边沿TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;// 设置捕获通道的信号来自于哪个输入通道,有直连和非直连两种TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;// 1分频,即捕获信号的每个有效边沿都捕获TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;// 不滤波TIM_ICInitStructure.TIM_ICFilter = 0x0;// 初始化PWM输入模式TIM_PWMIConfig(PWM_IN_TIMER, &TIM_ICInitStructure);// 当工作做PWM输入模式时,只需要设置触发信号的那一路即可(用于测量周期)// 另外一路(用于测量占空比)会由硬件自带设置,不需要再配置// 选择输入捕获的触发信号TIM_SelectInputTrigger(PWM_IN_TIMER, TIM_TS_TI1FP1);// 选择从模式: 复位模式// PWM输入模式时,从模式必须工作在复位模式,当捕获开始时,计数器CNT会被复位TIM_SelectSlaveMode(PWM_IN_TIMER, TIM_SlaveMode_Reset);TIM_SelectMasterSlaveMode(PWM_IN_TIMER,TIM_MasterSlaveMode_Enable);//配置中断控制器并使能中断NVIC_InitTypeDef NVIC_InitStruct;NVIC_InitStruct.NVIC_IRQChannel=TIM5_IRQn;NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=4;NVIC_InitStruct.NVIC_IRQChannelSubPriority=0;NVIC_Init(&NVIC_InitStruct);TIM_ITConfig(PWM_IN_TIMER,TIM_IT_CC1,ENABLE);//使能定时器TIM_Cmd(PWM_IN_TIMER,ENABLE);
}
uint32_t IC1Value,IC2Value;
float DutyCycle,Frequency;void TIM5_IRQHandler(void)
{if(SET==TIM_GetITStatus(PWM_IN_TIMER,TIM_IT_CC1)){TIM_ClearITPendingBit(PWM_IN_TIMER,TIM_IT_CC1);/* 获取输入捕获值 */IC1Value = TIM_GetCapture1(PWM_IN_TIMER);IC2Value = TIM_GetCapture2(PWM_IN_TIMER);//printf("IC1Value = %d  IC2Value = %d \r\n",IC1Value,IC2Value);// 注意:捕获寄存器CCR1和CCR2的值在计算占空比和频率的时候必须加1if (IC1Value != 0&&IC2Value != 0) {/* 频率计算 */Frequency = (960*1000.0)/(float)(IC1Value+1);/* 占空比计算 */DutyCycle = (float)((IC2Value+1)*1.0 / (IC1Value+1)*100.0);printf("DutyCycle=%0.2f%%   Frequency=%0.2fHz\r\n",DutyCycle,Frequency);} else {DutyCycle = 0;Frequency = 0;}}
}

因为是PWM输入模式,只能使用通道1和通道2 ,假如我们使用的是通道1,即TI1,输入的PWM信号会被分成两路,分别是TI1FP1和TI1FP2, 两路都可以是触发信号。如果选择TI1FP1为触发信号,那么IC1捕获到的是PWM信号的周期, IC2捕获到的是占空比,这种输入通道TI和捕获通道IC的映射关系叫直连, 输入捕获结构体的TIM_ICSelection要配置为TIM_ICSelection_DirectTI。如果选择TI1FP2为触发信号,则IC2捕获到的是周期,IC1捕获到的是占空比, 这种输入通道TI和捕获通道IC的映射关系叫非直连,输入捕获结构体的TIM_ICSelection要配置为TIM_ICSelection_IndirectTI。 有关输入通道TI和捕获通道IC的具体映射关系见图 输入通道与捕获通道IC的映射图 ,有直连和非直连两种。

输入通道与捕获通道IC的映射图

当捕获到PWM信号的第一个上升沿时,产生中断,计数器被复位,锁存到捕获寄存器IC1和IC2的值都为0。当下降沿到来时,IC2会捕获,对应的是占空比, 但是会产生中断。当捕获到第二个下降沿时,IC1会捕获,对应的是周期,而且会再次进入中断,这个时间就可以根据IC1和IC2的值计算出频率和占空比。 有关PWM输入的时序见图 PWM输入模式时序图 。

PWM输入模式时序图

在这里插入图片描述

还有几点值得注意:

  1. 输入捕获的GPIO复用引脚也是配置为推挽复用功能。
  2. 输入捕获定时器的周期需要比被测PWM周期大,不然捕获定时器计数溢出都还没有捕获到上升沿。

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

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

相关文章

2.1 大语言模型的训练过程 —— 《带你自学大语言模型》系列

《带你自学大语言模型》系列部分目录及计划&#xff0c;完整版目录见&#xff1a; 带你自学大语言模型系列 —— 前言 第一部分 走进大语言模型&#xff08;科普向&#xff09; 第一章 走进大语言模型1.1 从图灵机到GPT&#xff0c;人工智能经历了什么&#xff1f;1.2 如何让…

基于MDEV的PCI设备虚拟化DEMO实现

利用周末时间做了一个MDEV虚拟化PCI设备的小试验&#xff0c;简单记录一下&#xff1a; DEMO架构&#xff0c;此图参考了内核文档&#xff1a;Documentation/driver-api/vfio-mediated-device.rst host kernel watchdog pci driver: #include <linux/init.h> #include …

【网络架构】keepalive

目录 一、keepalive基础 1.1 作用 1.2 原理 1.3 功能 二、keepalive安装 2.1 yum安装 2.2 编译安装 三、配置文件 3.1 keepalived相关文件 3.2 主配置的组成 3.2.1 全局配置 3.2.2 配置虚拟路由器 四、实际操作 4.1 lvskeepalived高可用群集 4.2 keepalivedngi…

AI视界引擎 | ​基于 YOLOv8 和计算机视觉 CV 的实时识别系统!

本文来源公众号“AI视界引擎”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;​基于 YOLOv8 和计算机视觉 CV 的实时识别系统&#xff01; 技术进步和创新正在尽可能地推进作者的日常生活&#xff0c;但仍有很大一部分社会群体因为…

自研Eclipse插件的生成及安装和使用

说明&#xff1a; 本处是使用个人自研的Eclipse插件为例&#xff0c;创建了一个菜单式的插件组&#xff0c;插件组下&#xff0c;有一个生成右击Jakarta EE服务端点类后&#xff0c;生成端点对应的Restful客户端。有什么问题&#xff0c;欢迎大家交流&#xff01;&#xff01;…

cython 笔记

数据类型 # bool 类型 // bool_type_ptactice.pyx cdef bint a 123 # 非0 为 真 &#xff0c; 0 为假 cdef bint b -123 cdef bint c 0 py_a a # cdef 定义的内容没法直接在python中直接引用 py_b b py_c c// main.py import pyximport pyximport.install(language_le…

教您设置打开IDM下载浮动条的快捷键 全网最强下载神器idm怎么使用教程 idm浮动条不显示怎么办

很多人都知道Internet Download Manager(以下简称IDM)是一款非常优秀的下载提速软件。它功能强大&#xff0c;几乎能下载网页中的所有数据&#xff08;包括视频、音频、图片等&#xff09;&#xff0c;且适用于现在市面上几乎所有的浏览器&#xff0c;非常受大家欢迎。 在使用I…

面向对象和面向过程编程的区别

引言 小伙伴们&#xff0c;当你们看到这章的时候&#xff0c;显然你们已经跨过了来自指针给你们带来的麻烦&#xff0c;唔~真棒呢&#xff0c;但是我们只学会一些基础的C语法并不能帮我们解决问题&#xff0c;甚至是稍微难一些的题目我们都没办法解决&#xff0c;那怎么办呢&am…

多机调度问题

#include<iostream> #include<string> using namespace std; struct work {int time;int number; }; int setwork0(int m,int n,int a[],struct work w[]) {int maxtime0;for(int i1; i<m; i){cout<<i<<"号设备处理作业"<<w[i].num…

python系列30:各种爬虫技术总结

1. 使用requests获取网页内容 以巴鲁夫产品为例&#xff0c;可以用get请求获取内容&#xff1a; https://www.balluff.com.cn/zh-cn/products/BES02YF 对应的网页为&#xff1a; 使用简单方法进行解析即可 import requests r BES02YF res requests.get("https://www.…

YOLOv8改进 | 卷积模块 | 分布移位卷积DSConv替换Conv

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 专栏目录&#xff1a;《YOLOv8改进有效…

2024百度之星第一场-110串

补题链接&#xff1a; 码蹄集 三个状态转移的计数dp 先确定状态 n个数至多修改k次&#xff0c;保证不出现字串“110” 常规想法先把状态确定为dp[n][k][0/1]&#xff0c;前n个数&#xff0c;修改k次后&#xff0c;末尾数为0/1&#xff0c;不能转移再换思路。 初始状态设定如…

存储请求地址但是使用时请求的是端口

baseURL默认全局加载一次&#xff0c;后续直接读取缓存 解决方案&#xff1a;

类和对象(封装、继承、多态、友元)

c面相对象的三大特性为&#xff1a;封装、继承、多态 c 认为万事万物都皆为对象&#xff0c;对象上有其属性和行为 一、类和对象&#xff08;封装&#xff09; &#xff08;一&#xff09;封装的意义 封装是c面相对象的三大特性之一 封装的意义&#xff1a; 将属性和行为…

网页如何快速被收录?

其实就是要要吸引搜索引擎爬虫更快地抓取你的网页&#xff0c;想让爬虫爬取网页&#xff0c;首要做的自然是创建并提交站点地图。站点地图是搜索引擎了解你网站结构的重要工具。它可以帮助爬虫更快地发现和抓取你网站上的所有重要页面。通过Google Search Console提交站点地图&…

6. 较全的Open3D点云数据处理(python)

注意&#xff1a;以下内容来自博客爆肝5万字❤️Open3D 点云数据处理基础&#xff08;Python版&#xff09;_python 点云 焊缝-CSDN博客&#xff0c;这篇博客写的全且详细&#xff0c;在这里是为了记笔记方便查看&#xff0c;并非抄袭。 1.点云的读写 代码如下&#xff1a; …

ARM功耗管理软件之软件栈及示例

安全之安全(security)博客目录导读 思考:功耗管理软件栈及示例?WFI&WFE?时钟&电源树?DVFS&AVS?

ubuntu22.04速装中文输入法

附送ubuntu安装chrome wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb sudo dpkg -i google-chrome-stable_current_amd64.deb

python中pip换源

目录 1. 背景2. Python 的 pip 换源2.1 临时换源&#xff08;命令行中使用参数&#xff09;2.2 永久换源&#xff08;修改配置文件&#xff09;2.2.1 Windows系统2.2.2 Linux/macOS系统 2.3 使用 pip-config 命令换源&#xff08;Linux/macOS 特定&#xff09; 3. 常用的 PyPI …

深入分析 Android BroadcastReceiver (七)

文章目录 深入分析 Android BroadcastReceiver (七)1. 高级应用场景1.1 示例&#xff1a;动态权限请求1.2 示例&#xff1a;应用内通知更新 2. 安全性与性能优化2.1 示例&#xff1a;设置权限防止广播攻击2.2 示例&#xff1a;使用 LocalBroadcastManager2.3 示例&#xff1a;在…