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

STM32微控制器_03_GPIO原理与应用

核心内容

  • STM32 GPIO基本原理(熟悉)
  • GPIO输出功能HAL库编程实现的应用(重点)
  • GPIO输入功能HAL库编程实现的应用(重点)

一.STM32 GPIO基本原理

1.GPIO简介

STM32的GPIO相当于STM32的四肢,一个STM32芯片被封装好后,能与外部直接进行交互的就是它的GPIO。查看数据手册Figure 7. STM32F103xC/D/E performance line LQFP64 pinout
在这里插入图片描述
IO引脚从PA0-PA15;PB0-PB15;PC0-PC15。

2.端口的复用和重映射

端口复用功能

查看Table 5. High-density STM32F103xC/D/E pin definitions,我们发现STM32 有很多的内置外设,这些外设的外部引脚都是与 GPIO 复用的。也就是说,一个 GPIO如果可以复用为内置外设的功能引脚,那么当这个 GPIO 作为内置外设使用的时候,就叫做复用。具体的案例我们到串口章节再做阐述。

端口重映射

为了使不同器件封装的外设 IO 功能数量达到最优,可以把一些复用功能重新映射到其他一 些引脚上。STM32 中有很多内置外设的输入输出引脚都具有重映射(remap)的功能。我们知道每个内置外设都有若干个输入输出引脚,一般这些引脚的输出端口都是固定不变的,为了让设计工程师可以更好地安排引脚的走向和功能,在 STM32 中引入了外设引脚重映射的概念,即一个外设的引脚除了具有默认的端口外,还可以通过设置重映射寄存器的方式,把这个外设的引脚映射到其它的端口。具体可以参照《STM32 中文参考手册 V10》的 P116 页“8.3 复用功能和调试配置”。

3.GPIO工作模式

STM32的I/O 端口有8种模式(4种输入模式和4种输出模式),每个 I/O 端口位支持3种最大翻转速度(2MHz、10MHz、50MHz),均可自由编程。
输出模式下可通过控制端口输出高低电平,来驱动蜂鸣器,发光二极管等类似的元件,也可以用来软件模拟时序等应用。 输入模式下可通过读取端口的状态,用来判断传感器状态,读取电池电压,软件模拟时序等应用。关于STM32的GPIO模式如下所示:
在这里插入图片描述

4种输入模式

  • 浮空输入(GPIO_Mode_IN_FLOATING)
    在这里插入图片描述
    在浮空输入模式里,由于无上下拉电阻的作用,mcu通过直接读取输入数据寄存器的值来获取外部io端口的电平信号。即输入的信号完全由外部的输入决定,当外部无信号输入时,表现为该引脚悬空,表示该端口的电平是不确定的。
  • 上拉输入(GPIO_Mode_IPU):
    在这里插入图片描述
    在上拉输入模式里,由于上拉电阻开关导通,mcu通过读取输入数据寄存器的值来获取电平信号。当外部无信号输入时,由于上拉电阻的作用,表现为该引脚为高电平,即io口默认为高电平,如果输入的信号为低电平,那么mcu读取到的信号为低电平。
  • 下拉输入(GPIO_Mode_IPD):
    在这里插入图片描述
    在下拉输入模式里,由于下拉电阻开关导通,mcu通过读取输入数据寄存器的值来获取电平信号。当外部无信号输入时,由于下拉电阻的作用,表现为该引脚为低电平,即io口默认为低电平,如果输入的信号为高电平,那么mcu读取到的信号为高电平。
  • 模拟输入(GPIO_Mode_AIN):
    在这里插入图片描述
    在模拟输入模式下,GPIO的引脚用于ADC采集电压的输入通道,此时信号不经过施密特触发器,上下拉电阻也不起作用。信号将直接进入ADC模块。使用输入数据寄存器获取不到电平信号,表现为空,该模式下无法督导引脚的电平状态。

4种输出模式

开漏输出(GPIO_Mode_Out_OD):
在这里插入图片描述
在开漏输出模式下,只有N-MOS管工作,当我们控制输出信号为低电平时,N-MOS管导通,此时引脚输出低电平,io端口的电平就是低电平。当我们控制输出信号为高电平时,N-MOS管关闭,输出指令无效,此时io端口的电平悬空或由外部的上下拉电路决定。即在开漏输出模式下,io口的电平不一定是输出的电平。

  • 推挽输出(GPIO_Mode_Out_PP):
    在这里插入图片描述
    在推挽输出模式下,N-MOS管和P-MOS管都工作。当我们控制输出信号为低电平时,P-MOS管关闭,N-MOS管导通,输出低电平,io口的电平就是低电平。当我们控制输出信号为高电平时,P-MOS管导通,N-MOS管关闭,输出高电平,io口的电平就是高电平。如果无控制输出信号,那么io口的电平由外部上下拉电路决定。

  • 复用开漏输出(GPIO_Mode_AF_OD):
    在这里插入图片描述
    在复用开漏输出模式下,GPIO复用为其他外设,输出的高低电平来源源自其他外设,除了输出来源的改变,其他与开漏输出模式相同。

  • 复用推挽输出(GPIO_Mode_AF_PP):
    在这里插入图片描述
    在复用推挽输出模式下,GPIO复用为其他外设,输出的高低电平来源源自其他外设,除了输出来源的改变,其他与推挽输出模式相同。

输出速度

GPIO的I/O引脚用于输出模式是右三种速度选择,分别基于2MHz、10MHz和50MHz频率。“速度”指的是输出驱动电路的响应速度,并不是输出信号的速度。
I/O端口的输出部分设计有多个响应不同速度的驱动电路,应该根据需求选择相匹配的驱动电路,达到最佳的噪声控制效果,并降低功耗。
● 对于LED、数码管、蜂鸣器等低速设备,一般设置2MHz;
● 对于串口,一般2MHz引脚速度;
● 对于I2C接口,可以选用10MHz的引脚速度;
● 对于SPI接口,可以选择50MHz的引脚速度。
● 对于复用功能的,一般设置50MHz的引脚速度。
当GPIO的I/O引脚设置为输入模式时,不需要配置输出速度。

二.GPIO输出功能HAL库编程实现的应用

项目:通过控制GPIO实现控制8个LED灯的亮灭,实现流水灯。

2.1硬件设计

LED灯

LED(light-emitting diode),即发光二极管,俗称 LED 小灯,它的种类很多,参数也不尽相同,我们板子上用的是普通的贴片发光二极管。这种二极管通常的正向导通电压是 1.8V 到 2.2V 之间,工作电流一般在 1mA~20mA 之间。其中,当电流在 1mA~5mA 之间变化时, 随着通过 LED 的电流越来越大,我们的肉眼会明显感觉到这个小灯越来越亮,而当电流从 5mA~20mA 之间变化时,我们看到的发光二极管的亮度变化就不是太明显了。当电流超过 20mA 时,LED 就会有烧坏的危险了,电流越大,烧坏的也就越快。
在这里插入图片描述
LED0-LED7分别连接PC0-PC7。
电阻R是限流电阻。Rmax = (3300 - 2000)mV/1mA = 1.3K
Rmin = (3300 - 2000)mV/20mA = 65R,这里取了510R。
当单片机为低电平的时候LED亮,高电平时候LED灭。

蜂鸣器

蜂鸣器从结构区分分为压电式蜂鸣器和电磁式蜂鸣器。压电式为压电陶瓷片发音,电流比较小一些,电磁式蜂鸣器为线圈通电震动发音,体积比较小。
按照驱动方式分为有源蜂鸣器和无源蜂鸣器。这里的有源和无源不是指电源,而是振荡源。有源蜂鸣器内部带了振荡源,两端有电压就会响。无源蜂鸣器则没有自带震荡电路,必须外部提供 2~5Khz 左右的方波驱动,才能发声。我们能否直接用单片机IO口来驱动蜂鸣器呢?
让我们来分析下:STM32 的单个 IO 最大可以提供 25mA 电流(来自数据手册),而蜂鸣器的驱动电流是 30mA 左右, 两者十分相近,但是全盘考虑,STM32 整个芯片的电流,最大也就 150mA,所以我们用了一个 PNP 三极管(S8550)来驱动蜂鸣器,R25 主要用于控制 PNP 管饱和导通作用。当 PB.8 输出低电平的时候,蜂鸣器将发声,当 PB.8 输出高电平的时候,蜂鸣器停止发声。
在这里插入图片描述

2.2软件设计

利用我们上节课讲的HAL库的工程模板,拷贝一份到新的文件中,然后在工程模板的根目录下新建HARDWARE文件夹,如下图所示。
在这里插入图片描述
这个HARDWARE文件夹里面就是放我们所涉及的外设,比如LED,BEEP,我们就在里面新建对应外设文件夹。接着打开该工程,创建HARDWARE组,添加新建对应外设的.c和.h文件并添加到该组里面。如led.c。

LED灯软件设计

STM32CubuMX 配置 实现8个LED灯的初始化。具体实现就不展开分析。生成代码后打开工程main.c文件中MX_GPIO_Init()就是LED的初始化函数。把该函数复制到我们的led.c文件中。

static void MX_GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct;/* GPIO Ports Clock Enable */__HAL_RCC_GPIOC_CLK_ENABLE();/*Configure GPIO pin Output Level */HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3 |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7, GPIO_PIN_RESET);/*Configure GPIO pins : PC0 PC1 PC2 PC3 PC4 PC5 PC6 PC7 */GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3 |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}

接下来分析GPIO和主要HAL库函数,查看对应的hal库stm32f1xx_hal_gpio.c文件进行分析。

  • __HAL_RCC_GPIOC_CLK_ENABLE();时钟打开与关闭
  • HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init);初始化GPIO
  • HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin);回复默认的GPIO引脚
  • GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);读出GPIOx对应的IO口电平状态
  • HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);写GPIOx对应的IO口电平状态
  • HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);翻转GPIOx对应的IO口电平状态。
    我们要实现流水灯,如何实现呢?循环实现,位操作。如下代码所示。
//软件延时
void LED_Delay(void)
{u32 i = 0;u32 j = 0;for(i = 0; i < 10000; i++){for(j = 0; j < 500; j++){;}}
}
//LED流水灯测试功能
void LED_Test(void)
{u8 i = 0;u16 pin = GPIO_PIN_0;for(i = 0 ; i < 8; i++){//先全部灭了8个灯HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3 |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7, GPIO_PIN_SET);//从左到右点亮led灯HAL_GPIO_WritePin(GPIOC, pin, GPIO_PIN_RESET);LED_Delay();pin = pin << 1;}
}

最后在编译成功之后,我们就可以下载代码到 NANO STM32 开发板上,实际验证一下我们的程序是否正确。
作业1:编写代码实现控制蜂鸣器的响或者灭。

三.GPIO输入功能HAL库编程实现的应用

3.1硬件设计

在这里插入图片描述
按键电路及其引脚链接如上图所示,KEY0-KEY2默认是高电平,按下是低电平,WK_UP按下是高电平,默认是低电平。

3.2软件设计

我们跟上节软件设计一样利用HAL库的工程模板,拷贝一份到新的文件中,然后在工程模板的根目录下新建HARDWARE文件夹,我们就在里面新建对应外设文件夹。接着打开该工程,创建HARDWARE组,添加新建对应外设的.c和.h文件并添加到该组里面。

按键KEY软件设计

STM32CubuMX 配置实现4个LED灯的初始化和4个KEY的初始化。具体实现就不展开分析。生成代码后打开工程main.c文件中MX_GPIO_Init()就是LED的初始化函数。把该函数复制到我们的KEY.c文件中。

static void MX_GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct;/* GPIO Ports Clock Enable */__HAL_RCC_GPIOC_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOD_CLK_ENABLE();/*Configure GPIO pin Output Level */HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2, GPIO_PIN_SET);/*Configure GPIO pins : PC0 PC1 PC2 */GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);/*Configure GPIO pin : PA0 */GPIO_InitStruct.Pin = GPIO_PIN_0;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_PULLDOWN;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);/*Configure GPIO pins : PC8 PC9 */GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_PULLUP;HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);/*Configure GPIO pin : PD2 */GPIO_InitStruct.Pin = GPIO_PIN_2;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_PULLUP;HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);}

那接下来判断按键状态,相应的控制led灯的亮灭。
常规的根据按下的电平编写逻辑,有啥问题?根据现象进行思考?

void KEY_Scan1(void)
{//KEY0按下if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_8)){
//		delay_ms(10);  //防抖动
//		if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_8)){
//			HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_0);
//		}HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_0);}//KEY1按下if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_9)){HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_1);}//KEY2按下if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_2)){HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_2);}//KEY_UP按下if(GPIO_PIN_SET == HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)){HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2, GPIO_PIN_RESET);}
}

现象:按键不灵,多次执行;原因:按键抖动,软件查询的方式处理导致多次扫描到。怎么解决整个问题?
抖动/消抖:通常按键所用的开关都是机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上就稳定的接通,在断开时也不会一下子彻底断开,而是在闭合和断开的瞬间伴随了一连串的抖动。

按键稳定闭合时间长短是由操作人员决定的,通常都会在 100ms 以上,刻意快速按的话能达到 40-50ms 左右,很难再低了。抖动时间是由按键的机械特性决定的,一般都会在 10ms以内,为了确保程序对按键的一次闭合或者一次断开只响应一次,必须进行按键的消抖处理。当检测到按键状态变化时,不是立即去响应动作,而是先等待闭合或断开稳定后再进行处理。
按键消抖可分为硬件消抖和软件消抖。
硬件消抖就是在按键上并联一个电容。这是利用电容的充放电来消抖。实际项目中这样的效果不是很好,因为电容值很难精确确定,不经常使用。

最简单的软件消抖原理,就是当检测到按键按下后,先等待一个 10ms 左右的延时时间,让抖动消失后再进行一次按键状态检测,如果与刚才检测到的状态相同,就可以确认按键已经稳定的动作了。

if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_8)){delay_ms(10);  //防抖动if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_8)){HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_0);}
}

对此判断:上一次按下的键值和当此的按下的键值是否不相等,相等就说明多次扫描到,不相等才有效。所以整合代码。

//KEY 扫描,获得键值
u8 KEY_Scan(void)
{u8 keynum = KEYNOPRESS;		//默认没有按键按下,也就是都是弹起状态//KEY0按下if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_8)){keynum = KEY0;}//KEY1按下if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_9)){keynum = KEY1;}//KEY2按下if(GPIO_PIN_RESET == HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_2)){keynum = KEY2;}//KEY_UP按下if(GPIO_PIN_SET == HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)){keynum = KEYUP;}return keynum;
}//KEY处理
void KEY_Handle(void)
{static u8 lastkey = KEYNOPRESS;u8 keynum = 0;keynum = KEY_Scan(); //获取键值//上一次的键值和当此的键值是否不相等,说明有按键按下if(keynum != lastkey){delay_ms(10);  //防抖动if(keynum == KEY_Scan()){	//再次获取键值,有没有发生改变,按键有效if(KEY0 == keynum){HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_0);}else if(KEY1 == keynum){HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_1);}else if(KEY2 == keynum){HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_2);}else if(KEYUP == keynum){HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2, GPIO_PIN_RESET);}lastkey = keynum;	//更新上一次的键值} }
}

最后在编译成功之后,我们就可以下载代码到 NANO STM32 开发板上,实际验证一下我们的程序是否正确。

作业2:通过按键KEY1和KEY_UP控制蜂鸣器的响或者灭。KEY1按下响,KEY_UP按下不响。

相关文章:

STM32微控制器_03_GPIO原理与应用

