一、GPIO简介
GPIO ( General Purpose Input Output )通用输入输出口
可配置为 8 种输入输出模式
输出模式下可控制端口输出高低电平,用以驱动 LED 、控制蜂鸣器、模拟通信协议输出时序等
输入模式下可读取端口的高低电平或电压,用于读取按键输入、外接模块电平信号输入、 ADC 电压采集、模拟通信协议接收数据等
我们常用的是下拉输入和推挽输出。
二、程序模块
(1)时钟使能
开启时钟总线:时钟总线有三种AHB,APB1和APB2,如上图所示,GPIO挂在时钟APB2上。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
所以我们选择开启APB2的时钟上使能GPIOA。
(2)初始化GPIO
初始化GPIO几乎是必须要做的,根据他的模式可以选择不同的初始状态。
GPIO_InitTypeDef GPIO_InitStructure; //GPIO_InitTypeDef是早就定好的结构体
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//输出模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//PIN—0
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//50兆hz的速度
//用结构体的函数初始化GPIO口
GPIO_Init(GPIOA, &GPIO_InitStructure);//第二个参数为指向结构体的指针,故传地址
(3)设置高低电平
GPIO_ResetBits(GPIOA, GPIO_Pin_0);//0
GPIO_SetBits(GPIOA, GPIO_Pin_0);//1
(4)闪烁灯
#include "stm32f10x.h" // Device header
#include "Delay.h"
int main(void)
{
//使用RCC初始化GPIO时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//使用GPIO_Init函数初始化GPIO
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//通用推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//50兆hz的速度
//用结构体的函数初始化GPIO口
GPIO_Init(GPIOA, &GPIO_InitStructure);//第二个参数为指向结构体的指针,故传地址
while (1)
{
//使用输出或输入函数控制GPIO口
GPIO_ResetBits(GPIOA, GPIO_Pin_0);//0
Delay_ms(500);
GPIO_SetBits(GPIOA, GPIO_Pin_0);//1
Delay_ms(500);
}
}
三、输入模式
(1)基本配置
时钟使能不变------初始化时选择上拉或者下拉输入。
上拉输入:若GPIO引脚配置为上拉输入模式,在默认情况下(GPIO引脚无输入),读取的GPIO引脚数据为1,即高电平。
下拉输入:若GPIO引脚配置为下拉输入模式,在默认情况下(GPIO引脚无输入),读取的GPIO引脚数据为0,即低电平。
(2)C语言基本知识
应了解 宏定义,typedef,结构体,枚举等。
(3)程序输入
应该建立c文件和h文件,h文件方便主函数所在的c文件查找,存放函数和全局变量。
GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_13); //读取当前的GPIO的状态
main.c
#include "stm32f10x.h" // Device header
int main(void)
{
buzzer_init(); //初始化蜂鸣器
lightsenoer_init(); //初始化光敏传感器
while(1)
{
if(lightsenoer_get() == 1) //光线暗,模块本身不亮指示灯
{
buzzer_off(); //关闭蜂鸣器
}
else
{
buzzer_on(); //否者,打开蜂鸣器
}
}
}
void buzzer_init(void) //蜂鸣器初始化
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //开启时钟
GPIO_InitTypeDef GPIO_InitStruct; //定义结构体变量
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12; //pa12端口
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStruct);//传递地址
GPIO_SetBits(GPIOB,GPIO_Pin_12);//初始化为高电平,蜂鸣器不响
}
void buzzer_on(void)
{
GPIO_ResetBits(GPIOB,GPIO_Pin_12);
}
void buzzer_off(void)
{
GPIO_SetBits(GPIOB,GPIO_Pin_12);
}
void buzzer_turn(void)
{
if(GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_12) == 0)
{
GPIO_SetBits(GPIOB,GPIO_Pin_12);
}
else
{
GPIO_ResetBits(GPIOB,GPIO_Pin_12);
}
}
void lightsenoer_init(void) //光敏传感器初始化函数
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; //上拉输入,默认高电平状态;若始终接在端口上,也可以选择浮空输入;只要保证引脚不会悬空即可
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13; //pb13端口
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStruct);
}
uint8_t lightsenoer_get(void) //返回端口值函数
{
return GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_13);
}