一、GPIO简介
GPIO(General Purpose Input Output)通用输入输出口
可配置为8种输入输出模式
引脚电平:0V~3.3V,部分引脚可容忍5V(引脚中带FT的可容忍5V电压)。
输出模式下可控制端口输出高低电平,用以驱动LED、控制蜂鸣器、模拟通信协议输出时序等
输入模式下可读取端口的高低电平或电压,用于读取按键输入、外接模块电平信号输入、ADC电压采集、模拟通信协议接收数据等。
二、GPIO结构
在stm32中,所有的GPIO外设都是挂载在APB2总线上的,GPIO外设以GPIOA,GPIOB,GPIOC这样的方式来命名 ,每个GPIO外设都有16个引脚,GPIOA的引脚就是PA0-PA15,GPIOB的引脚都是PB0-PB15。
GPIO外设主要由寄存器和驱动器构成,寄存器就是特殊的数据存储器,内核可以通过APB2总线对寄存器完成读写,这样就能完成输出电平和读取电平的功能。寄存器的每一位对应一个引脚,其中输出寄存器写1,对应的引脚就是高电平,写0,对应的引脚就是低电平。输入寄存器读取为1,说明对应的引脚为高电平,读取为0,对应的引脚为低电平。
stm32单片机是32位的,因此寄存器也都是32位的,但是由于只有16个端口,0-15,因此寄存器的高16位没有用到,只用了低16位。
驱动器是用来增加信号驱动能力的,因为寄存器只是用来存储数据的,驱动外设还是要靠驱动器来完成。
三、stm32GPIO使用步骤
1.使用RCC开启GPIO的时钟,
2.使用GPIO_Init函数来初始化GPIO,
3.使用输入或输出的函数来控制GPIO口。
接下来通过点灯,控制蜂鸣器,流水灯等程序来具体实现。
常用函数就是GPIO_Init和读写函数,这些就可以操作GPIO了。
void GPIO_Init(GPIO_TypeDef* GPIOx, 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);
1.点亮第一个LED灯
接线图
测试demo:
#include "stm32f10x.h" // Device header
#include "Delay.h"
int main(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
while(1)
{
GPIO_ResetBits(GPIOA,GPIO_Pin_0); //可以用GPIO_WriteBit函数
Delay_ms(500);
GPIO_SetBits(GPIOA,GPIO_Pin_0);
Delay_ms(500);
}
}
2.蜂鸣器
接线图
测试demo:
#include "stm32f10x.h" // Device header
#include "Delay.h"
int main(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStruct);
while(1)
{
GPIO_ResetBits(GPIOB,GPIO_Pin_12);
Delay_ms(500);
GPIO_SetBits(GPIOB,GPIO_Pin_12);
Delay_ms(500);
}
}
3.流水灯
接线图
测试demo:
#include "stm32f10x.h" // Device header
#include "Delay.h"
int main(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_All; //选择所有引脚,以按位或的方式控制
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
while(1)
{
GPIO_Write(GPIOA,~0x0001); //0000 0000 0000 0001 PA0~PA15
Delay_ms(500);
GPIO_Write(GPIOA,~0x0002); //0000 0000 0000 0010
Delay_ms(500);
GPIO_Write(GPIOA,~0x0004); //0000 0000 0000 0100
Delay_ms(500);
GPIO_Write(GPIOA,~0x0008); //0000 0000 0000 1000
Delay_ms(500);
GPIO_Write(GPIOA,~0x0010); //0000 0000 0001 0000
Delay_ms(500);
GPIO_Write(GPIOA,~0x0020); //0000 0000 0010 0000
Delay_ms(500);
}
}
这就是常用GPIO输出的做法了,主要就是通过写寄存器来控制对应引脚的电平,记住几个常用函数的用法就行了。不知道函数参数的可以通过右键跳转定义来查看说明。