GPIO简介
GPIO 是通用输入输出端口的简称,简单来说就是 STM32 可控制的引脚,STM32 芯片
的 GPIO 引脚与外部设备连接起来,从而实现与外部通讯、控制以及数据采集的功能。
STM32 芯片的 GPIO 被分成很多组,每组有 16 个引脚,如型号为 STM32F103VET6 型号的
芯片有 GPIOA、GPIOB、GPIOC 至 GPIOE 共 5 组 GPIO,芯片一共 100 个引脚,其中
GPIO 就占了一大部分,所有的 GPIO 引脚都有基本的输入输出功能。
最基本的输出功能是由 STM32 控制引脚输出高、低电平,实现开关控制,如把 GPIO
引脚接入到 LED 灯,那就可以控制 LED 灯的亮灭,引脚接入到继电器或三极管,那就可
以通过继电器或三极管控制外部大功率电路的通断。

基本结构分析
下面我们按图中的编号对 GPIO 端口的结构部件进行说明。
在这里插入图片描述GPIO框图

1. 保护二极管及上、下拉电阻
引脚的两个保护二级管可以防止引脚外部过高或过低的电压输入,当引脚电压高于
VDD 时,上方的二极管导通,当引脚电压低于 VSS 时,下方的二极管导通,防止不正常电
压引入芯片导致芯片烧毁。尽管有这样的保护,并不意味着 STM32 的引脚能直接外接大功
率驱动器件,如直接驱动电机,强制驱动要么电机不转,要么导致芯片烧坏,必须要加大
功率及隔离电路驱动。
2. 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 管都关闭,所以引脚既不输出高电平,也不输出低电平,为高
阻态。为正常使用时必须外部接上拉电阻,参考图 8-3 中等效电路。它具有“线与”特性,
也就是说,若有很多个开漏模式引脚连接到一起时,只有当所有引脚都输出高阻态,才由
上拉电阻提供高电平,此高电平的电压为外部上拉电阻所接的电源的电压。若其中一个引
脚为低电平,那线路就相当于短路接地,使得整条线路都为低电平,0 伏。
推挽输出模式一般应用在输出电平为 0 和 3.3 伏而且需要高速切换开关状态的场合。 在 STM32 的应用中,除了必须用开漏模式的场合,我们都习惯使用推挽输出模式。
开漏输出一般应用在 I2C、SMBUS 通讯等需要“线与”功能的总线电路中。除此之外,
还用在电平不匹配的场合,如需要输出 5 伏的高电平,就可以在外部接一个上拉电阻,上 拉电源为 5 伏,并且把 GPIO 设置为开漏模式,当输出高阻态时,由上拉电阻和电源向外
输出 5 伏的电平
3. 输出数据寄存器
前面提到的 双 MOS 管结构电路的输入信号,是由 GPIO“输出数据寄存 器
GPIOx_ODR”提供的,因此我们通过修改输出数据寄存器的值就可以修改 GPIO 引脚的输
出电平。而“置位/复位寄存器 GPIOx_BSRR”可以通过修改输出数据寄存器的值从而影响
电路的输出。
4. 复用功能输出
“复用功能输出”中的“复用”是指 STM32 的其它片上外设对 GPIO 引脚进行控制,
此时 GPIO 引脚用作该外设功能的一部分,算是第二用途。从其它外设引出来的“复用功
能输出信号”与 GPIO 本身的数据据寄存器都连接到双 MOS 管结构的输入中,通过图中的
梯形结构作为开关切换选择。
例如我们使用 USART 串口通讯时,需要用到某个 GPIO 引脚作为通讯发送引脚,这个
时候就可以把该 GPIO 引脚配置成 USART 串口复用功能,由串口外设控制该引脚,发送数

5. 输入数据寄存器
看 GPIO 结构框图的上半部分,GPIO 引脚经过内部的上、下拉电阻,可以配置成上/
下拉输入,然后再连接到施密特触发器,信号经过触发器后,模拟信号转化为 0、1 的数字
信号,然后存储在“输入数据寄存器 GPIOx_IDR”中,通过读取该寄存器就可以了解
GPIO 引脚的电平状态。
6. 复用功能输入
与“复用功能输出”模式类似,在“复用功能输入模式”时,GPIO 引脚的信号传输到
STM32 其它片上外设,由该外设读取引脚状态。
同样,如我们使用 USART 串口通讯时,需要用到某个 GPIO 引脚作为通讯接收引脚,
这个时候就可以把该 GPIO 引脚配置成 USART 串口复用功能,使 USART 可以通过该通讯
引脚的接收远端数据。
7. 模拟输入输出
当 GPIO 引脚用于 ADC 采集电压的输入通道时,用作“模拟输入”功能,此时信号是
不经过施密特触发器的,因为经过施密特触发器后信号只有 0、1 两种状态,所以 ADC 外
设要采集到原始的模拟信号,信号源输入必须在施密特触发器之前。类似地,当 GPIO 引
脚用于 DAC 作为模拟电压输出通道时,此时作为“模拟输出”功能,DAC 的模拟信号输
出就不经过双 MOS 管结构,模拟信号直接输出到引脚

**

GPIO 工作模式

**
总结一下,由 GPIO 的结构决定了 GPIO 可以配置成以下模式

1 typedef enum
2 {
3 GPIO_Mode_AIN = 0x0,                      // 模拟输入
4 GPIO_Mode_IN_FLOATING = 0x04,             // 浮空输入
5 GPIO_Mode_IPD = 0x28,                     // 下拉输入
6 GPIO_Mode_IPU = 0x48,                     // 上拉输入
7 GPIO_Mode_Out_OD = 0x14,                  // 开漏输出
8 GPIO_Mode_Out_PP = 0x10,                  // 推挽输出
9 GPIO_Mode_AF_OD = 0x1C,                   // 复用开漏输出
10 GPIO_Mode_AF_PP = 0x18                   // 复用推挽输出
11 } GPIOMode_TypeDef;

在固件库中,GPIO 总共有 8 种细分的工作模式,稍加整理可以大致归类为以下三类:
1. 输入模式(模拟/浮空/上拉/下拉)
在输入模式时,施密特触发器打开,输出被禁止,可通过输入数据寄存器 GPIOx_IDR
读取 I/O 状态。其中输入模式,可设置为上拉、下拉、浮空和模拟输入四种。上拉和下拉
输入很好理解,默认的电平由上拉或者下拉决定。浮空输入的电平是不确定的,完全由外
部的输入决定,一般接按键的时候用的是这个模式。模拟输入则用于 ADC 采集。
2. 输出模式(推挽/开漏)
在输出模式中,推挽模式时双 MOS 管以轮流方式工作,输出数据寄存器 GPIOx_ODR
可控制 I/O 输出高低电平。开漏模式时,只有 N-MOS 管工作,输出数据寄存器可控制 I/O
输出高阻态或低电平。输出速度可配置,有 2MHz\10MHz\50MHz 的选项。此处的输出速
度即 I/O 支持的高低电平状态最高切换频率,支持的频率越高,功耗越大,如果功耗要求
不严格,把速度设置成最大即可。
在输出模式时施密特触发器是打开的,即输入可用,通过输入数据寄存器 GPIOx_IDR
可读取 I/O 的实际状态。
3. 复用功能(推挽/开漏)
复用功能模式中,输出使能,输出速度可配置,可工作在开漏及推挽模式,但是输出
信号源于其它外设,输出数据寄存器 GPIOx_ODR 无效;输入可用,通过输入数据寄存器
可获取 I/O 实际状态,但一般直接用外设的寄存器来获取该数据信号。
通过对 GPIO 寄存器写入不同的参数,就可以改变 GPIO 的工作模式,再强调一下,
要了解具体寄存器时一定要查阅《STM32F10X-中文参考手册》中对应外设的寄存器说明。
在 GPIO 外设中,控制端口高低控制寄存器 CRH 和 CRL 可以配置每个 GPIO 的工作模式和
工作的速度,每 4 个位控制一个 IO,CRH 控制端口的高八位,CRL 控制端口的低 8 位,
具体的看 CRH 和 CRL 的寄存器描述。

学习 STM32 最好的方法是用固件库,然后在固件库的基础上了解底层,学习寄存器。
什么是 STM32 函数库
以上所说的固件库是指“STM32 标准函数库”,它是由 ST 公司针对 STM32 提供的函
数接口,即 API (Application Program Interface),开发者可调用这些函数接口来配置 STM32
的寄存器,使开发人员得以脱离最底层的寄存器操作,有开发快速,易于阅读,维护成本
低等优点。
当我们调用库 API 的时候不需要挖空心思去了解库底层的寄存器操作,就像当年我们
刚开始学习 C 语言的时候,用 prinft()函数时只是学习它的使用格式,并没有去研究它的源
码实现,但需要深入研究的时候,经过千锤百炼的库源码就是最佳学习范例。
实际上,库是架设在寄存器与用户驱动层之间的代码,向下处理与寄存器直接相关的
配置,向上为用户提供配置寄存器的接口。

外设寄存器结构体定义
上一章中我们在操作寄存器的时候,操作的是都寄存器的绝对地址,如果每个外设寄存器都这样操作,那将非常麻烦。我们考虑到外设寄存器的地址都是基于外设基地址的偏移地址,都是在外设基地址上逐个连续递增的,每个寄存器占 32 个字节,这种方式跟结构体里面的成员类似。
所以我们可以定义一种外设结构体,结构体的地址等于外设的基地址,结构体的成员等于寄存器,成员的排列顺序跟寄存器的顺序一样。这样我们操作寄存器的时候就不用每次都找到绝对地址,只要知道外设的基地址就可以操作外设的全部寄存器,即操作结构体的成员即可。
在工程中的“stm32f10x.h”文件中,我们使用结构体封装 GPIO 及 RCC 外设的的寄存
器,见代码清单 9-1。结构体成员的顺序按照寄存器的偏移地址从低到高排列,成员类型
跟寄存器类型一样。
9-1 封装寄存器列表

