四、GPIO
GPIO
GPIO简介
- GPIO(General Purpose Input Output)通用输入输出口
- 可配置为8种输入输出模式
- 引脚电平:0V~3.3V,部分引脚可容忍5V
- 输出模式下可控制端口输出高低电平,用以驱动LED、控制蜂鸣器、模拟通信协议输出时序等
- 输入模式下可读取端口的高低电平或电压,用于读取按键输入、外接模块电平信号输入、ADC电压采集、模拟通信协议接收数据等
GPIO基本结构
GPIO都是挂载在APB2总线上的外设
-
GPIO的命名方式:
使用大写字母的方式命名GPIO外设,例如:GPIOA、GPIOB、GPIOC等等
而每一个GPIO都对应有16个IO口,从0~15。例如:GPIOA的IO口命名为:PA0~PA15。GPIOB的IO口命名为:PB0~PB15。以此类推
-
寄存器:
内核通过APB2总线对寄存器进行读写,寄存器的每一位对应一个引脚。写入1就输出高电平,写入0就输出低电平;读出1就说明引脚输入的高电平,输入0就说明输入的低电平
STM32是32位的单片机,所以GPIO的寄存器中可以写入32位数据,但是只有低16位有对应的引脚,高16位是没有的
-
驱动器:
用于增加信号的驱动能力
GPIO位结构
GPIO模式
通过配置GPIO的端口寄存器,端口可以配置成以下8种模式
注意:除了模拟输入外,其他七种模式的数字输入都是有效的
模式名称 | 性质 | 特征 |
---|---|---|
浮空输入 | 数字输入 | 可读取引脚电平,若引脚悬空,则电平不稳定 |
上拉输入 | 数字输入 | 可读引脚取电平,内部连接上拉电阻,悬空时默认高电平 |
下拉输入 | 数字输入 | 可读引脚取电平,内部连接下拉电阻,悬空时默认低电平 |
模拟输入 | 模拟输入 | GPIO无效,引脚直接接入内部ADC |
开漏输出 | 数字输出 | 可输出引脚电平,高电平为高阻态,低电平接VSS |
推挽输出 | 数字输出 | 可输出引脚电平,高电平接VDD,低电平接VSS |
复用开漏输出 | 数字输出 | 可输出引脚电平,高电平为高阻态,低电平接VSS |
复用推挽输出 | 数字输出 | 可输出引脚电平,高电平接VDD,低电平接VSS |
浮空/上拉/下拉输入
浮空输入: 可读取引脚电平,若引脚悬空,则电平不稳定
上拉输入: 可读引脚取电平,内部连接上拉电阻,悬空时默认高电平
下拉输入: 可读引脚取电平,内部连接下拉电阻,悬空时默认低电平
模拟输入
模拟输入: GPIO无效,引脚直接接入内部ADC
模拟输入一般只用于ADC
开漏/推挽输出
-
开漏输出:高电平为高阻态,没有驱动能力,只有低电平具有驱动能力
- 可以作为通信协议的驱动方式,例如I2C通信的引脚就是使用开漏输出的模式
- 还可以用于输出5V的电平信号。比如在IO口外接一个上拉电阻到5V的电源,当输出高电平时,由外部的上拉电阻拉高至5V。可以用于兼顾5V电平的设备
-
推挽输出:高低电平都具有较强的驱动能力,所以也可以叫强推输出模式。在推挽输出模式下,STM32对IO口具有绝对的控制权,高低电平都由STM32说了算
复用开漏\推挽输出
与不同开漏\推挽输出差不多,只不过引脚的控制权在其他外设上
GPIO输出
LED和蜂鸣器简介
LED和蜂鸣器硬件电路
库函数配置寄存器
设置AP0引脚为推挽输出,50MHz的速度
-
1、开启GPIOA的时钟
AP0引脚属于GPIOA,要使用外设就需要开启对应的外设时钟。因为GPIOA挂载在APB2总线上,在Library中找到并打开stm32f10x_rcc.h文件,找到开启APB2上外设时钟的函数声明
根据要使用的外设在RCC_APB2PeriphClockCmd函数中填入对应的参数来开启时钟
// 开启GPIOA的时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); /* 其中第一个参数可以使用 | 来选中多个外设 例如:同时开启GPIOA和GPIOB的外设时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE); */
-
2、初始化引脚
打开stm32f10x_gpio.h文件,找到初始化引脚配置的结构体
定义一个GPIO_InitTypeDef类型的结构体
// 定义一个GPIO_InitTypeDef类型的结构体 GPIO_InitTypeDef GPIO_InitStructure;
配置结构体中的成员属性
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出模式 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // 选中引脚0 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 速度50MHz /* 成员属性GPIO_Mode的值 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; */ /* 成员属性GPIO_Pin的值 GPIO_Pin_x,其中x为0~15、All、None 当 GPIO_Pin=GPIO_Pin_All 时表示选中全部引脚 当 GPIO_Pin=GPIO_Pin_None 时表示无引脚被选中 该参数选择待设置的 GPIO 管脚,使用操作符“|”可以一次选中多个管脚。 */ /* 成员属性GPIO_Speed的值 typedef enum { GPIO_Speed_10MHz = 1, // 最高输出速率 10MHz GPIO_Speed_2MHz, // 最高输出速率 2MHz GPIO_Speed_50MHz // 最高输出速率 50MHz }GPIOSpeed_TypeDef; */
根据指定初始化GPIOx外设GPIO_InitStruct中的参数
// 根据指定初始化GPIOx外设GPIO_InitStruct中的参数 GPIO_Init(GPIOA, &GPIO_InitStructure); /* 第一个参数是:GPIOx,其中x为A~G 第二个参数是:GPIO_InitTypeDef类型的结构体的地址 */
控制引脚输出的函数
/**
* @作用 设置所选数据端口位
* @参数 GPIOx: 其中x可以为(A..G)选择GPIO外设
* @参数 GPIO_Pin: 指定要写入的端口位。
* 该参数可以是GPIO_Pin_x的任意组合,其中x可以是(0..15)。
* @返回值 None
*/
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
/**
* @作用 清除所选数据端口位。
* @参数 GPIOx: 其中x可以为(A..G)选择GPIO外设
* @参数 GPIO_Pin: 指定要写入的端口位。
* 该参数可以是GPIO_Pin_x的任意组合,其中x可以是(0..15)。
* @返回值 None
*/
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
/**
* @作用 设置或清除所选数据端口位。
* @参数 GPIOx: 其中x可以为(A..G)选择GPIO外设
* @参数 GPIO_Pin: 指定要写入的端口位。
* 该参数可以是GPIO_Pin_x的任意组合,其中x可以是(0..15)。
* @参数 BitVal: 指定要写入所选位的值
* 该参数可以是BitAction枚举值之一:
* @值 Bit_RESET: 清除端口引脚
* @值 Bit_SET: 设置端口引脚
* @返回值 None
*/
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal)
/**
* @作用 将数据写入指定的GPIO数据端口。
* @参数 GPIOx: 其中x可以为(A..G)选择GPIO外设
* @参数 PortVal: 要写入端口输出数据寄存器的值
* @返回值 None
*/
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal)
-
4、添加延时函数
在工程中新建文件夹:Systems
复制如下路径中的文件:STM32入门教程资料\程序源码\STM32Project-有注释版\1-3 Delay函数模块
粘贴到Systems文件夹中,Keil5中新建分组,命名为:Systems,将Systems文件夹中的文件添加到组中,文件夹路径也要添加进来
先直接使用
分别可以进行us、ms、s级别的延时
LED闪烁案例
接线图
代码示例
#include "stm32f10x.h" // Device header
#include "Delay.h"
int main()
{
// 开启GPIOA的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// 定义一个GPIO_InitTypeDef类型的结构体
GPIO_InitTypeDef GPIO_InitStructure;
// 给结构体中的子项赋值
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // 选中引脚0
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 速度50MHz
// 根据指定初始化GPIOx外设GPIO_InitStruct中的参数
GPIO_Init(GPIOA, &GPIO_InitStructure);
while(1)
{
// 控制GPIOA的第0位输出高电平
GPIO_SetBits(GPIOA, GPIO_Pin_0);
// 延时500ms
Delay_ms(500);
// 控制GPIOA的第0位输出低电平
GPIO_ResetBits(GPIOA, GPIO_Pin_0);
// 延时500ms
Delay_ms(500);
// 控制GPIOA的第0位输出高电平
GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET);
Delay_ms(500);
// 控制GPIOA的第0位输出低电平
GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET);
Delay_ms(500);
}
}
LED流水灯案例
接线图
代码示例
#include "stm32f10x.h" // Device header
#include "Delay.h"
int main()
{
// 开启GPIOA的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// 定义一个GPIO_InitTypeDef类型的结构体
GPIO_InitTypeDef GPIO_InitStructure;
// 给结构体中的子项赋值
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All; // 选中所有引脚
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 速度50MHz
// 根据指定初始化GPIOx外设GPIO_InitStruct中的参数
GPIO_Init(GPIOA, &GPIO_InitStructure);
while(1)
{
// 设置初始值
unsigned int set_pin = 0x0001;
for(int i = 0;i<8;i++)
{
// GPIO_Write():将数据写入指定的GPIO数据端口。
// 接线图可知,LED在低电平时点亮,所以要对set_pin按位取反
GPIO_Write(GPIOA, ~(set_pin<<i));
// 延时500ms
Delay_ms(100);
}
}
}
蜂鸣器案例
接线图
据图可知触发蜂鸣器的是PB12引脚,属于外设GPIOB。且该蜂鸣器是电平触发
代码示例
#include "stm32f10x.h" // Device header
#include "Delay.h"
int main()
{
// 开启GPIOB的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
// 定义一个GPIO_InitTypeDef类型的结构体
GPIO_InitTypeDef GPIO_InitStructure;
// 给结构体中的子项赋值
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; // 选中引脚12
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 速度50MHz
// 初始化GPIOB外设GPIO_InitStruct中的参数
GPIO_Init(GPIOB, &GPIO_InitStructure);
while(1)
{
// 该蜂鸣器是低电平触发
GPIO_ResetBits(GPIOB, GPIO_Pin_12);
Delay_ms(100);
GPIO_SetBits(GPIOB, GPIO_Pin_12);
Delay_ms(100);
GPIO_ResetBits(GPIOB, GPIO_Pin_12);
Delay_ms(100);
GPIO_SetBits(GPIOB, GPIO_Pin_12);
Delay_ms(700);
}
}
GPIO输入
按键简介
传感器模块介绍
传感器模块:传感器元件(光敏电阻/热敏电阻/红外接收管等)的电阻会随外界模拟量的变化而变化,通过与定值电阻分压即可得到模拟电压输出,再通过电压比较器进行二值化即可得到数字电压输出
传感器
传感器基本电路
-
电路图3:
-
N1:是代表传感器元件的可变电阻,他的阻值可以根据环境的光线、温度等模拟量变化
-
R1:是用来与N1进行分压的定值电阻
-
C2:是一个滤波电容,滤除一些干扰,保证电压波形的平滑
-
AO输出端:输出模拟电压。通过电路图4的AO引脚直接输出
当N1电阻减小时,下拉作用就会增强,中间的AO端的电压就会拉低,阻值为0时AO端输出0v电压
当N1电阻变大时,下拉作用就会减弱,AO端由于R1的上拉作用,电压升高,N1阻值无穷大时,相当于断路,输出电压被R1拉高至VCC
-
-
电路图1
-
这是一个LM393芯片,是一个电压比较器芯片。用来对电路图3中的AO进行二值化输出,得到数字电压输出
-
运算放大器做比较器的情况:当同相输入端的电压大于反相输入端的电压时,输出就会瞬间升为最大值,也就是VCC;反之,当同相输入端的电压小于于反相输入端的电压时,输出就会瞬间降低为最小值,也就是GND
-
该电路图中的同相输入端IN+接到了电路图的AO,也就是模拟电压端,反相输入端IN-接到了电路图2中的电位器,拧动该电位器,IN-就可以生成一个可调的阈值电压,两个电压进行比较,最终输出结果就是DO,数字电压输出。DO最终接到了电路图4的DO引脚
-
-
电路图4
LED1是电源指示灯,通电就亮
LED2是DO输出指示灯,指示DO的输出电平,低电平点亮
R5:上拉电阻,保证默认输出高电平的
对于红外传感器模块,会多一个红外发射的电路
按键硬件电路
一般情况来说单片机按键都是接GND,也就是上面的接法1和接法2
-
接法1:当K1按键被按下,PA0被直接下拉到GND,此时PA0的电压就是低电平。但是当K1没有按下时,PA0属于浮空状态,电压极易受到外界干扰,所以需要将PA0配置成上拉输入的模式,默认输入高电平,只有在K1被按下时才为低电平
-
接法2:相比于接法1,这里外接了一个上拉电阻,当K1按键没有按下时由于上拉作用,自然保持高电平,只有按键按下时PA0才为低电平。在该转态下,PA0引脚可以配置为浮空输入的模式或上拉输入模式
-
接法3:与接法1相反,K1按键被按下时PA0为高电平,所以需要将PA0配置成下拉输入的模式,默认输入低电平
-
接法4:与接法2相反,PA0可以配置为浮空输入模式或下拉输入模式
传感器硬件电路
AO模拟输出在使用ADC时再用
读取输入输出寄存器
/**
* @作用 读取指定的输入端口引脚。
* @参数 GPIOx: 其中x可以为(A..G)选择GPIO外设。
* @参数 GPIO_Pin: 指定要读取的端口位。
* 该参数可以是GPIO_Pin_x,其中x可以是(0..15)。
* @返回值 输入端口引脚值。
*/
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
/**
* @作用 读取指定的GPIO输入数据端口。
* @参数 GPIOx: 其中x可以为(A..G)选择GPIO外设。
* @返回值 GPIO输入数据端口值。
*/
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
/**
* @作用 读取指定的输出数据端口位。
* @参数 GPIOx: 其中x可以为(A..G)选择GPIO外设。
* @参数 GPIO_Pin: 指定要读取的端口位。
* 该参数可以是GPIO_Pin_x,其中x可以是(0..15)。
* @返回值 输出端口引脚值。
*/
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
/**
* @作用 读取指定的GPIO输出数据端口。
* @参数 GPIOx: 其中x可以为(A..G)选择GPIO外设。
* @返回值 GPIO输出数据端口值。
*/
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
按键控制LED案例
接线图
代码示例
#include "stm32f10x.h" // Device header
#include "Delay.h"
int main()
{
// 开启GPIOA和GPIOB的外设时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
// 初始化LED的引脚
GPIO_InitTypeDef GPIO_Init_LED;
GPIO_Init_LED.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出
GPIO_Init_LED.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2; // 选中引脚1和引脚2
GPIO_Init_LED.GPIO_Speed = GPIO_Speed_50MHz; // 速度50MHz
GPIO_Init(GPIOA, &GPIO_Init_LED);
// 初始化按键的引脚
GPIO_InitTypeDef GPIO_Init_Key;
GPIO_Init_Key.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入
GPIO_Init_Key.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_11; // 选择引脚1和引脚11
GPIO_Init_Key.GPIO_Speed = GPIO_Speed_50MHz; // 速度50MHz
GPIO_Init(GPIOB, &GPIO_Init_Key);
while(1)
{
// 按键低电平触发,读取输入寄存器PB1对应的数据,当PB1输入0时,说明按键被按下
if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)
{
// 延时20ms消抖
Delay_ms(20);
// 当PB1输入1时说明按键被松开,结束循环
while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0);
// 延时20ms消抖
Delay_ms(20);
// 读取输出寄存器PA1对应的数据,当PA1为0时将他置1,当PA1为1时将他清0
if(GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_1) == 0)
{
GPIO_SetBits(GPIOA, GPIO_Pin_1);
}
else
{
GPIO_ResetBits(GPIOA, GPIO_Pin_1);
}
}
// 按键低电平触发,读取输入寄存器PB11对应的数据,当PB11输入0时,说明按键被按下
if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0)
{
// 延时20ms消抖
Delay_ms(20);
// 当PB11输入1时说明按键被松开,结束循环
while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0);
// 延时20ms消抖
Delay_ms(20);
// 读取输出寄存器PA2对应的数据,当PA2为0时将他置1,当PA2为1时将他清0
if(GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_2) == 0)
{
GPIO_SetBits(GPIOA, GPIO_Pin_2);
}
else
{
GPIO_ResetBits(GPIOA, GPIO_Pin_2);
}
}
}
}
光敏传感器控制蜂鸣器案例
接线图
代码示例
#include "stm32f10x.h" // Device header
#include "Delay.h"
int main()
{
// 开启GPIOB的外设时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
// 初始化蜂鸣器的输出引脚
GPIO_InitTypeDef GPIO_Init_Buzzer;
GPIO_Init_Buzzer.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出
GPIO_Init_Buzzer.GPIO_Pin = GPIO_Pin_12; // 选中引脚12
GPIO_Init_Buzzer.GPIO_Speed = GPIO_Speed_50MHz; // 速度50MHz
GPIO_Init(GPIOB, &GPIO_Init_Buzzer);
// 初始化光敏传感器的输入引脚
GPIO_InitTypeDef GPIO_Init_Light;
GPIO_Init_Light.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入
GPIO_Init_Light.GPIO_Pin = GPIO_Pin_13; // 选择引脚13
GPIO_Init_Light.GPIO_Speed = GPIO_Speed_50MHz; // 速度50MHz
GPIO_Init(GPIOB, &GPIO_Init_Light);
while(1)
{
// 当PB13引脚对应的寄存器位为1时,说明OD电压的高于电位器的阈值,OD指示灯熄灭,蜂鸣器鸣响
if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_13) == 1)
{
// PB12引脚对应位清0,蜂鸣器鸣响
GPIO_WriteBit(GPIOB, GPIO_Pin_12, Bit_RESET);
Delay_ms(100);
}
else
{
// PB12引脚对应位置1,蜂鸣器不发声
GPIO_WriteBit(GPIOB, GPIO_Pin_12, Bit_SET);
}
}
}
GPIO常用函数
开启GPIO时钟
// 开启GPIOA的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
初始化引脚
// 定义一个GPIO_InitTypeDef类型的结构体
GPIO_InitTypeDef GPIO_InitStructure;
// 配置结构体的子项
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // 选中引脚0
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 速度50MHz
// 根据指定初始化GPIOx外设GPIO_InitStruct中的参数
/*
第一个参数是:GPIOx,其中x为A~G
第二个参数是:GPIO_InitTypeDef类型的结构体的地址
*/
GPIO_Init(GPIOA, &GPIO_InitStructure);
/*
成员属性GPIO_Mode的值
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;
*/
/*
成员属性GPIO_Pin的值
GPIO_Pin_x,其中x为0~15、All、None
当 GPIO_Pin=GPIO_Pin_All 时表示选中全部引脚
当 GPIO_Pin=GPIO_Pin_None 时表示无引脚被选中
该参数选择待设置的 GPIO 管脚,使用操作符“|”可以一次选中多个管脚。
*/
/*
成员属性GPIO_Speed的值
typedef enum
{
GPIO_Speed_10MHz = 1, // 最高输出速率 10MHz
GPIO_Speed_2MHz, // 最高输出速率 2MHz
GPIO_Speed_50MHz // 最高输出速率 50MHz
}GPIOSpeed_TypeDef;
*/
引脚输出函数
/**
* @作用 设置所选数据端口位
* @参数 GPIOx: 其中x可以为(A..G)选择GPIO外设
* @参数 GPIO_Pin: 指定要写入的端口位。
* 该参数可以是GPIO_Pin_x的任意组合,其中x可以是(0..15)。
* @返回值 None
*/
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
/**
* @作用 清除所选数据端口位。
* @参数 GPIOx: 其中x可以为(A..G)选择GPIO外设
* @参数 GPIO_Pin: 指定要写入的端口位。
* 该参数可以是GPIO_Pin_x的任意组合,其中x可以是(0..15)。
* @返回值 None
*/
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
/**
* @作用 设置或清除所选数据端口位。
* @参数 GPIOx: 其中x可以为(A..G)选择GPIO外设
* @参数 GPIO_Pin: 指定要写入的端口位。
* 该参数可以是GPIO_Pin_x的任意组合,其中x可以是(0..15)。
* @参数 BitVal: 指定要写入所选位的值
* 该参数可以是BitAction枚举值之一:
* @值 Bit_RESET: 清除端口引脚
* @值 Bit_SET: 设置端口引脚
* @返回值 None
*/
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal)
/**
* @作用 将数据写入指定的GPIO数据端口。
* @参数 GPIOx: 其中x可以为(A..G)选择GPIO外设
* @参数 PortVal: 要写入端口输出数据寄存器的值
* @返回值 None
*/
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal)
读取输入输出寄存器
/**
* @作用 读取指定的输入端口引脚。
* @参数 GPIOx: 其中x可以为(A..G)选择GPIO外设。
* @参数 GPIO_Pin: 指定要读取的端口位。
* 该参数可以是GPIO_Pin_x,其中x可以是(0..15)。
* @返回值 输入端口引脚值。
*/
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
/**
* @作用 读取指定的GPIO输入数据端口。
* @参数 GPIOx: 其中x可以为(A..G)选择GPIO外设。
* @返回值 GPIO输入数据端口值。
*/
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
/**
* @作用 读取指定的输出数据端口位。
* @参数 GPIOx: 其中x可以为(A..G)选择GPIO外设。
* @参数 GPIO_Pin: 指定要读取的端口位。
* 该参数可以是GPIO_Pin_x,其中x可以是(0..15)。
* @返回值 输出端口引脚值。
*/
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
/**
* @作用 读取指定的GPIO输出数据端口。
* @参数 GPIOx: 其中x可以为(A..G)选择GPIO外设。
* @返回值 GPIO输出数据端口值。
*/
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY