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

stm32外设-GPIO

0. 写在最前

本栏目笔记都是基于stm32F10x

1. GPIO基本介绍

GPIO—general purpose intput output
是通用输入输出端口的简称,简单来说就是软件可控制的引脚, STM32芯片的GPIO引脚与外部设备连接起来,从而实现与外部通讯、控制以及数据采集的功能

2. GPIO功能框图介绍

GPIO功能框图如下:

在这里插入图片描述

  1. 保护二极管及上、下拉电阻

引脚的两个保护二级管可以防止引脚外部过高或过低的电压输入,当引脚电压高于VDD 时,上方的二极管导通,当引脚电压低于VSS时,下方的二极管导通,防止不正常电压引入芯片导致芯片烧毁。尽管有这样的保护,并不意味着STM32的引脚能直接外接大功率驱动器件,如直接驱动电机,强制驱动要么电机不转,要么导致芯片烧坏,必须要加大功率及隔离电路驱动。

  1. P-MOS 管和N-MOS 管

GPIO 引脚线路经过两个保护二极管后,向上流向“输入模式”结构,向下流向“输出模式”结构。先看输出模式部分,线路经过一个由P-MOS 和N-MOS管组成的单元电路。这个结构使GPIO具有了“推挽输出”“开漏输出”两种模式。

  • 所谓的推挽输出模式,是根据这两个MOS 管的工作方式来命名的。在该结构中输入高电平时,经过反向后,上方的P-MOS 导通,下方的N-MOS关闭,对外输出高电平;而在该结构中输入低电平时,经过反向后,N-MOS 管导通,P-MOS 关闭,对外输出低电平。当引脚高低电平切换时,两个管子轮流导通,P管负责灌电流,N 管负责拉电流,使其负载能力和开关速度都比普通的方式有很大的提高。推挽输出的低电平为0伏,高电平为3.3伏,它是推挽输出模式时的等效电路。

  • 而在开漏输出模式时,上方的P-MOS 管完全不工作。如果我们控制输出为0,低电平,则P-MOS 管关闭,N-MOS 管导通,使输出接地,若控制输出为1 (它无法直接输出高电平)时,则P-MOS 管和N-MOS 管都关闭,所以引脚既不输出高电平,也不输出低电平,为高阻态。为正常使用时必须外部接上拉电阻。它具有“线与”特性,也就是说,若有很多个开漏模式引脚连接到一起时,只有当所有引脚都输出高阻态,才由上拉电阻提供高电平,此高电平的电压为外部上拉电阻所接的电源的电压。若其中一个引脚为低电平,那线路就相当于短路接地,使得整条线路都为低电平,0 伏。推挽输出模式一般应用在输出电平为0 和3.3 伏而且需要高速切换开关状态的场合。在STM32 的应用中,除了必须用开漏模式的场合,我们都习惯使用推挽输出模式。

    开漏输出一般应用在I2C、SMBUS 通讯等需要“线与”功能的总线电路中。除此之外,还用在电平不匹配的场合,如需要输出5 伏的高电平,就可以在外部接一个上拉电阻,上拉电源为5 伏,并且把GPIO 设置为开漏模式,当输出高阻态时,由上拉电阻和电源向外输出5 伏的电平。

  1. 输出数据寄存器

前面提到的双MOS 管结构电路的输入信号, 是由GPIO“ 输出数据寄存器GPIOx_ODR”提供的,因此我们通过修改输出数据寄存器的值就可以修改GPIO 引脚的输出电平。而“置位/复位寄存器GPIOx_BSRR”可以通过修改输出数据寄存器的值从而影响电路的输出。

  1. 复用功能输出

“复用功能输出”中的“复用”是指STM32 的其它片上外设对GPIO 引脚进行控制,此时GPIO 引脚用作该外设功能的一部分,算是第二用途。从其它外设引出来的“复用功能输出信号”与GPIO本身的数据据寄存器都连接到双MOS 管结构的输入中,通过图中的梯形结构作为开关切换选择。

例如我们使用USART 串口通讯时,需要用到某个GPIO引脚作为通讯发送引脚,这个时候就可以把该GPIO引脚配置成USART 串口复用功能,由串口外设控制该引脚,发送数据。

  1. 输入数据寄存器

看GPIO 结构框图的上半部分,GPIO 引脚经过内部的上、下拉电阻,可以配置成上/下拉输入,然后再连接到施密特触发器,信号经过触发器后,模拟信号转化为0、1 的数字信号,然后存储在“输入数据寄存器GPIOx_IDR”中,通过读取该寄存器就可以了解GPIO引脚的电平状态。

  1. 复用功能输入

与“复用功能输出”模式类似,在“复用功能输入模式”时,GPIO引脚的信号传输到STM32 其它片上外设,由该外设读取引脚状态。同样,如我们使用USART 串口通讯时,需要用到某个GPIO引脚作为通讯接收引脚,这个时候就可以把该GPIO 引脚配置成USART 串口复用功能,使USART 可以通过该通讯引脚的接收远端数据。

  1. 模拟输入输出

当GPIO 引脚用于ADC 采集电压的输入通道时,用作“模拟输入”功能,此时信号是不经过施密特触发器的,因为经过施密特触发器后信号只有0、1 两种状态,所以ADC 外设要采集到原始的模拟信号,信号源输入必须在施密特触发器之前。类似地,当GPIO 引脚用于DAC 作为模拟电压输出通道时,此时作为“模拟输出”功能,DAC 的模拟信号输出就不经过双MOS 管结构,模拟信号直接输出到引脚。

3. GPIO工作模式

标准库中用枚举对象实现模型的选择,并在GPIO_Init函数传入结构体对寄存器进行操作:

typedef enum
{ GPIO_Mode_AIN = 0x0,GPIO_Mode_IN_FLOATING = 0x04,GPIO_Mode_IPD = 0x28,GPIO_Mode_IPU = 0x48,GPIO_Mode_Out_OD = 0x14,GPIO_Mode_Out_PP = 0x10,GPIO_Mode_AF_OD = 0x1C,GPIO_Mode_AF_PP = 0x18
}GPIOMode_TypeDef;

输出模式:

在输出模式中,推挽模式时双MOS 管以轮流方式工作,输出数据寄存器GPIOx_ODR可控制I/O 输出高低电平。开漏模式时,只有N-MOS 管工作,输出数据寄存器可控制I/O输出高阻态或低电平。输出速度可配置,有2MHz\10MHz\50MHz 的选项。此处的输出速度即I/O 支持的高低电平状态最高切换频率,支持的频率越高,功耗越大,如果功耗要求不严格,把速度设置成最大即可。

在输出模式时施密特触发器是打开的,即输入可用,通过输入数据寄存器GPIOx_IDR可读取I/O 的实际状态。

  • 推挽输出:GPIO可以输出高电平或低电平,驱动外部设备,如LED、蜂鸣器等。
  • 开漏输出:GPIO只能输出低电平,高电平由外部上拉电阻提供,适用于电平不匹配或多个设备共用一条线的场合,如IIC总线等。

输入模式:

在输入模式时,施密特触发器打开,输出被禁止,可通过输入数据寄存器GPIOx_IDR读取I/O 状态。其中输入模式,可设置为上拉、下拉、浮空和模拟输入四种。上拉和下拉输入很好理解,默认的电平由上拉或者下拉决定。浮空输入的电平是不确定的,完全由外部的输入决定,一般接按键的时候用的是这个模式。模拟输入则用于ADC 采集。

  • 浮空输入:GPIO不连接任何元件,只接收外部信号,适用于信号源具有较强驱动能力的场合,如编码器、PWM捕获等。
  • 上拉输入:GPIO连接一个内部上拉电阻,使输入信号默认为高电平,适用于信号源具有较弱驱动能力的场合,如按键、UART接收等。
  • 下拉输入:GPIO连接一个内部下拉电阻,使输入信号默认为低电平。
  • 模拟输入:GPIO可以采集外部模拟信号,并转换为数字信号,适用于ADC转换等场合。

复用功能:

复用功能模式中,输出使能,输出速度可配置,可工作在开漏及推挽模式,但是输出信号源于其它外设,输出数据寄存器GPIOx_ODR 无效;输入可用,通过输入数据寄存器可获取I/O 实际状态,但一般直接用外设的寄存器来获取该数据信号。

  • 复用功能:GPIO可以配置为特定的功能引脚,如定时器、串口、SPI等外设的通道。
  • 模拟功能:GPIO可以关闭数字功能和内部寄存器,并作为纯粹的模拟引脚。

4. 寄存器介绍

每个GPI/O端口有两个32位配置寄存器(GPIOx_CRLGPIOx_CRH),两个32位数据寄存器(GPIOx_IDRGPIOx_ODR),一个32位置位/复位寄存器(GPIOx_BSRR),一个16位复位寄存器(GPIOx_BRR)和一个32位锁定寄存器(GPIOx_LCKR)。

4.1 GPIOx_CRL

在这里插入图片描述

GPIOx_CRL是一个32位的寄存器,用来配置GPIO端口的低8位(GPIOx0~GPIOx7)的工作模式。每4位对应一个引脚,分别设置其模式(MODE)和配置(CNF)。例如,要设置GPIOA0为推挽输出模式,输出频率为10MHz,可以写:

// 将GPIOA0的MODE[1:0]设为01,表示输出频率为10MHz
// 将GPIOA0的CNF[1:0]设为00,表示推挽输出模式
GPIOA->CRL &= 0xFFFFFFF0; // 清零低4位
GPIOA->CRL |= 0x00000001; // 设置低4位为0001

类似地,要设置GPIOA7为上拉输入模式,可以写:

// 将GPIOA7的MODE[1:0]设为00,表示输入模式
// 将GPIOA7的CNF[1:0]设为10,表示上拉输入模式
GPIOA->CRL &= 0x0FFFFFFF; // 清零高4位
GPIOA->CRL |= 0x80000000; // 设置高4位为1000

4.2 GPIOx_CRH

在这里插入图片描述

GPIOx_CRH是一个32位的寄存器,用来配置GPIO端口的高8位(GPIOx8~GPIOx15)的工作模式。它的结构和功能与GPIOx_CRL相同,只是对应的引脚不同。例如,要设置GPIOA8为开漏输出模式,输出频率为50MHz,可以写:

// 将GPIOA8的MODE[1:0]设为11,表示输出频率为50MHz
// 将GPIOA8的CNF[1:0]设为01,表示开漏输出模式
GPIOA->CRH &= 0xFFFFFFF0; // 清零低4位
GPIOA->CRH |= 0x00000007; // 设置低4位为0111

类似地,要设置GPIOA15为下拉输入模式,可以写:

// 将GPIOA15的MODE[1:0]设为00,表示输入模式
// 将GPIOA15的CNF[1:0]设为10,表示下拉输入模式
GPIOA->CRH &= 0x0FFFFFFF; // 清零高4位
GPIOA->CRH |= 0x80000000; // 设置高4位为1000

4.3 GPIOx_IDR

在这里插入图片描述

GPIOx_IDR是一个32位的寄存器,用来读取GPIO端口的输入电平状态。每一位对应一个引脚,0表示低电平,1表示高电平。例如,要读取GPIOA0的输入电平,可以写:

// 读取GPIOA->IDR的第0位,即GPIOA0的输入电平
uint8_t input = (GPIOA->IDR & 0x00000001) >> 0;

类似地,要读取GPIOA15的输入电平,可以写:

// 读取GPIOA->IDR的第15位,即GPIOA15的输入电平
uint8_t input = (GPIOA->IDR & 0x00008000) >> 15;

(GPIOA->IDR & 0x00008000) >>15是一个位运算表达式,用来提取GPIOA->IDR的第15位的值。它的含义是:

  • GPIOA->IDR是一个32位的寄存器,存储了GPIOA端口的输入电平状态,每一位对应一个引脚。
  • 0x00008000是一个16进制数,表示二进制的00000000 00000000 10000000 00000000。
  • &是按位与运算符,表示将两个操作数的每一位进行逻辑与运算,只有当两个操作数的同一位都为1时,结果才为1,否则为0。
  • >>是右移运算符,表示将左边的操作数向右移动指定的位数,左边空出的位置用0填充。
  • 15是右移运算符的右边操作数,表示移动15位。