1 //寄存器的值常常是芯片外设自动更改的,即使 CPU 没有执行程序,也有可能发生变化
2 //编译器有可能会对没有执行程序的变量进行优化
3 
4 //volatile 表示易变的变量,防止编译器优化,
5 #define __IO volatile
6 typedef unsigned int uint32_t;
7 typedef unsigned short uint16_t;
8 
9 // GPIO 寄存器结构体定义
10 typedef struct
11 {
12 __IO uint32_t CRL; // 端口配置低寄存器, 地址偏移 0X00
13 __IO uint32_t CRH; // 端口配置高寄存器, 地址偏移 0X04
14 __IO uint32_t IDR; // 端口数据输入寄存器, 地址偏移 0X08
15 __IO uint32_t ODR; // 端口数据输出寄存器, 地址偏移 0X0C
16 __IO uint32_t BSRR; // 端口位设置/清除寄存器,地址偏移 0X10
17 __IO uint32_t BRR; // 端口位清除寄存器, 地址偏移 0X14
18 __IO uint32_t LCKR; // 端口配置锁定寄存器, 地址偏移 0X18
19 } GPIO_TypeDef;

这段代码在每个结构体成员前增加了一个“__IO”前缀,它的原型在这段代码的第一
行,代表了 C 语言中的关键字“volatile”,在 C 语言中该关键字用于表示变量是易变的,
要求编译器不要优化。这些结构体内的成员,都代表着寄存器,而寄存器很多时候是由外
设或 STM32 芯片状态修改的,也就是说即使 CPU 不执行代码修改这些变量,变量的值也
有可能被外设修改、更新,所以每次使用这些变量的时候,我们都要求 CPU 去该变量的地
址重新访问。若没有这个关键字修饰,在某些情况下,编译器认为没有代码修改该变量,
就直接从 CPU 的某个缓存获取该变量值,这时可以加快执行速度,但该缓存中的是陈旧数
据,与我们要求的寄存器最新状态可能会有出入。

外设存储器映射
外设寄存器结构体定义仅仅是一个定义,要想实现给这个结构体赋值就达到操作寄存
器的效果,我们还需要找到该寄存器的地址,就把寄存器地址跟结构体的地址对应起来。
所以我们要再找到外设的地址,根据我们前面的学习,我们可以把这些外设的地址定义成
一个个宏,实现外设存储器的映射。

1 /*片上外设基地址 */
2 #define PERIPH_BASE                ((unsigned int)0x40000000)
3 
4 /*APB2 总线基地址 */
5 #define APB2PERIPH_BASE            (PERIPH_BASE + 0x10000)
6 /* AHB 总线基地址 */
7 #define AHBPERIPH_BASE             (PERIPH_BASE + 0x20000)
8 
9 /*GPIO 外设基地址*/
10 #define GPIOA_BASE                (APB2PERIPH_BASE + 0x0800)
11 #define GPIOB_BASE                (APB2PERIPH_BASE + 0x0C00)
12 #define GPIOC_BASE                (APB2PERIPH_BASE + 0x1000)
13 #define GPIOD_BASE                (APB2PERIPH_BASE + 0x1400)
14 #define GPIOE_BASE                (APB2PERIPH_BASE + 0x1800)
15 #define GPIOF_BASE                (APB2PERIPH_BASE + 0x1C00)
16 #define GPIOG_BASE                (APB2PERIPH_BASE + 0x2000)
17 
18 /*RCC 外设基地址*/
19 #define RCC_BASE (AHBPERIPH_BASE + 0x1000)

外设声明
定义好外设寄存器结构体,实现完外设存储器映射后,我们再把外设的基址强制类型
转换成相应的外设寄存器结构体指针,然后再把该指针声明成外设名,这样一来,外设名
就跟外设的地址对应起来了,而且该外设名还是一个该外设类型的寄存器结构体指针,通
过该指针可以直接操作该外设的全部寄存器,见代码清单 9-2。

1 // GPIO 外设声明
2 #define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)
3 #define GPIOB ((GPIO_TypeDef *) GPIOB_BASE)
4 #define GPIOC ((GPIO_TypeDef *) GPIOC_BASE)
5 #define GPIOD ((GPIO_TypeDef *) GPIOD_BASE)
6 #define GPIOE ((GPIO_TypeDef *) GPIOE_BASE)
7 #define GPIOF ((GPIO_TypeDef *) GPIOF_BASE)
8 #define GPIOG ((GPIO_TypeDef *) GPIOG_BASE)
9 
10 
11 // RCC 外设声明
12 #define RCC ((RCC_TypeDef *) RCC_BASE)
13 
14 /*RCC 的 AHB1 时钟使能寄存器地址,强制转换成指针*/
15 #define RCC_APB2ENR *(unsigned int*)(RCC_BASE+0x18)

首先通过强制类型转换把外设的基地址转换成 GPIO_TypeDef 类型的结构体指针,然
后通过宏定义把 GPIOA、GPIOB 等定义成外设的结构体指针,通过外设的结构体指针我们
就可以达到访问外设的寄存器的目的。
通过操作外设结构体指针的方式,我们把 main 文件里对应的代码修改掉,见代码 9-2
else 部分。
使用寄存器结构体指针操作寄存器