核心内容 STM32 GPIO基本原理&#xff08;熟悉&#xff09;GPIO输出功能HAL库编程实现的应用&#xff08;重点&#xff09;GPIO输入功能HAL库编程实现的应用&#xff08;重点&#xff09; 一.STM32 GPIO基本原理 1.GPIO简介 STM32的GPIO相当于STM32的四肢&#xff0c;一个S…...

零拷贝分析

kafka 零拷贝 请求 - 网口 - socket - 用户态 - 内核缓存区 - 内核态&#xff08;磁盘信息&#xff09; 磁盘 - 内核缓存区 - 用户缓存区 - 网络缓存区 零拷贝&#xff08;Zero-Copy&#xff09; 是一种高效的数据传输技术&#xff0c;旨在减少数据在内存中的拷贝次数&#x…...

爬虫逆向:详细讲述Android底层原理及机制

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Android系统架构1.1 Linux内核层1.2 硬件抽象层(HAL)1.3 系统运行库层1.4 应用框架层1.5 应用层二、Android启动过程三、进程与线程管理四、内存管理机制五、Binder机制六、安全机制七、电源管理机制八、Android …...

电容器基础观念

Take-away: 电容器容值&#xff0c;和「导体的几何形状」&#xff0c;「周围的介电材料」相关。电力线起于正电荷&#xff0c;终止于负电荷。金属互相越靠近&#xff0c;电容越大。Maxwell电容矩阵有负号&#xff0c;SPICE电容矩阵没有负号。Maxwell电容矩阵、SPICE电容矩阵可…...

Python 视频爬取教程

文章目录 前言基本原理环境准备Python安装选择Python开发环境安装必要库 示例 1&#xff1a;爬取简单直链视频示例 2&#xff1a;爬取基于 HTML5 的视频&#xff08;以某简单视频网站为例&#xff09; 前言 以下是一个较为完整的 Python 视频爬取教程&#xff0c;包含基本原理…...

NumPy系列 - 创建矩阵

目录 前传直接创建数组就只是创建数组1. np.array()2. np.arange()3. np.ones()4. numpy.ones_like()5. np.zeros()6. numpy.zeros_like() 定义数据类型 参考资料 前传 由于&#xff0c;某人在上智能相关课程的时候&#xff0c;总想着一大堆的事情&#xff0c;统计股市涨跌&am…...

从Instagram到画廊:社交平台如何改变艺术家的展示方式

从Instagram到画廊&#xff1a;社交平台如何改变艺术家的展示方式 在数字时代&#xff0c;艺术家的展示方式正在经历一场革命。社交平台&#xff0c;尤其是Instagram&#xff0c;已经成为艺术家展示作品、与观众互动和建立品牌的重要渠道。本文将探讨社交平台如何改变艺术家的…...

谈谈 TypeScript 中的联合类型(union types)和交叉类型(intersection types),它们的应用场景是什么?

一、联合类型&#xff08;Union Types&#xff09; 核心概念 使用管道符 | 表示多选一关系&#xff0c;典型场景&#xff1a;处理可能存在多种类型的变量 // 基础示例&#xff1a;处理数值型ID&#xff08;number&#xff09;或哈希型ID&#xff08;string&#xff09; type…...

华为OD机试 - 最长的完全交替连续方波信号(Java 2023 B卷 200分)

题目描述 给定一串方波信号,要求找出其中最长的完全连续交替方波信号并输出。如果有多个相同长度的交替方波信号,输出任意一个即可。方波信号的高位用1标识,低位用0标识。 说明: 一个完整的信号一定以0开始并以0结尾,即010是一个完整的信号,但101,1010,0101不是。输入的…...

✎ 一次有趣的经历

&#x1f4c6;2025年3月17日 | 周一 | ☀️晴 &#x1f4cd;今天路过学院楼7&#xff0c;见到了满园盛开的花&#x1f33a;&#xff0c;心情瞬间明朗&#xff01; &#x1f4cc;希望接下来的日子也能像这些花一样&#xff0c;充满活力&#x1f525;&#xff01; &#x1…...