所以(GPIOA->IDR & 0x00008000) >>15的计算过程如下:

  • 假设GPIOA->IDR的值为11111111 11111111 11111111 10101010(随机举例)。
  • 将GPIOA->IDR和0x00008000进行按位与运算,得到:
// 按位与运算
11111111 11111111 11111111 10101010
& // 按位与
00000000 00000000 10000000 00000000
= // 结果
------------------------------------
00000000 00000000 10000000 00101010
  • 将上一步得到的结果向右移动15位,得到:
// 右移运算
( // 左括号// 上一步得到的结果// 移动前:32个二进制数字(省略了前面28个)00000000 00000000 10000000 00101010// 移动后:32个二进制数字(省略了前面28个)00000000 00000000 00000000 00000001
) // 右括号
>> // 右移
15 // 移动15位(不变)
= // 结果
------------------------------------
... ...
  • 最终得到结果为:
// 最终结果:32个二进制数字(省略了前面31个)
... ...

因此(GPIOA->IDR & 0x8000) >>15就相当于读取GPIOA->IDR寄存器中第15位置上是否为1或者说是否为高电平。

4.4 GPIOx_ODR

在这里插入图片描述

GPIOx_ODR是端口输出数据寄存器,它的低16位对应x的相应引脚,用来设置或读取引脚的状态。例如,如果你想让GPIOE的第8个引脚输出高电平,你可以写

GPIOE->ODR |= 0x0100 // 0000000100000000

4.5 GPIOx_BSRR

在这里插入图片描述

GPIOx_BSRR是端口位设置/复位寄存器,它的高16位是清除位,用来复位对应的引脚;低16位是设置位,用来设置对应的引脚。这样可以保证操作某个端口时对其他端口无影响。例如,如果你想让GPIOE的第8个引脚输出高电平,你可以写

GPIOE->BSRR = 0x0100;

4.6 GPIOx_BRR

在这里插入图片描述

GPIOx_BRR是端口位清除寄存器,它的低16位对应x的相应引脚,用来复位对应的引脚。例如,如果你想让GPIOE的第8个引脚输出低电平,你可以写GPIOE->BRR = 0x0100。它与GPIOx_BSRR的高16位具有相同功能

4.7 GPIOx_BSRR和GPIOx_BRR异同

既然GPIOx_BSRR都可以做复位操作,那么它们有什么不同呢?

  • GPIOx_BRR和GPIOx_BSRR都可以用来控制GPIO的输出,但是有一些区别GPIOx_BRR只有低16位有效,而GPIOx_BSRR有高16位和低16

  • GPIOx_BRR的低16位是复位操作,而GPIOx_BSRR的高16位是复位操作,低16位是设置操作

  • GPIOx_BRR和GPIOx_BSRR的优先级相同,如果同时写入两个寄存器,那么复位操作会覆盖设置操作

4.8 GPIOx_BSRR和GPIOx_ODR

GPIOx_BSRR和GPIOx_ODR都可以用来控制GPIO的输出,但是有一些区别

  • GPIOx_BSRR可以单独设置或复位某个引脚,而GPIOx_ODR需要对整个端口进行读写操作
  • GPIOx_BSRR是原子操作,不会影响其他引脚的状态,而GPIOx_ODR可能会产生竞争条件
  • GPIOx_BSRR有高16位和低16位,分别对应复位和设置操作,而GPIOx_ODR只有低16位有效

一般来说,如果你需要对单个引脚进行快速和安全的控制,那么GPIOx_BSRR可能更合适;如果你需要对整个端口进行统一的控制,那么GPIOx_ODR可能更方便。

5. 标准库常用函数

  • GPIO_DeInit():复位GPIO端口的所有引脚为默认状态。
  • GPIO_Init():初始化GPIO端口的某个或多个引脚。
  • GPIO_StructInit():将GPIO_InitTypeDef结构体的成员初始化为默认值。
  • GPIO_ReadInputDataBit():读取GPIO端口的某个输入引脚的状态。
  • GPIO_ReadInputData():读取GPIO端口的所有输入引脚的状态。
  • GPIO_ReadOutputDataBit():读取GPIO端口的某个输出引脚的状态。
  • GPIO_ReadOutputData():读取GPIO端口的所有输出引脚的状态。
  • GPIO_SetBits():设置GPIO端口的某个或多个输出引脚为高电平。
  • GPIO_ResetBits():设置GPIO端口的某个或多个输出引脚为低电平。
  • GPIO_WriteBit():设置GPIO端口的某个输出引脚为指定电平。
  • GPIO_Write():设置GPIO端口的所有输出引脚为指定电平。
void GPIO_DeInit(GPIO_TypeDef* GPIOx);
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct);
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);

6. 写在最后

给个赞吧😄

相关文章:

stm32外设-GPIO

0. 写在最前 本栏目笔记都是基于stm32F10x 1. GPIO基本介绍 GPIO—general purpose intput output 是通用输入输出端口的简称,简单来说就是软件可控制的引脚, STM32芯片的GPIO引脚与外部设备连接起来,从而实现与外部通讯、控制以及数据采集的…...

AfxMessageBox 自定义封装

一般情况下AfxMessageBox是系统提供的一个对话框,若要做这种效果的,必须重写。 实例1: void test_SgxMemDialog_AutoSize() { //使用给定大小的对话框 CSgxMemDialog dlg(180, 60); dlg.SetWindowTitle(_T(" SegeX - CT&qu…...

登入vCenter显示503,证书过期解决办法

登入vCenter显示503 原因:当安全令牌服务 (STS) 证书已过期时,会出现这些问题。这会导致内部服务和解决方案用户无法获取有效令牌,从而导致无法按预期运行(证书两年后就会过期)。 解决办法&…...

设计模式(十九)----行为型模式之命令模式

1、概述 日常生活中,我们出去吃饭都会遇到下面的场景。 定义: 将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通,这样方便将命令对象进行存储、传递、调用、增加与管理。命…...

【数据库】数据库基础架构

数据库架构 数据库对于后端程序员来说是每天都需要打交道的系统,因此了解并掌握MySQL底层原理是必须的。 基础架构图 MySQL内部分为两层,一个是Server层,另一个是存储引擎层,而我们常用的就是MyISAM、InnoDB,主要负…...

English Learning - L2 语音作业打卡 双元音 [ɔɪ] [ɪə] Day16 2023.3.8 周三

English Learning - L2 语音作业打卡 双元音 [ɔɪ] [ɪə] Day16 2023.3.8 周三💌发音小贴士:💌当日目标音发音规则/技巧:🍭 Part 1【热身练习】🍭 Part2【练习内容】🍭【练习感受】🍓元音 [ɔ…...

C++语法规则4(C++面向对象)

接口(抽象类) 接口描述了类的行为和功能,而不需要完成类的特定实现。C 接口是使用抽象类来实现的,抽象类与数据抽象互不混淆,数据抽象是一个把实现细节与相关的数据分离开的概念。 如果类中至少有一个函数被声明为纯虚…...

【Spring 深入学习】AOP的前世今生之后续

AOP的前世今生之后续 1. 概述 上篇文章【Spring 深入学习】AOP的前世今生之代理模式我们讲述了代理模式。而我们今天的主人公AOP就是基于代理模式实现的,所以我们今天会简单学习下AOP 2. 什么是AOP 是面向切面编程,一般可以帮助我们在不修改现有代码的情…...

软考高项——配置管理

配置管理配置管理配置管理6个主要活动配置项配置基线配置项的状态配置库配置库权限管理配置审计配置管理 配置管理的总线索包括: 1)配置管理6个主要活动 2)配置项 3)配置基线 4)配置项的状态 5)配置库 6&a…...

网站SEO优化,网站TDK三大标签SEO优化,LOGO SEO优化

SEO(Search Engine Optimization)汉译为搜索引擎优化,是一种利用搜索引擎的规则提高网站在有关搜索 引擎内自然排名的方式。 SEO 的目的是对网站进行深度的优化,从而帮助网站获取免费的流量,进而在搜索引擎上提升网站的…...

select查询语句

worker表的字段有id, d_id, name, sex, birthday, salary, address 编号,部门号,姓名,性别,出生日期,工资,家庭住址 department表的字段有d_id, d_name, function, address 部门号,部门名,部门职能,部门位置 (1)查询worker表的所有记录(用*表示)。 select * fro…...

