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

Linux学习笔记16---高精度延时实验

        延时函数是很常用的 API 函数,在前面的实验中我们使用循环来实现延时函数,但是使用循环来实现的延时函数不准确,误差会很大。虽然使用到延时函数的地方精度要求都不会很严格( 要求严格的话就使用硬件定时器了 ) ,但是延时函数肯定是越精确越好,这样延时函数就可以使用在某些对时序要求严格的场合。本章我们就来学习一下如何使用硬件定时器来实现高精度延时。

1、 高精度延时简介

        1.1 GPT 定时器简介

        学过 STM32 的同学应该知道,在使用 STM32 的时候可以使用 SYSTICK 来实现高精度延时。I.MX6U 没有 SYSTICK 定时器,但是 I.MX6U 有其他定时器啊,比如第十五章讲解的 EPIT定时器。本章我们使用 I.MX6U GPT 定时器来实现高精度延时,顺便学习一下 GPT 定时器, GPT 定时器全称为 General Purpose Timer
        GPT 定时器是一个 32 位向上定时器 ( 也就是从 0X00000000 开始向上递增计数 ) GPT 定时器也可以跟一个值进行比较,当计数器值和这个值相等的话就发生比较事件,产生比较中断。GPT 定时器有一个 12 位的分频器,可以对 GPT 定时器的时钟源进行分频, GPT 定时器特性如下:
  • ①、一个可选时钟源的 32 位向上计数器。
  • ②、两个输入捕获通道,可以设置触发方式。
  • ③、三个输出比较通道,可以设置输出模式。
  • ④、可以生成捕获中断、比较中断和溢出中断。
  • ⑤、计数器可以运行在重新启动(restart)(自由运行)free-run 模式。
  • GPT 定时器的可选时钟源如图 20.1.1.1 所示:

        从图 20.1.1.1 可以看出一共有五个时钟源,分别为: ipg_clk_24M GPT_CLK( 外部时钟 ) 、ipg_clk、 ipg_clk_32k ipg_clk_highfreq 。本例程选择 ipg_clk GPT 的时钟源, ipg_clk=66MHz
GPT 定时器结构如图 20.1.1.2 所示:

        图 20.1.1.2 中各部分意义如下:
  • ①、此部分为 GPT 定时器的时钟源,前面已经说过了,本章例程选择 ipg_clk 作为 GPT 定时器时钟源。
  • ②、此部分为 12 位分频器,对时钟源进行分频处理,可设置 0~4095,分别对应 1~4096 分频。
  • ③、经过分频的时钟源进入到 GPT 定时器内部 32 位计数器。
  • ④和⑤、这两部分是 GPT 的两路输入捕获通道,本章不讲解 GPT 定时器的输入捕获。
  • ⑥、此部分为输出比较寄存器,一共有三路输出比较,因此有三个输出比较寄存器,输出比较寄存器是 32 位的。
  • ⑦、此部分位输出比较中断,三路输出比较中断,当计数器里面的值和输出比较寄存器里面的比较值相等就会触发输出比较中断。
        GPT 定时器有两种工作模式:重新启动 (restart) 模式和自由运行 (free-run) 模式,这两个工作模式的区别如下:
        重新启动(restart) 模式 :当 GPTx_CR(x=1 2) 寄存器的 FRR 位清零的时候 GPT 工作在此 模式。在此模式下,当计数值和比较寄存器中的值相等的话计数值就会清零,然后重新从 0X00000000 开始向上计数,只有比较通道 1 才有此模式!向比较通道 1 的比较寄存器写入任何 数据都会复位 GPT 计数器。对于其他两路比较通道(通道 2 3 ),当发生比较事件以后不会复位计数器。
        自由运行(free-run) 模式 :当 GPTx_CR(x=1 2) 寄存器的 FRR 位置 1 时候 GPT 工作在此模 式下,此模式适用于所有三个比较通道,当比较事件发生以后并不会复位计数器,而是继续计 数,直到计数值为 0XFFFFFFFF ,然后重新回滚到 0X00000000
        接下来看一下 GPT 定时器几个重要的寄存器,第一个就是 GPT 的配置寄存器 GPTx_CR , 此寄存器的结构如图 20.1.1.3 所示:
寄存器 GPTx_CR 我们用到的重要位如下:
        SWR(bit15):复位 GPT 定时器,向此位写 1 就可以复位 GPT 定时器,当 GPT 复位完成以后此为会自动清零。
        FRR(bit9): 运行模式选择,当此位为 0 的时候比较通道 1 工作在重新启动 (restart) 模式。当此位为 1 的时候所有的三个比较通道均工作在自由运行模式 (free-run)
        CLKSRC(bit8:6) GPT 定时器时钟源选择位,为 0 的时候关闭时钟源;为 1 的时候选择ipg_clk 作为时钟源;为 2 的时候选择 ipg_clk_highfreq 为时钟源;为 3 的时候选择外部时钟为时钟源;为 4 的时候选择 ipg_clk_32k 为时钟源;为 5 的时候选择 ip_clk_24M 为时钟源。本章例程选择 ipg_clk 作为 GPT 定时器的时钟源,因此此位设置位 1(0b001)
        ENMOD(bit1): GPT 使能模式,此位为 0 的时候如果关闭 GPT 定时器,计数器寄存器保存定时器关闭时候的计数值。此位为 1 的时候如果关闭 GPT 定时器,计数器寄存器就会清零。
        EN(bit): GPT 使能位,为 1 的时候使能 GPT 定时器,为 0 的时候关闭 GPT 定时器。
接下来看一下 GPT 定时器的分频寄存器 GPTx_PR ,此寄存器结构如图 20.1.1.4 所示:
寄存器 GPTx_PR 我们用到的重要位就一个: PRESCALER(bit11:0) ,这就是 12 位分频值,可设置 0~4095 ,分别对应 1~4096 分频。
接下来看一下 GPT 定时器的状态寄存器 GPTx_SR ,此寄存器结构如图 20.1.1.5 所示:
        寄存器 GPTx_SR 重要的位如下:
        ROV(bit5): 回滚标志位,当计数值从 0XFFFFFFFF 回滚到 0X00000000 的时候此位置 1
        IF2~IF1(bit4:3): 输入捕获标志位,当输入捕获事件发生以后此位置 1 ,一共有两路输入捕 获通道。如果使用输入捕获中断的话需要在中断处理函数中清除此位。
        OF3~OF1(bit2:0):输出比较中断标志位,当输出比较事件发生以后此位置 1 ,一共有三路 输出比较通道。如果使用输出比较中断的话需要在中断处理函数中清除此位。接着看一下 GPT 定时器的计数寄存器 GPTx_CNT ,这个寄存器保存着 GPT 定时器的当前计数值。最后看一下 GPT 定时器的输出比较寄存器 GPTx_OCR ,每个输出比较通道对应一个输出比较寄存器,因此一个 GPT 定时器有三个 OCR 寄存器,它们的作都是相同的。以输出比较通道 1 为例,其输出比较寄存器为 GPTx_OCR1 ,这是一个 32 位寄存器,用于存放 32 位的比较值。当计数器值和寄存器 GPTx_OCR1 中的值相等就会产生比较事件,如果使能了比较中断的话就会触发相应的中断。
        关于 GPT 的寄存器就介绍到这里,关于这些寄存器详细的描述,请参考《 I.MX6ULL 参考手册》第 1432 页的 30.6 小节。

        1.2 定时器实现高精度延时原理

        高精度延时函数的实现肯定是要借助硬件定时器,前面说了本章实验使用 GPT 定时器来实现高精度延时。如果设置 GPT 定时器的时钟源为 ipg_clk=66MHz ,设置 66 分频,那么进入 GPT定时器的最终时钟频率就是 66/66=1MHz ,周期为 1us GPT 的计数器每计一个数就表示“过去”了 1us 。如果计 10 个数就表示“过去”了 10us 。通过读取寄存器 GPTx_CNT 中的值就知道计了个数比如现在要延时100us ,那么进入延时函数以后纪录下寄存器 GPTx_CNT 中的值为 200 , 当 GPTx_CNT 中的值为 300 的时候就表示 100us 过去了,也就是延时结束。 GPTx_CNT 是个 32 位寄存器,如果时钟为 1MHz 的话, GPTx_CNT 最多可以实现 0XFFFFFFFFus=4294967295us ≈4294s 72min 。也就是说 72 分钟以后 GPTx_CNT 寄存器就会回滚到 0X00000000 ,也就是溢 出,所以需要在延时函数中要处理溢出的情况。关于定时器实现高精度延时的原理就讲解到这 里,原理还是很简单的,高精度延时的实现步骤如下:
        1、设置 GPT1 定时器
        首先设置 GPT1_CR 寄存器的 SWR(bit15) 位来复位寄存器 GPT1 。复位完成以后设置寄存器 GPT1_CR 寄存器的 CLKSRC(bit8:6) 位,选择 GPT1 的时钟源为 ipg_clk 。设置定时器 GPT1