1 // 使用寄存器结构体指针点亮 LED
2 int main(void)
3 {
4 #if 0 // 直接通过操作内存来控制寄存器
5 // 开启 GPIOB 端口时钟
6 RCC_APB2ENR |= (1<<3);
7 
8 //清空控制 PB0 的端口位
9 GPIOB_CRL &= ~( 0x0F<< (4*0));
10 // 配置 PB0 为通用推挽输出,速度为 10M
11 GPIOB_CRL |= (1<<4*0);
12 
13 // PB0 输出 低电平
14 GPIOB_ODR |= (0<<0);
15 
16 while (1);
17 
18 #else // 通过寄存器结构体指针来控制寄存器
19 
20 // 开启 GPIOB 端口时钟
21 RCC->APB2ENR |= (1<<3);
22 
23 //清空控制 PB0 的端口位
24 GPIOB->CRL &= ~( 0x0F<< (4*0));
25 // 配置 PB0 为通用推挽输出,速度为 10M
26 GPIOB->CRL |= (1<<4*0);
27 
28 // PB0 输出 低电平
29 GPIOB->ODR |= (0<<0);
30 
31 while (1);
32 
33 #endi

乍一看,除了把“_”换成了“->”,其他都跟使用寄存器点亮 LED 那部分代码一样。
这是因为我们现在只是实现了库函数的基础,还没有定义库函数。
打好了地基,下面我们就来建高楼。接下来使用函数来封装 GPIO 的基本操作,方便
以后应用的时候不需要再查询寄存器,而是直接通过调用这里定义的函数来实现。我们把
针 对 GPIO 外 设 操 作 的 函 数 及 其 宏 定 义 分 别 存 放 在 “ stm32f10x_gpio.c ” 和
“stm32f10x_gpio.h”文件中,这两个文件需要自己新建。

定义位操作函数
在“stm32f10x_gpio.c”文件定义两个位操作函数,分别用于控制引脚输出高电平和低
电平,见代码清单 9-3。

1 /**
2 *函数功能:设置引脚为高电平
3 *参数说明:GPIOx:该参数为 GPIO_TypeDef 类型的指针,指向 GPIO 端口的地址
4 * GPIO_Pin:选择要设置的 GPIO 端口引脚,可输入宏 GPIO_Pin_0-15,
5 * 表示 GPIOx 端口的 0-15 号引脚。
6 */
7 void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
8 {
9 /*设置 GPIOx 端口 BSRR 寄存器的第 GPIO_Pin 位,使其输出高电平*/
10 /*因为 BSRR 寄存器写 0 不影响,
11 宏 GPIO_Pin 只是对应位为 1,其它位均为 0,所以可以直接赋值*/
12 
13 GPIOx->BSRR = GPIO_Pin;
14 }
15 
16 /**
17 *函数功能:设置引脚为低电平
18 *参数说明:GPIOx:该参数为 GPIO_TypeDef 类型的指针,指向 GPIO 端口的地址
19 * GPIO_Pin:选择要设置的 GPIO 端口引脚,可输入宏 GPIO_Pin_0-15,
20 * 表示 GPIOx 端口的 0-15 号引脚。
21 */
22 void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
23 {
24 /*设置 GPIOx 端口 BRR 寄存器的第 GPIO_Pin 位,使其输出低电平*/
25 /*因为 BRR 寄存器写 0 不影响,
26 宏 GPIO_Pin 只是对应位为 1,其它位均为 0,所以可以直接赋值*/
27 
28 GPIOx->BRR = GPIO_Pin;
29 }

这两个函数体内都是只有一个语句,对 GPIOx 的 BSRR 或 BRR 寄存器赋值,从而设
置引脚为高电平或低电平,操作 BSRR 或者 BRR 可以实现单独的操作某一位,
其中 GPIOx 是一个指针变量,通过函数的输入参数我们
可以修改它的值,如给它赋予 GPIOA、GPIOB、GPIOH 等结构体指针值,这个函数就可
以控制相应的 GPIOA、GPIOB、GPIOH 等端口的输出。
利用这两个位操作函数,可以方便地操作各种 GPIO 的引脚电平,控制各种端口引脚

1 
2 /*控制 GPIOB 的引脚 10 输出高电平*/
3 GPIO_SetBits(GPIOB,(uint16_t)(1<<10));
4 /*控制 GPIOB 的引脚 10 输出低电平*/
5 GPIO_ResetBits(GPIOB,(uint16_t)(1<<10));
6 
7 /*控制 GPIOB 的引脚 10、引脚 11 输出高电平,使用“|”同时控制多个引脚*/
8 GPIO_SetBits(GPIOB,(uint16_t)(1<<10)|(uint16_t)(1<<11));
9 /*控制 GPIOB 的引脚 10、引脚 11 输出低电平*/
10 GPIO_ResetBits(GPIOB,(uint16_t)(1<<10)|(uint16_t)(1<<10));
11 
12 /*控制 GPIOA 的引脚 8 输出高电平*/
13 GPIO_SetBits(GPIOA,(uint16_t)(1<<8));
14 /*控制 GPIOB 的引脚 9 输出低电平*/
15 GPIO_ResetBits(GPIOB,(uint16_t)(1<<9));

使用位操作函数及宏控制 GPIO

1 
2 /*控制 GPIOB 的引脚 10 输出高电平*/
3 GPIO_SetBits(GPIOB,GPIO_Pin_10);
4 /*控制 GPIOB 的引脚 10 输出低电平*/
5 GPIO_ResetBits(GPIOB,GPIO_Pin_10);
6 
7 /*控制 GPIOB 的引脚 10、引脚 11 输出高电平,使用“|”,同时控制多个引脚*/
8 GPIO_SetBits(GPIOB,GPIO_Pin_10|GPIO_Pin_11);
9 /*控制 GPIOB 的引脚 10、引脚 11 输出低电平*/
10 GPIO_ResetBits(GPIOB,GPIO_Pin_10|GPIO_Pin_11);
11 /*控制 GPIOB 的所有输出低电平*/
12 GPIO_ResetBits(GPIOB,GPIO_Pin_ALL);
13 
14 /*控制 GPIOA 的引脚 8 输出高电平*/
15 GPIO_SetBits(GPIOA,GPIO_Pin_8);
16 /*控制 GPIOB 的引脚 9 输出低电平*/
17 GPIO_ResetBits(GPIOB,GPIO_Pin_9);

使用以上代码控制 GPIO,我们就不需要再看寄存器了,直接从函数名和输入参数就
可以直观看出这个语句要实现什么操作。(英文中―Set‖表示“置位”,即高电平,“Reset”
表示“复位”,即低电平)。

定义初始化结构体 GPIO_InitTypeDef
定义位操作函数后,控制 GPIO 输出电平的代码得到了简化,但在控制 GPIO 输出电
平前还需要初始化 GPIO 引脚的各种模式,这部分代码涉及的寄存器有很多,我们希望初
始化 GPIO 也能以如此简单的方法去实现。为此,我们先根据 GPIO 初始化时涉及到的初
始化参数以结构体的形式封装起来,声明一个名为 GPIO_InitTypeDef 的结构体类型,见代 码 9-3

1 typedef struct
2 {
3 uint16_t GPIO_Pin; /*!< 选择要配置的 GPIO 引脚 */
4 
5 uint16_t GPIO_Speed; /*!< 选择 GPIO 引脚的速率 */
6 
7 uint16_t GPIO_Mode; /*!< 选择 GPIO 引脚的工作模式 */
8 } GPIO_InitTypeDef;

这个结构体中包含了初始化 GPIO 所需要的信息,包括引脚号、工作模式、输出速率。
设计这个结构体的思路是:初始化 GPIO 前,先定义一个这样的结构体变量,根据需要配
置 GPIO 的模式,对这个结构体的各个成员进行赋值,然后把这个变量作为“GPIO 初始化
函数”的输入参数,该函数能根据这个变量值中的内容去配置寄存器,从而实现 GPIO 的
初始化。

**

定义 GPIO 初始化函数

**
接着前面的思路,对初始化结构体赋值后,把它输入到 GPIO 初始化函数,由它来实
现寄存器配置。我们的 GPIO 初始化函数实现见代码

1 /**
2 *函数功能:初始化引脚模式
3 *参数说明:GPIOx,该参数为 GPIO_TypeDef 类型的指针,指向 GPIO 端口的地址
4 * GPIO_InitTypeDef:GPIO_InitTypeDef 结构体指针,指向初始化变量
5 */
6 void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
7 {
8 uint32_t currentmode =0x00,currentpin = 0x00,pinpos = 0x00,pos = 0x00;
9 uint32_t tmpreg = 0x00, pinmask = 0x00;
10 
11 /*---------------- GPIO 模式配置 -------------------*/
12 // 把输入参数 GPIO_Mode 的低四位暂存在 currentmode
13 currentmode = ((uint32_t)GPIO_InitStruct->GPIO_Mode) &
14 ((uint32_t)0x0F);
15 
16 // bit4 是 1 表示输出,bit4 是 0 则是输入
17 // 判断 bit4 是 1 还是 0,即首选判断是输入还是输出模式
18 if ((((uint32_t)GPIO_InitStruct->GPIO_Mode) &
19 ((uint32_t)0x10)) != 0x00)
20 {
21 // 输出模式则要设置输出速度
22 currentmode |= (uint32_t)GPIO_InitStruct->GPIO_Speed;
23 }
24 /*-----GPIO CRL 寄存器配置 CRL 寄存器控制着低 8 位 IO- ----*/
25 // 配置端口低 8 位,即 Pin0~Pin7
26 if (((uint32_t)GPIO_InitStruct->GPIO_Pin &
27 ((uint32_t)0x00FF)) != 0x00)
28 {
29 // 先备份 CRL 寄存器的值
30 tmpreg = GPIOx->CRL;
31 
32 // 循环,从 Pin0 开始配对,找出具体的 Pin
33 for (pinpos = 0x00; pinpos < 0x08; pinpos++)
34 {
35 // pos 的值为 1 左移 pinpos 位
36 pos = ((uint32_t)0x01) << pinpos;
37 
38 // 令 pos 与输入参数 GPIO_PIN 作位与运算
39 currentpin = (GPIO_InitStruct->GPIO_Pin) & pos;
40 
41 //若 currentpin=pos,则找到使用的引脚
42 if (currentpin == pos)
43 {
44 //pinpos 的值左移两位(乘以 4),因为寄存器中 4 个位配置一个引脚
45 pos = pinpos << 2;
46 //把控制这个引脚的 4 个寄存器位清零,其它寄存器位不变
47 pinmask = ((uint32_t)0x0F) << pos;
48 tmpreg &= ~pinmask;
49
50 // 向寄存器写入将要配置的引脚的模式
51 tmpreg |= (currentmode << pos);
52 
53 // 判断是否为下拉输入模式
54 if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)
55 {
56 // 下拉输入模式,引脚默认置 0,对 BRR 寄存器写 1 对引脚置 0
57 GPIOx->BRR = (((uint32_t)0x01) << pinpos);
58 }
59 else
60 {
61 // 判断是否为上拉输入模式
62 if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)
63 {
64 // 上拉输入模式,引脚默认值为 1,对 BSRR 寄存器写 1 对引脚置 1
65 GPIOx->BSRR = (((uint32_t)0x01) << pinpos);
66 }
67 }
68 }
69 }
70 // 把前面处理后的暂存值写入到 CRL 寄存器之中
71 GPIOx->CRL = tmpreg;
72 }
73 /*--------GPIO CRH 寄存器配置 CRH 寄存器控制着高 8 位 IO- -----*/
74 // 配置端口高 8 位,即 Pin8~Pin15
75 if (GPIO_InitStruct->GPIO_Pin > 0x00FF)
76 {
77 // // 先备份 CRH 寄存器的值
78 tmpreg = GPIOx->CRH;
79 
80 // 循环,从 Pin8 开始配对,找出具体的 Pin
81 for (pinpos = 0x00; pinpos < 0x08; pinpos++)
82 {
83 pos = (((uint32_t)0x01) << (pinpos + 0x08));
84 
85 // pos 与输入参数 GPIO_PIN 作位与运算
86 currentpin = ((GPIO_InitStruct->GPIO_Pin) & pos);
87 
88 //若 currentpin=pos,则找到使用的引脚
89 if (currentpin == pos)
90 {
91 //pinpos 的值左移两位(乘以 4),因为寄存器中 4 个位配置一个引脚
92 pos = pinpos << 2;
93 
94 //把控制这个引脚的 4 个寄存器位清零,其它寄存器位不变
95 pinmask = ((uint32_t)0x0F) << pos;
96 tmpreg &= ~pinmask;
97 
98 // 向寄存器写入将要配置的引脚的模式
99 tmpreg |= (currentmode << pos);
100 
101 // 判断是否为下拉输入模式
102 if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)
103 {
104 // 下拉输入模式,引脚默认置 0,对 BRR 寄存器写 1 可对引脚置 0
105 GPIOx->BRR = (((uint32_t)0x01) << (pinpos + 0x08));
106 }
107 // 判断是否为上拉输入模式
108 if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)
109 {
110 // 上拉输入模式,引脚默认值为 1,对 BSRR 寄存器写 1 可对引脚置 1
111 GPIOx->BSRR = (((uint32_t)0x01) << (pinpos + 0x08));
112 }
113 }
114 }
115 // 把前面处理后的暂存值写入到 CRH 寄存器之中
116 GPIOx->CRH = tmpreg;
117 }
118 }