没有对象感,沟通太费劲

沟通中最重要的感觉:对象感! 要沟通的是谁?以啥方式最好? 趣讲大白话:蹲着跟小孩说话 【趣讲信息科技100期】 ******************************* 对象感是沟通者必须训练和提升的 是换位思考的一种能力 以便跟沟通对象进…...

智能优化算法之遗传算法

该算法已被很多篇文章讲解,本文将会去除很多较简单的内容,挑选认为重点核心部分进行讲述,内容中有属于信息的收集整理部分,也有属于自己理解的部分。 1、遗传算法概述 遗传算法是一类借鉴生物界的进化规律演化而来的随机化搜索方…...

【rabbitmq 实现延迟消息-插件版本安装(docker环境)】

一:插件简介 在rabbitmq 3.5.7及以上的版本提供了一个插件(rabbitmq-delayed-message-exchange)来实现延迟队列功能。同时插件依赖Erlang/OPT 18.0及以上。 二:插件安装 1:选择适合自己安装mq 版本的插件&#xff1…...

【大数据】HDFS管理员 HaAdmin 集群高可用命令详细使用说明

高可用HaAdmin使用概览使用说明checkHealth查看NameNode的状态所有NN的服务状态查询指定NN的服务状态failovertransitionToActive概览 HDFS高可用特性解决了集群单点故障问题,通过提供了两个冗余的NameNode以主动或被动的方式用于热备,使得集群既可以从…...

京区航天研究所 哪些比较好的研究所?

第一梯队:一院一部、战术武器部、10所、12所、研发部、空天部,五院501所(总体设计部)、502所、通导部、遥感部、钱室(所人均年薪35w-50w级别) 第二梯队:一院14所、15所,二院未来实验…...

Nacos配置拉取及配置动态刷新原理【源码阅读】

Nacos配置拉取及配置刷新原理 一、初始化时获取配置文件 背景 SpringCloud项目中SpringBoot在启动阶段除了会创建SpringBoot容器,还会通过bootstrap.yml构建一个SpringCloud容器,之后会在准备上下文阶段通过SPI加载实现类后,会进行配置合并…...

第十届省赛——9等差数列(集合做法)

题目:试题 I: 等差数列时间限制: 1.0s 内存限制: 512.0MB 本题总分:25 分【问题描述】数学老师给小明出了一道等差数列求和的题目。但是粗心的小明忘记了一部分的数列,只记得其中 N 个整数。现在给出这 N 个整数,小明想知道包含这…...

《数据分析-JiMuReport03》JiMuReport报表设计入门介绍-新建报表

报表设计 1 新建报表 1.1 创建新的数据报表 以数据报表为例,简单介绍创建报表的过程 1.2 进入报表设计页面 如下图可见,主要分为四个模块: 模块一(左) 数据集管理报表信息数据字典 模块二(右) 这部分是对数据报表的进一步优化 模块三(上…...

从功能测试进阶自动化测试,爆肝7天整理出这一份超全学习指南【附网盘资源】

因为我最近在分享自动化测试技术,经常被问到:功能测试想转自动化,请问应该怎么入手?有没有好的资源推荐?那么,接下来我就结合自己的经历聊一聊我是如何在工作中做自动化测试的。(学习路线和网盘…...

synchronized 学习

学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...

【JVM】- 内存结构

引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...

蓝桥杯 2024 15届国赛 A组 儿童节快乐

P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色&#xf…...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

全面解析各类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? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...

Docker 本地安装 mysql 数据库

Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...

C语言中提供的第三方库之哈希表实现

一. 简介 前面一篇文章简单学习了C语言中第三方库(uthash库)提供对哈希表的操作,文章如下: C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...

Django RBAC项目后端实战 - 03 DRF权限控制实现

项目背景 在上一篇文章中,我们完成了JWT认证系统的集成。本篇文章将实现基于Redis的RBAC权限控制系统,为系统提供细粒度的权限控制。 开发目标 实现基于Redis的权限缓存机制开发DRF权限控制类实现权限管理API配置权限白名单 前置配置 在开始开发权限…...