【Spring】第二弹:通过反射机制初步理解 IoC

一、Java 反射机制 Java反射机制是在运行状态中&#xff0c;对于任意一个类&#xff0c;都能够知道这个类的所有属性和方法&#xff1b;对于任意一个对象&#xff0c;都能够调用它的任意方法和属性&#xff1b;这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机…...

快!快!快!NDPP时延测试数据公布!

在全方位认识NDPP第3期《NDPP在金融场景的应用》中&#xff0c;我们重点介绍了NDPP的典型应用场景行情解码硬件加速和策略计算加速&#xff0c;并帮助某百亿私募用户基于NDPP实现期货业务加速的案例。 近期&#xff0c;中科驭数凭借低时延产品荣获信创“大比武”行业融合赛道三…...

激光雷达“开卷”2.0,头部Tier1入局

高阶智驾的普及&#xff0c;正在催生激光雷达市场的巨大潜在增长空间。 本周&#xff0c;汽车激光雷达主力供应商之一的禾赛科技发布财报&#xff0c;去年第四季度激光雷达总交付量为222,054台&#xff0c;同比增长153.1%&#xff0c;超过2023年全年。2024全年激光雷达总交付量…...

STM32 - 在机器人领域,LL库相比HAL优势明显

在机器人控制器、电机控制器等领域的开发&#xff0c;需要高实时性、精细化控制或者对代码执行效率、占用空间有较高要求。所以&#xff0c;大家常用的HAL库明显不符合要求。再加上&#xff0c;我们学习一门技术&#xff0c;一定要学会掌握底层的原理。MCU开发的底层就是寄存器…...

力扣No.376.摆动序列

题目&#xff1a; 链接&#xff1a; https://leetcode.cn/problems/wiggle-subsequence/description/ 代码&#xff1a; class Solution {public int wiggleMaxLength(int[] nums) {int nnums.length;//状态表示:int[] fnew int[n];int[] gnew int[n];//初始化:for(int i0;i…...

找工作、创业的思考和出路

最近有几位朋友在找工作&#xff0c;以及探索职场出路&#xff0c;与他们聊了一些关于找工作和职业发展的话题。而这些话题对大多数职场人来说&#xff0c;都是必须考虑和面对的问题。今天就基于这两个话题展开聊聊。 首先&#xff0c;初入职场时&#xff0c;工作是相对容易找…...

IP关联是什么?怎么避免?

在跨境电商的道路上&#xff0c;大家好&#xff01;今天想和大家聊一聊一个非常重要的话题&#xff0c;那就是IP关联的问题。在商业活动中&#xff0c;了解如何避免IP关联对保护我们宝贵的商铺至关重要。接下来&#xff0c;我们将深入探讨IP关联的概念、影响及如何有效防止这一…...

C语言中qsort函数的详解,以及模拟

引言 C语言中qsort函数的详解和模拟实现qsort函数&#xff0c;这里为了使用冒泡排序来模拟qsort函数 一、详解qsort函数 在 C 语言中&#xff0c;qsort 函数是一个标准库函数&#xff0c;用于对数组进行快速排序&#xff08;Quick Sort&#xff09;。它位于 <stdlib.h>…...

9、讲一讲你理解的虚拟内存【中高频】

计算机早期&#xff0c;CPU 是直接操作 物理内存&#xff08;Physical Memory&#xff09;的&#xff0c;但这会导致 内存空间无法完全隔离&#xff0c;一个程序修改了另一个程序的地址空间&#xff0c;就会导致程序崩溃&#xff1b;同时物理内存大小有限&#xff0c;一旦超出这…...

算法刷题整理合集(四)

本篇博客旨在记录自已的算法刷题练习成长&#xff0c;里面注有详细的代码注释以及和个人的思路想法&#xff0c;希望可以给同道之人些许帮助。本人也是算法小白&#xff0c;水平有限&#xff0c;如果文章中有什么错误或遗漏之处&#xff0c;望各位可以在评论区指正出来&#xf…...