这个函数有 GPIOx 和 GPIO_InitStruct 两个输入参数,分别是 GPIO 外设指针和 GPIO
初始化结构体指针。分别用来指定要初始化的 GPIO 端口及引脚的工作模式。

总结

**

什么是 ST 标准固件库?不懂的时候总觉得莫测高深,懂了之后一切都是纸老虎。
我们从寄存器映射开始,把内存跟寄存器建立起一一对应的关系,然后操作寄存器点
亮 LED,再把寄存器操作封装成一个个函数。一步一步走来,我们实现了库最简单的雏形,
如果我们不断地增加操作外设的函数,并且把所有的外设都写完,一个完整的库就实现了。
本章中的 GPIO 相关库函数及结构体定义,实际上都是从 ST 标准库搬过来的。这样分
析它纯粹是为了满足自己的求知欲,学习其编程的方式、思想,这对提高我们的编程水平
是很有好处的,顺便感受一下 ST 库设计的严谨性,我认为这样的代码不仅严谨且华丽优
美,不知您是否也有这样的感受。
与直接配置寄存器相比,从执行效率上看会有额外的消耗:初始化变量赋值的过程、
库函数在被调用的时候要耗费调用时间;在函数内部,对输入参数转换所需要的额外运算
也消耗一些时间(如 GPIO 中运算求出引脚号时)。而其它的宏、枚举等解释操作是作编译过
程完成的,这部分并不消耗内核的时间。那么函数库的优点呢?是我们可以快速上手
STM32 控制器;配置外设状态时,不需要再纠结要向寄存器写入什么数值;交流方便,查
错简单。这就是我们选择库的原因。
现在的处理器的主频是越来越高,我们不需要担心 CPU 耗费那么多时间来干活会不会
被累倒,库主要应用是在初始化过程,而初始化过程一般是芯片刚上电或在核心运算之前
的执行的,这段时间的等待是 0.02us 还是 0.01us 在很多时候并没有什么区别。相对来说,
我们还是担心一下如果都用寄存器操作,每行代码都要查数据手册的寄存器说明,自己会
不会被累倒吧。
在以后开发的工程中,一般不会去分析 ST 的库函数的实现。因为外设的库函数是很
类似的,库外设都包含初始化结构体,以及特定的宏或枚举标识符,这些封装被库函数这
些转化成相应的值,写入到寄存器之中,函数内部的具体实现是十分枯燥和机械的工作。

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

