STM32F4——GPIO基本知识
GPIO基本认识
STM32F4共7组I/O,每组I/O有16个I/O口。
每组IO的通过10个32位寄存器控制,分别控制I/O的配置、功能和数据等内容。
其中部分寄存器32位全部使用,每两位控制一个I/O口,部分寄存器16-31位保留,只有0-15位起作用,一位控制一个I/O口。
GPIO初始化
初始化步骤:
- 使能时钟,在头文件stm32f4xx_rcc.h中找到相应时钟
- 初始化I/O,运用到stm32f4xx_gpio.h中GPIO_Init()函数
- I/O口置初值
GPIO控制方式
库函数方式
eg:
GPIO_SetBits() //对应IO输出1
GPIO_ResetBits() //对应IO输出0
位带操作方式
宏定义IO口,操作某个IO
eg:
#define LED0 PAout(9) //输出
#define KEY0 PEin(4) //输入
MDK注意事项
- 开发环境配置
- 头文件路径设置
- 源文件包含到分组中
实验程序设计
整体设计
将LED,BEEP,KEY各部件的相关程序分别存放在不同目录的源文件下,实现不同部件文件的模块化管理。并在相应的头文件内加以声明,方便在主函数程序中调用。
模块结构图:
LED模块
硬件连接
软件设计
头文件led.h
作用:声明相关函数等内容
程序源码:
#include "sys.h"
#include "stm32f4xx.h"
#ifndef __LED_H
#define __LED_H
void LED_Init(void);//LED初始化函数声明
//LED0,LED1口宏定义
#define LED0 PFout(9)
#define LED1 PFout(10)
#endif
源文件led.c
作用:定义LED_Init()初始化函数
程序源码:
#include "led.h"
#include "stm32f4xx.h"
void LED_Init(void) //LED初始化函数定义
{
GPIO_InitTypeDef GPIO_InitStructure;//定义结构体变量,IO初始化函数中数据传入使用
//注意:定义结构体 应在 时钟使能 之前,否则编译出现警告!
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);//时钟,使能
//F9
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//第九位
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;//上拉
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;//100MHz
GPIO_Init(GPIOF,&GPIO_InitStructure);//初始化
//F10
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//第十位
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;//上拉
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;//100MHz
GPIO_Init(GPIOF,&GPIO_InitStructure);//初始化
//设置LED初始不亮
LED0 = 1;
LED1 = 1;
}
BEEP模块
硬件连接
软件设计
头文件beep.h
作用:声明相关函数等内容
程序源码:
#include "sys.h"
#include "stm32f4xx.h"
#ifndef __BEEP_H
#define __BEEP_H
void BEEP_Init(void);//声明 蜂鸣器初始化函数
#define BEEP PFout(8)//位操作蜂鸣器
#endif
源文件beep.c
作用:定义BEEP_Init()初始化函数
程序源码:
#include "beep.h"
#include "stm32f4xx.h"
void BEEP_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;//定义结构体变量,IO初始化函数中数据传入使用
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);//时钟,使能
//F8
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8;//第八位
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_DOWN;//下拉
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;//100MHZ
GPIO_Init(GPIOF,&GPIO_InitStructure);//初始化
GPIO_ResetBits(GPIOF,GPIO_Pin_8);//置低电平,蜂鸣器不响
}
KEY模块
硬件连接
软件设计
头文件key.h
作用:声明相关函数等内容
程序源码:
#include "stm32f4xx.h"
#ifndef __KEY_H
#define __KEY_H
void KEY_Init(void);//声明 按键初始化函数
u8 KEY_Scan ( void );//声明 按键扫描函数
//宏定义WK_UP口
#define WK_UP GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)
#endif
源文件key.c
作用:
定义KEY_Init()初始化函数
程序源码:
#include "key.h"
#include "delay.h"
#include "stm32f4xx.h"
void KEY_Init(void)//定义 按键初始化函数
{
GPIO_InitTypeDef GPIO_InitStructure;//定义结构体变量,IO初始化函数中数据传入使用
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);//PA时钟,使能
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN;//普通输入模式
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;//WK_UP
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_DOWN;//下拉
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);//WK_UP初始化
}
定义KEY_Scan()按键扫描函数
KEY_Scan按键扫描函数程序框图:
程序源码:
u8 KEY_Scan ( )//定义 按键扫描函数
{
static u8 key_up=1;//静态变量key_up记录按键状态,上一次按键是否完成
//0——上次按键没有结束,1——上次按键已经结束
if(key_up&&(WK_UP==1))//上次按键已经结束,检测到按键按下
{
delay_ms(10);//延时,消抖
key_up=0;//记录此次按键开始,按键尚未结束
return 1;//有效按键
}
else if(key_up==0&&(WK_UP==0))//上次按键尚未结束,检测到按键松开
{
key_up=1;//记录上次按键结束,可以开始下一次按键
}
return 0;//上次按键已经结束,按键处于松开状态;或上次按键尚未结束,按键处于按下状态,都无效
}
主函数main()
各模块初始化
调用LED_Init()初始化函数,BEEP_Init()初始化函数,KEY_Init()初始化函数,delay_Init()初始化函数
检测按键,循环执行
KEY_Scan()按键扫描函数,并对按键结果进行判断,相关部件做出反应,循环执行
main()程序源码:
#include "stm32f4xx.h"
#include "led.h"
#include "beep.h"
#include "key.h"
#include "delay.h"
int main(void)
{
u8 key;//保存按键扫描返回值
//初始化部分
LED_Init();
BEEP_Init();
KEY_Init();
delay_init(168);
//循环部分
while(1)
{
key=KEY_Scan();//将扫描结果传给key
if(key)//key不为零,即有按键按下
{
LED0=!LED0;
LED1=!LED1;
BEEP=!BEEP;
}
delay_init(10);
}
}
测试结果
按键按下一次,LED灯亮,同时蜂鸣器发出响声,再次按下按键,LED灯灭,同时蜂鸣器停止发声。