高数1.5 极限的运算法则

1. 预备知识 2.四则求极限法则 3.复合运算求极限法则...

【鸿蒙开发】Hi3861学习笔记- 定时器中断

00. 目录 文章目录 00. 目录01. 概述02. 定时器相关API2.1 hi_timer_create2.2 hi_timer_start2.3 hi_timer_stop2.4 hi_timer_delete 03. 硬件设计04. 软件设计05. 实验现象06. 附录 01. 概述 定时器&#xff0c;顾名思义就是用来计时的&#xff0c;我们常常会设定计时或闹钟…...

Spring Cloud Config 快速介绍与实例

Spring Cloud Config 是什么? Spring Cloud Config 是一个用于分布式系统的配置管理工具,提供集中化的外部配置支持。它适用于微服务架构,能够将各个服务的配置集中存储在服务端(如 Git 仓库),客户端按需动态获取配置,解决了配置分散、环境切换复杂等问题。 Spring Cl…...

Power Apps 技术分享:画布应用使用表单控件

前言 表单控件&#xff0c;是画布应用里一个非常好用的控件&#xff0c;我们今天简单介绍下&#xff0c;如何使用这个控件。 正文 1.首先&#xff0c;我们需要有一个数据源&#xff0c;我们这里用上一篇博客新建的数据源&#xff0c;如下图&#xff1a; 2.新建一个页面&#xf…...

【数据库】Data Model(数据模型)数据模型分析

理解图片中的 Data Model&#xff08;数据模型&#xff09;是学习数据库设计和应用程序开发的重要一步。作为初学者&#xff0c;你可以通过比喻和简单的解释来理解这些概念以及它们之间的联系。以下是对图片中数据模型的详细分析&#xff0c;以及如何理解它们之间的关系。 1. 数…...

【Unity】 HTFramework框架(六十二)Agent编辑器通用智能体(AI Agent)

更新日期&#xff1a;2025年3月14日。 Github源码&#xff1a;[点我获取源码] Gitee源码&#xff1a;[点我获取源码] 索引 编辑器通用智能体AIAgent类Friday&#xff08;星期五&#xff09;启用智能体设置智能体类型开放智能体权限智能体交互资源优化批处理运行代码联网搜索休闲…...

Elasticsearch 滚动索引(Rollover Index)详解

文章目录 1、滚动索引的作用2、滚动索引的用法2.1 核心概念2.2 实现步骤 3、适用场景4、与其他技术的结合使用5、案例&#xff1a;日志数据的滚动索引5.1 场景描述5.2 实现步骤 6、示例&#xff1a;结合索引生命周期管理&#xff08;ILM&#xff09;6.1 场景描述6.2 实现步骤 7…...

学习笔记:黑马程序员JavaWeb开发教程(2025.3.17)

11.5 案例-文件上传-阿里云OSS-入门 出现报错&#xff1a;Process exited with an error: 1 (Exit value: 1)&#xff0c;点击exec那一行&#xff0c;出现错误原因&#xff1a;Command execution failed. 在CSDN上找到了解决方法&#xff1a; 之后出现新的报错&…...

python局部变量和全局变量

文章目录 1.局部变量和全局变量2.局部变量2.1 局部变量的作用2.2 局部变量的生命周期 3. 全局变量3.1 函数不能直接修改全局变量的引用3.2 在函数内部修改全局变量的值3.3 全局变量定义的位置3.4 全局变量命名的建议 1.局部变量和全局变量 &#xff08;1&#xff09;局部变量 …...

攻克 3D 模型网站建设难题,看迪威系统优势

在当今数字化时代&#xff0c;3D 模型广泛应用于建筑设计、游戏开发、工业制造、文化创意等诸多领域。拥有一个功能强大的 3D 模型网站&#xff0c;对于企业展示产品、设计师分享作品、教育机构开展教学等都具有重要意义。然而&#xff0c;构建这样一个网站却并非易事&#xff…...