相关文章

  1. 视频

    Java面试Offer直通车sample.mov...

    2024/4/24 12:30:14
  2. 第三周课外编程练习

    所有题目来自Python123网站。时间函数的使用还是需要多加练习,这里用到了time.perf_count()且两次调用求出时间差,time.sleep()则是直接设置程序休眠时间。 import time scale = 50 print("执行开始".center(scale//2,-)) start = time.perf_counter() for i in ra…...

    2024/4/23 18:32:15
  3. 示波器使用

    1.探头补偿校准按图所示,连接到通道1,按下“自动设置”键(在示波器上通常标识为"自动设置"或“Autoset”或 “Auto”等)。拧动探头螺丝孔内的螺丝,调节补偿电容,以得到正确波形。2、输入耦合方式 输入耦合方式是指外部信号从示波器输入端口进入到内部电路的耦合…...

    2024/5/8 17:11:37
  4. 啊啊

    点点点...

    2024/4/24 12:30:08
  5. 应用层网关调研与基础测试

    背景 故事的开始还是源于现阶段各个平台之间有些许的接口调用,但是各个平台之间又相对比较独立,并没有将各个平台整合成一组微服务的需求。现在面临的问题就是各个平台直接都有互相调用的需求,如果各个平台有业务升级的情况下,不一定能察觉到是否会影响到对提供给其他系统使…...

    2024/4/24 12:30:10
  6. vue+element-ui实现多选框绑定数组对象。为什么不能回显

    本来的逻辑是点全选获取全部单选的绑定值的数组。就可以让下面所有的选中。但是如果下面单选绑定的不是一个值。而是一个对象的话。即使点击全选获取所有单选对象组成的数组也不能回显。直接按照官网的例子修改一下.让他绑定的值是对象。发现你写了checkedCities选中的对象内容…...

    2024/4/24 12:30:06
  7. android属性动画实践及原理

    动画 首先明确啥是动画?你可以理解成若干不同图片随着时间不断交替成为焦点的过程,说简单点就是"量子阅读法",你还可以把动画理解成使用某多种手段将一张图片进行各种变换。那么这两种理解方式对应android里的动画就是帧动画和属性动画,当然帧动画和补间动画属于…...

    2024/4/24 12:30:06
  8. 转载:SRT传输库评估报告(V1.0.0)

    原文地址:https://blog.csdn.net/mediapro/article/details/105790057,感谢大神;SRT传输库评估报告(V1.0.0)www.mediapro.ccSRT传输库简介 SRT是Haivision开源的一套集FEC前向纠错、ACK、NAK选择性重传、JitterBuff、拥塞控制、传输安全保障等技术于一体的实时传输解决方案。…...

    2024/4/24 12:30:04
  9. linux更换aliyun源

    linux更换国内源CentOS更换为阿里云的源 什么是国内源,通俗讲就是应用市场,Android系统有Android应用市场,Apple系统有Apple应用市场,Linux系统也有Linux应用市场。 Linux的国内源根据不同的版本分,主要有:  CentOS版本:yum源  Ubuntu版本:apt-get源 注1:如果只是…...

    2024/4/24 12:30:03
  10. 南京大学2020软工专硕初试第一经验分享

    写在前面:以下的所有经验都是我自己备考中亲身经历得出的,不存在想象或者编造的情况,但由于我自己的性格,我对于不喜欢的人或事的印象极难改变,所以你会看到我对一些老师相当负面的评价。 另外由于每个人的实际情况不同,当然每个人最适合的复习策略也不同,我会尽可能的介…...

    2024/5/8 13:46:45
  11. CAT1域格模块常见问题部分设计参考

    天线部分 CLM920_RC3 的 49 脚为主集天线接口,为方便天线调试需要在主板上增加π型匹 配电路,走 50 欧阻抗线。 CLM920_RC3 的 47 脚为 GNSS 天线接口,为方便天线调试需要在主板上增加π型 匹配电路,走 50 欧阻抗线 主天线与分集天线之间需要保持一定的间距 CLM920_RC3 模块…...

    2024/4/15 4:33:30
  12. MySQL数据库笔记10——视图、DBA命令、数据库设计三范式

    1.视图 1.1 什么是视图?站在不同的角度去看待数据,即同一张表的数据,通过不同的角度去看待。 1.2 怎么创建视图?怎么删除视图? create view myview as select empno,ename from emp; drop view myview; 注意:只有DQL语句才能以视图对象的方式创建出来。 1.3 对视图进行增…...

    2024/4/15 4:33:27
  13. 从0开始手动配置redis主从复制

    手动配置redis主从复制主从复制的概念主从复制的特点开始搭建1、下载redis:可以通过把下载好的redis安装包上传到服务器上,也可以通过yum,wget方式进行安装,我这里是通过wget方式进行安装的。2、开始搭建主从复制3、配置完毕,开始测试 主从复制的概念 1、在主从复制模型中…...

    2024/4/23 0:55:17
  14. liunx自学第三天

    文章目录更改用户组 chgrp常用环境变量常用文件管理命令df命令 更改用户组 chgrp chgrp 123456 123 123456这里代表的就是更改用户组的名称,123就是你的文件敲完命令之后:常用环境变量 DISPLAY 用来设置将图形显示到何处。 HOME 当前用户的主目录。 IFS …...

    2024/4/15 4:33:25
  15. IntelliJ IDEA彻底删除项目

    IDEA彻底删除项目 1.在项目上单击右键选择Remove Module,也可以直接在项目上按下delete键 2.提示我们工程只是从工作空间移除,但是磁盘上的不会删除,选择remove 3.到磁盘的工作空间Project中,删除项目即可彻底删除。...

    2024/4/17 7:38:06
  16. 线程中介之Java线程池

    在云计算、5G技术快速发展的互联网世界,为了快速响应用户的请求,宏观上除了团队内部实行DevOps机制管理、使用微服务架构进行技术设计、使用Docker或K8s进行应用部署外,微观上在程序开发中使用并行计算的能力也是必不可少的。而在Java开发中,最常用的便是通过线程池来最大程…...

    2024/4/19 14:18:33
  17. 【Java】java 的!file.exists()与 file !=null使用场景/区别

    1.exists()方法使用//这里使用new 创建实例,所以f不可能为null File f = new File("D:/xyz/hashdog.text")//用exists()方法判断 if(!f.exists()){System.out.print("该文件不存在") }2.!=null条件使用//这里使用new 创建实例,所以f不可能为null File f ; …...

    2024/4/15 4:33:23
  18. php神秘的函数应用

    话不多说,直接上代码: // 获取数组中某个键值对应的总个数 $list = array(array(id => 1, userId => 5),array(id => 2, userId => 5),array(id => 2, userId => 6), );// $userId = 5; $arr=array_column($list,userId);//把值提取出来转成一维数组 $arr=a…...

    2024/4/24 12:30:02
  19. Mysql的锁和并发参数的介绍

    Mysql的锁和并发参数的介绍 一、Mysql并发参数调整从实现上来说,MySQL Server 是多线程结构,包括后台线程和客户服务线程。多线程可以有效利用服务器资源,提高数据库的并发性能。在Mysql中,控制并发连接和线程的主要参数包括 max_connections、back_log、thread_cache_size…...

    2024/4/24 12:30:04
  20. S=A-BIS-dS+u2w2I+u1w1E数模作业

    给定模型S=A-BIS-dS+u2w2I+u1w1E,E=BIS-dE-eE-w1E,I=eE-dI-aI-w2I,给出潜伏者和感染者在t属于0~100上时间序列图。其中,点表示S,E,I分别关于时间t的导数。 (注意是左边S,E,I,因为我就是在这给坑了下,仔细看左边S,E,I和右边的确实不同,那右边S,E,I表示何物?表示原方程。…...

    2024/4/24 12:30:01

最新文章

  1. 【爬虫】爬取A股数据写入数据库(二)

    前几天有写过一篇 【爬虫】爬取A股数据写入数据库&#xff08;一&#xff09;&#xff0c;现在继续完善下&#xff0c;将已有数据通过ORM形式批量写入数据库。 2024/05&#xff0c;本文主要内容如下&#xff1a; 对东方财富官网进行分析&#xff0c;并作数据爬取&#xff0c;使…...

    2024/5/8 21:56:11
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/5/7 10:36:02
  3. AcWing 1381. 阶乘

    解题思路 最后一位数相乘的变化。注意&#xff1a;为什么不是ss%10&#xff0c;如果12 * 15&#xff0c; 12的最后一位时2&#xff0c; * 1530&#xff0c;则为3&#xff0c;问题是12*15180&#xff0c;为8&#xff0c;两 者不符&#xff0c;说明ss%10中的10要多加0. import j…...

    2024/5/6 15:08:59
  4. [蓝桥杯 2014 省 A] 波动数列

    容我菜菲说一句&#xff0c;全网前排题解都是rubbish&#xff0c;当然洛谷某些也是litter 不好意思&#xff0c;最近背单词背了很多垃圾的英文&#xff0c;正题开始 [蓝桥杯 2014 省 A] 波动数列 题目描述 输入格式 输入的第一行包含四个整数 n , s , a , b n,s,a,b n,s,a…...

    2024/5/7 16:12:29
  5. 零代码编程:用kimichat将PDF自动批量分割成多个图片

    有一个PDF文件&#xff0c;现在想把pdf文件转换成图片&#xff0c; 可以在kimichat中输入提示词&#xff1a; 你是一个Python编程专家&#xff0c;要完成一个将PDF文件自动批量分割成多个图片的任务&#xff0c;具体步骤如下&#xff1a; 打开d盘下的pdf文件&#xff1a;Ill …...

    2024/5/6 15:24:21
  6. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/5/8 6:01:22
  7. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/5/7 9:45:25
  8. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/5/4 23:54:56
  9. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/5/7 14:25:14
  10. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/5/4 23:54:56
  11. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/5/4 23:55:05
  12. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/5/4 23:54:56
  13. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/5/7 11:36:39
  14. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/5/4 23:54:56
  15. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/5/6 1:40:42
  16. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/5/4 23:54:56
  17. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/5/8 20:48:49
  18. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/5/7 9:26:26
  19. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/5/4 23:54:56
  20. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/5/8 19:33:07
  21. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/5/5 8:13:33
  22. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/5/8 20:38:49
  23. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/5/4 23:54:58
  24. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/5/6 21:42:42
  25. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/5/4 23:54:56
  26. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  27. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  28. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  29. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  30. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  31. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  32. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  33. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  34. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  35. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  36. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  37. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  38. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  39. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  40. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  41. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  42. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  43. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  44. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  45. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57