的工作模式,
        2、设置 GPT1 的分频值
        设置寄存器 GPT1_PR 寄存器的 PRESCALAR(bit111:0) 位,设置分频值。
        3、设置 GPT1 的比较值
        如果要使用 GPT1 的输出比较中断,那么 GPT1 的输出比较寄存器 GPT1_OCR1 的值可以 根据所需的中断时间来设置。本章例程不使用比较输出中断,所以将 GPT1_OCR1 设置为最大 值,即:0XFFFFFFFF
        4、使能 GPT1 定时器
        设置好 GPT1 定时器以后就可以使能了,设置 GPT1_CR EN(bit0) 位为 1 来使能 GPT1 定 时器。
        5、编写延时函数
        GPT1定时器已经开始运行了,可以根据前面介绍的高精度延时函数原理来编写延时函数, 针对 us ms 延时分别编写两个延时函数。

2、 硬件原理分析

本试验用到的资源如下:
①、一个 LED 灯: LED0
②、定时器 GPT1
本实验通过高精度延时函数来控制 LED0 的闪烁,可以通过示波器来观察 LED0 的控制 IO
输出波形,通过波形的频率或者周期来判断延时函数精度是否正常。

3、 实验程序编写

本章实验在上一章例程的基础上完成,更改工程名字为“ delay ”,直接修改 bsp_delay.c
bsp_delay.h 这两个文件,将 bsp_delay.h 文件改为如下所示内容:
#ifndef __BSP_DELAY_H
#define __BSP_DELAY_H
#include "imx6ul.h"/* 函数声明 */
void delay_init(void);
void delayus(unsigned    int usdelay);
void delayms(unsigned	 int msdelay);
void delay(volatile unsigned int n);
void gpt1_irqhandler(void);#endif
bsp_delay.h 文件就是一些函数声明,很简单。在文件 bsp_delay.c 中输入如下内容:
#include "bsp_delay.h"/** @description	: 延时有关硬件初始化,主要是GPT定时器GPT定时器时钟源选择ipg_clk=66Mhz* @param		: 无* @return 		: 无*/
void delay_init(void)
{GPT1->CR = 0; 					/* 清零,bit0也为0,即停止GPT  			*/GPT1->CR = 1 << 15;				/* bit15置1进入软复位 				*/while((GPT1->CR >> 15) & 0x01);	/*等待复位完成 						*//** GPT的CR寄存器,GPT通用设置* bit22:20	000 输出比较1的输出功能关闭,也就是对应的引脚没反应* bit9:    0   Restart模式,当CNT等于OCR1的时候就产生中断* bit8:6   001 GPT时钟源选择ipg_clk=66Mhz* bit*/GPT1->CR = (1<<6);/** GPT的PR寄存器,GPT的分频设置* bit11:0  设置分频值,设置为0表示1分频,*          以此类推,最大可以设置为0XFFF,也就是最大4096分频*/GPT1->PR = 65;	/* 设置为65,即66分频,因此GPT1时钟为66M/(65+1)=1MHz *//** GPT的OCR1寄存器,GPT的输出比较1比较计数值,*	GPT的时钟为1Mz,那么计数器每计一个值就是就是1us。* 为了实现较大的计数,我们将比较值设置为最大的0XFFFFFFFF,* 这样一次计满就是:0XFFFFFFFFus = 4294967296us = 4295s = 71.5min* 也就是说一次计满最多71.5分钟,存在溢出*/GPT1->OCR[0] = 0XFFFFFFFF;GPT1->CR |= 1<<0;			//使能GPT1/* 一下屏蔽的代码是GPT定时器中断代码,* 如果想学习GPT定时器的话可以参考一下代码。*/
#if 0/** GPT的PR寄存器,GPT的分频设置* bit11:0  设置分频值,设置为0表示1分频,*          以此类推,最大可以设置为0XFFF,也就是最大4096分频*/GPT1->PR = 65;	//设置为1,即65+1=66分频,因此GPT1时钟为66M/66=1MHz/** GPT的OCR1寄存器,GPT的输出比较1比较计数值,* 当GPT的计数值等于OCR1里面值时候,输出比较1就会发生中断* 这里定时500ms产生中断,因此就应该为1000000/2=500000;*/GPT1->OCR[0] = 500000;/** GPT的IR寄存器,使能通道1的比较中断* bit0: 0 使能输出比较中断*/GPT1->IR |= 1 << 0;/** 使能GIC里面相应的中断,并且注册中断处理函数*/GIC_EnableIRQ(GPT1_IRQn);	//使能GIC中对应的中断system_register_irqhandler(GPT1_IRQn, (system_irq_handler_t)gpt1_irqhandler, NULL);	//注册中断服务函数	
#endif}#if 0
/* 中断处理函数 */
void gpt1_irqhandler(void)
{ static unsigned char state = 0;state = !state;/** GPT的SR寄存器,状态寄存器* bit2: 1 输出比较1发生中断*/if(GPT1->SR & (1<<0)) {led_switch(LED2, state);}GPT1->SR |= 1<<0; /* 清除中断标志位 */
}
#endif/** @description		: 微秒(us)级延时* @param - value	: 需要延时的us数,最大延时0XFFFFFFFFus* @return 			: 无*/
void delayus(unsigned    int usdelay)
{unsigned long oldcnt,newcnt;unsigned long tcntvalue = 0;	/* 走过的总时间  */oldcnt = GPT1->CNT;while(1){newcnt = GPT1->CNT;if(newcnt != oldcnt){if(newcnt > oldcnt)		/* GPT是向上计数器,并且没有溢出 */tcntvalue += newcnt - oldcnt;else  					/* 发生溢出    */tcntvalue += 0XFFFFFFFF-oldcnt + newcnt;oldcnt = newcnt;if(tcntvalue >= usdelay)/* 延时时间到了 */break;			 		/*  跳出 */}}
}/** @description		: 毫秒(ms)级延时* @param - msdelay	: 需要延时的ms数* @return 			: 无*/
void delayms(unsigned	 int msdelay)
{int i = 0;for(i=0; i<msdelay; i++){delayus(1000);}
}/** @description	: 短时间延时函数* @param - n	: 要延时循环次数(空操作循环次数,模式延时)* @return 		: 无*/
void delay_short(volatile unsigned int n)
{while(n--){}
}/** @description	: 延时函数,在396Mhz的主频下* 			  	  延时时间大约为1ms* @param - n	: 要延时的ms数* @return 		: 无*/
void delay(volatile unsigned int n)
{while(n--){delay_short(0x7ff);}
}
        文件 bsp_delay.c 中一共有 5 个函数,分别为: delay_init delayus delayms delay_short 和 delay 。除了 delay_short delay 以外,其他三个都是新增加的。函数 delay_init 是延时初始化函数,主要用于初始化 GPT1 定时器,设置其时钟源、分频值和输出比较寄存器值。第 43 到 68 行被屏蔽掉的程序是 GPT1 的中断初始化代码,如果要使用 GPT1 的中断功能的话可以参考此部分代码。第 73 89 行被屏蔽掉的程序是 GPT1 的中断处理函数 gpt1_irqhandler ,同样的, 如果需要使用 GPT1 中断功能的话可以参考此部分代码。
        函数 delayus delayms 就是 us 级和 ms 级的高精度延时函数,函数 delayus 就是按照我们
20.1.2 小节讲解的高精度延时原理编写的, delayus 函数处理 GPT1 计数器溢出的情况。函数delayus 只有一个参数 usdelay ,这个参数就是要延时的 us 数。 delayms 函数很简单,就是对 delayus(1000)的多次叠加,此函数也只有一个参数 msdelay ,也就是要延时的 ms 数。
        最后修改 main.c 文件,内容如下:
#include "bsp_clk.h"
#include "bsp_delay.h"
#include "bsp_led.h"
#include "bsp_beep.h"
#include "bsp_key.h"
#include "bsp_int.h"
#include "bsp_keyfilter.h"/** @description	: main函数* @param 		: 无* @return 		: 无*/
int main(void)
{unsigned char state = OFF;int_init(); 				/* 初始化中断(一定要最先调用!) */imx6u_clkinit();			/* 初始化系统时钟 			*/delay_init();				/* 初始化延时 			*/clk_enable();				/* 使能所有的时钟 			*/led_init();					/* 初始化led 			*/beep_init();				/* 初始化beep	 		*/while(1)			{	state = !state;led_switch(LED0, state);delayms(500);}return 0;
}
main.c 函数很简单,在第 20 行调用 delay_init 函数进行延时初始化,最后在 while 循环中 周期性的点亮和熄灭 LED0 ,调用函数 delayms 来实现延时。

4、 编写 Makefile 和链接脚本

因为本章例程并没有新建任何文件,所以只需要修改 Makefile 中的 TARGET delay
可,链接脚本保持不变。

5、编译下载

使用 Make 命令编译代码,编译成功以后使用软件 imxdownload2 将编译完成的 bsp.bin 文件生成可执行的img文件,命令如下:

make
./imxdownload2 delay.bin

如果  imxdownload2无权限,可用以下命令添加权限

chmod 777 imxdownload2

 

利用Win32DiskImager软件将load.img执行文件写入SD卡,SD卡插入开发板上即可正常运行。如果代码运行正常的话 LED0 会以以 500ms 为周期不断的亮、灭闪烁。可以通过肉眼观察 LED 亮灭的时间是否为 500ms。

但是肉眼观察肯定不准确,既然本章号称高精度延时实验,那么就得经得住专业仪器的测试。我们
率就应该是 1/0.00004=25000Hz=25KHz 。使用示波器测试 LED0 对应的 IO 频率,结果如图
20.4.2.1 所示:

从图 20.4.2.1 可以看出, LED0 对应的 IO 波形频率为 22.3KHz ,周期是 44.9us ,那么 main 函数中 while 循环执行一次的时间就是 44.9/2=22.45us ,大于我们设置的 20us ,看起来好像是延 时不准确。但是我们要知道这 22.45us main 函数里面 while 循环总执行时间,也就是下面代
码的总执行时间:
while(1)
{
state = !state;
led_switch(LED0, state);
delayus(20);
}
在上面代码中不止有 delayus(20) 延时函数,还有控制 LED 灯亮灭的函数,这些代码的执行也需要时间的,即使是 delayus 函数,其内部也是要消耗一些时间的。假如我们将 while 循环里面的代码改为如下形式:
while(1)
{ 
GPIO1->DR &= ~(1<<3);delayus(20); GPIO1->DR |= (1<<3);delayus(20); 
}
上述代码我们通过直接操作寄存器的方式来控制 IO 输出高低电平,理论上 while 循环执行时间会更小,并且 while 循环里面使用了两个 delayus(20) ,因此执行一次 while 循环的理论时间应该是 40us ,和上面做的实验一样。重新使用示波器测量一下,结果如图 20.4.2.2 所示:
从图 20.4.2.2 可以看出,此时 while 循环执行一次的时间是 41.8us ,那么一次 delayus(20) 的时间就是 41.8/2=20.9us ,很接近我们的 20us 理论值。但是还是因为有其他程序开销存在,在加上示波器测量误差,所以不可能测量出绝对的 20us 。但是其已经非常接近了,基本可以证明我们的高精度延时函数是成功的、可以用的。

例程

【免费】Linux学习笔记17-高精度延时实验例程资源-CSDN文库

相关文章:

Linux学习笔记16---高精度延时实验

延时函数是很常用的 API 函数&#xff0c;在前面的实验中我们使用循环来实现延时函数&#xff0c;但是使用循环来实现的延时函数不准确&#xff0c;误差会很大。虽然使用到延时函数的地方精度要求都不会很严格( 要求严格的话就使用硬件定时器了 ) &#xff0c;但是延时函数肯定…...

vue2:如何动态控制el-form-item之间的行间距

需求 某页面有查看和编辑两种状态: 编辑: 查看: 可以看到,查看时,行间距太大导致页面不紧凑,所以希望缩小查看是的行间距。 行间距设置 行间距通常是通过 CSS 的 margin 或 padding 属性来控制的。在 Element UI 的样式表中,.el-form-item 的下边距(margin-bottom)…...

deepseek从网络拓扑图生成说明文字实例

deepseek对话页面中输入问题指令&#xff1a; 我是安全测评工程师&#xff0c;正在撰写系统测评报告&#xff0c;现在需要对系统网络架构进行详细说明&#xff0c;请根据附件网络拓扑图输出详细说明文字。用总分的段落结构&#xff0c;先介绍各网络区域&#xff0c;再介绍网络…...

两种文件类型(pdf/图片)打印A4半张纸方法

环境:windows10、Adobe Reader XI v11.0.23 Pdf: 1.把内容由横排变为纵排&#xff1a; 2.点击打印按钮&#xff1a; 3.选择打印页范围和多页&#xff1a; 4.内容打印在纸张上部 图片&#xff1a; 1.右键图片点击打印&#xff1a; 2.选择打印类型&#xff1a; 3.打印配置&am…...

HTB:UnderPass[WriteUP]

目录 连接至HTB服务器并启动靶机 信息收集 使用rustscan对靶机TCP端口进行开放扫描 使用nmap对靶机TCP开放端口进行脚本、服务扫描 使用nmap对靶机TCP开放端口进行漏洞、系统扫描 使用nmap对靶机常用UDP端口进行开放扫描 使用nmap对靶机UDP开放端口进行脚本、服务扫描 …...

【deepseek实战】绿色好用,不断网

前言 最佳deepseek火热网络&#xff0c;我也开发一款windows的电脑端&#xff0c;接入了deepseek&#xff0c;基本是复刻了网页端&#xff0c;还加入一些特色功能。 助力国内AI&#xff0c;发出自己的热量 说一下开发过程和内容的使用吧。 目录 一、介绍 二、具体工作 1.1、引…...

MySQL 进阶专题:索引(索引原理/操作/优缺点/B+树)

在数据库的秋招面试中&#xff0c;索引&#xff08;Index&#xff09;是一个经典且高频的题目。索引的作用类似于书中的目录&#x1f4d6;&#xff0c;它能够显著加快数据库查询的速度。本文将深入探讨索引的概念、作用、优缺点以及背后的数据结构&#xff0c;帮助你从原理到应…...

用NeuralProphet预测股价:AI金融新利器(附源码)

作者&#xff1a;老余捞鱼 原创不易&#xff0c;转载请标明出处及原作者。 写在前面的话&#xff1a;我用NeuralProphet模型预测了股票价格&#xff0c;发现其通过结合时间序列分析和神经网络算法&#xff0c;确实能提供比传统Last Value方法更精准的预测。经过一系列超参数调优…...

【Elasticsearch】parent aggregation

在Elasticsearch中&#xff0c;Parent Aggregation是一种特殊的单桶聚合&#xff0c;用于选择具有指定类型的父文档&#xff0c;这些类型是通过一个join字段定义的。以下是关于Parent Aggregation的详细介绍&#xff1a; 1.基本概念 Parent Aggregation是一种聚合操作&#x…...

IDEA使用Auto-dev+DeepSeek 10分钟快速集成,让java开发起飞

在当今的软件开发领域,AI 工具的辅助作用愈发凸显,DeepSeek AI 便是其中的佼佼者。它凭借强大的自然语言处理能力和高效的代码生成能力,成为众多开发者的得力助手。而 IntelliJ IDEA 作为一款广受欢迎的集成开发环境(IDE),若能与 DeepSeek AI 无缝集成,无疑将为开发者带…...

ASP.NET Core中间件Markdown转换器

目录 需求 文本编码检测 Markdown→HTML 注意 实现 需求 Markdown是一种文本格式&#xff1b;不被浏览器支持&#xff1b;编写一个在服务器端把Markdown转换为HTML的中间件。我们开发的中间件是构建在ASP.NET Core内置的StaticFiles中间件之上&#xff0c;并且在它之前运…...

使用page assist浏览器插件结合deepseek-r1 7b本地模型

为本地部署的DeepSeek R1 7b模型安装Page Assist&#xff0c;可以按照以下步骤进行&#xff1a; 一、下载并安装Ollama‌ 首先&#xff0c;你需要下载并安装Ollama&#xff0c;这是部署DeepSeek所必需的工具。你可以访问Ollama的官方网站&#xff08;ollama.com&#xff09;下…...

【华为OD-E卷 - 108 最大矩阵和 100分(python、java、c++、js、c)】

【华为OD-E卷 - 最大矩阵和 100分&#xff08;python、java、c、js、c&#xff09;】 题目 给定一个二维整数矩阵&#xff0c;要在这个矩阵中选出一个子矩阵&#xff0c;使得这个子矩阵内所有的数字和尽量大&#xff0c;我们把这个子矩阵称为和最大子矩阵&#xff0c;子矩阵的…...

【Reading Notes】Favorite Articles from 2025

文章目录 1、January2、February3、March4、April5、May6、June7、July8、August9、September10、October11、November12、December 1、January 极越之后&#xff0c;中国车市只会倒下更多人&#xff08;2025年01月01日&#xff09; 在这波枪林弹雨中&#xff0c;合资品牌中最…...

云计算行业分析

云计算作为数字经济的核心基础设施&#xff0c;未来十年将持续重塑全球科技格局&#xff0c;并渗透到几乎所有行业的数字化转型中。 一、云计算的发展潜力 1. 技术融合驱动爆发式创新 AI与云计算的深度耦合 - **智能云服务**&#xff1a;云厂商将提供预训练模型、自动化ML工…...

【Linux系统】线程:线程的优点 / 缺点 / 超线程技术 / 异常 / 用途

1、线程的优点 创建和删除线程代价较小 创建一个新线程的代价要比创建一个新进程小得多&#xff0c;删除代价也小。这种说法主要基于以下几个方面&#xff1a; &#xff08;1&#xff09;资源共享 内存空间&#xff1a;每个进程都有自己独立的内存空间&#xff0c;包括代码段…...

3.攻防世界 weak_auth

题目描述提示 是一个登录界面&#xff0c;需要密码登录 进入题目页面如下 弱口令密码爆破 用1 or 1 #试试 提示用admin登录 则尝试 用户名admin密码&#xff1a;123456 直接得到flag 常用弱口令密码&#xff08;可复制&#xff09; 用户名 admin admin-- admin or -- admin…...

代码随想录算法训练营| 二叉树总结

代码随想录 二叉树的理论基础&#xff1a;二叉树种类、存储方式、遍历方式、定义方式 二叉树遍历&#xff1a;深度优先和广度优先 二叉树属性&#xff1a;对称、深度、节点、平衡、路径、回溯 修改与构造&#xff1a;反转、构造、合并 涉及到二叉树的构造&#xff0c;无论普…...

Python OCR工具pytesseract识别数字验证码

直接下载地址&#xff1a;https://digi.bib.uni-mannheim.de/tesseract/ 找的最新版本&#xff1a; 我添加了math 跟chinese&#xff08;因为是国内网络的原因吧&#xff0c;下载都失败&#xff0c;所以不用选择&#xff0c;后面自己下载后&#xff0c;添加到相应目录就好&…...

SpringBoot开发(五)SpringBoot接收请求参数

1. SpringBoot接收请求参数 1.1. 获取参数的方式 &#xff08;1&#xff09;通过request对象获取参数   &#xff08;2&#xff09;RequestParam(针对请求头方式为x-www-form-ur lencoded)   &#xff08;3&#xff09;RequestBody(针对请求头方式为application/json)   …...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

SkyWalking 10.2.0 SWCK 配置过程

SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外&#xff0c;K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案&#xff0c;全安装在K8S群集中。 具体可参…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件

今天呢&#xff0c;博主的学习进度也是步入了Java Mybatis 框架&#xff0c;目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学&#xff0c;希望能对大家有所帮助&#xff0c;也特别欢迎大家指点不足之处&#xff0c;小生很乐意接受正确的建议&…...

渲染学进阶内容——模型

最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

【JavaWeb】Docker项目部署

引言 之前学习了Linux操作系统的常见命令&#xff0c;在Linux上安装软件&#xff0c;以及如何在Linux上部署一个单体项目&#xff0c;大多数同学都会有相同的感受&#xff0c;那就是麻烦。 核心体现在三点&#xff1a; 命令太多了&#xff0c;记不住 软件安装包名字复杂&…...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec&#xff1f; IPsec VPN 5.1 IPsec传输模式&#xff08;Transport Mode&#xff09; 5.2 IPsec隧道模式&#xff08;Tunne…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...