- 使用开发板:STM32F103ZET6
- 编译环境 :keil 5
一、原理图
- 使用上次的led原理图和 这次按键原理图
- 本次使用到的使 LED2 , K2
二 、需要操作到的寄存器
-
1.由芯片手册的可知
-
2.控制PE5、输出低电平,需要配置相对应的寄存器
-
3.控制PE4、设置为输入模式,从引脚中获取值
由存储器映射表可知, GPIOE 寄存器的首地址
-
4.使用寄存器输出低电平的方法步骤 偏移地址: 0x18
-
APB2 外设时钟使能寄存器(RCC_APB2ENR)
-
端口配置低寄存器(GPIOx_CRL) (x=A…E) 偏移地址: 0x00
-
端口输出数据寄存器(GPIOx_ODR) (x=A…E) 地址偏移: 0Ch
-
端口输入数据寄存器(GPIOx_IDR) (x=A…E) 地址偏移: 0x08
* 1. 配置 RCC寄存器是能 GPIOE端口 GPIO-[6]
* 2. 设置 端口配置低寄存器(GPIOx_CRL) 里的 GPIOE-[20:23]
* 设置为 0001 输出模式的 CNFy[1:0]-00-通用推挽输出模式,MODEy[1:0]-01-输出模式,最大速度10MHZ
* 设置为 0100 输入模式的 CNFy[1:0]-01-浮空输入模式,MODEy[1:0]-00-输入模式
* 3. 检测端口输入寄存器(GPIOx_IDR) 第5位是否为 0
* 若为 0, 配置输出数据寄存器(GPIOx_ODR)第5位 为 0
*
三、使用固件库编程
- bsp_led.h
#ifndef _BSP_LED_H_
#define _BSP_LED_H_
#include "stm32f10x.h"
#define LED_G_GPIO_PIN GPIO_Pin_5
#define LED_G_GPIO_PORT GPIOE
#define LED_G_GPIO_CLK RCC_APB2Periph_GPIOE
#define NO 1 /* 开 */
#define OFF 0 /* 关 */
#define LED_G(a) {if(a) \
GPIO_SetBits(LED_G_GPIO_PORT, LED_G_GPIO_PIN ); \
else \
GPIO_ResetBits(LED_G_GPIO_PORT, LED_G_GPIO_PIN );}
#define LED_G_TOGGLE {LED_G_GPIO_PORT->ODR ^= LED_G_GPIO_PIN;}
void LED_GPIO_Config(void);
#endif /* _BSP_LED_H_ */
- bsp_led.c
#include "bsp_led.h"
void LED_GPIO_Config(void)
{
/* 定义要操作的GPIO结构体,然后对其初始化 */
GPIO_InitTypeDef GPIO_InitStruct;
/* 初始化时钟 */
RCC_APB2PeriphClockCmd(LED_G_GPIO_CLK, ENABLE);
/* 配置GPIOE */
GPIO_InitStruct.GPIO_Pin = LED_G_GPIO_PIN; /* LED连接的引脚 */
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; /* 设置为推挽输出模式 */
GPIO_InitStruct.GPIO_Speed= GPIO_Speed_50MHz; /* 50M速度 */
/* 初始化GPIO */
// GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
GPIO_Init(LED_G_GPIO_PORT, &GPIO_InitStruct);
}
- bsp_key.h
#ifndef _BSP_KEY_H_
#define _BSP_KEY_H_
#include "stm32f10x.h"
#define KEY_ON 0
#define KEY_OFF 1
#define KEY_GPIO_PIN GPIO_Pin_4
#define KEY_GPIO_PORT GPIOE
#define KEY_GPIO_CLK RCC_APB2Periph_GPIOE
void KEY_GPIO_Config(void);
uint8_t Key_Scan(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);
#endif /* _BSP_KEY_H_ */
- bsp_key.c
#include "bsp_key.h"
#include "stm32f10x.h"
void KEY_GPIO_Config(void)
{
/* 定义要操作的GPIO结构体,然后对其初始化 */
GPIO_InitTypeDef GPIO_InitStruct;
/* 初始化时钟 */
RCC_APB2PeriphClockCmd(KEY_GPIO_CLK, ENABLE);
/* 配置GPIOE */
GPIO_InitStruct.GPIO_Pin = KEY_GPIO_PIN; /* KEY连接的引脚 */
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; /* 设置为浮空输入模式 */
/* 初始化GPIO */
// GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
GPIO_Init(KEY_GPIO_PORT, &GPIO_InitStruct);
}
/* 按键扫描 */
uint8_t Key_Scan(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
{
/* 读取 KEY 的状态 */
if( GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) == KEY_ON)
{
// 松手检测
while( GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) == KEY_ON )
return KEY_ON;
}
else
{
return KEY_OFF;
}
}
- main.c 主文件
#include "stm32f10x.h" // Device header
/* bsp: board support package 板级支持包 */
#include "bsp_led.h"
#include "bsp_key.h"
void Delay(uint32_t count)
{
for(; count!=0; count--);
}
int main(void)
{
LED_GPIO_Config();
GPIO_ResetBits(LED_G_GPIO_PORT, LED_G_GPIO_CLK );
KEY_GPIO_Config();
GPIO_ResetBits(KEY_GPIO_PORT, KEY_GPIO_PIN );
while(1)
{
if( Key_Scan(KEY_GPIO_PORT, KEY_GPIO_PIN) == KEY_ON )
{
Delay(0xff); /* 软件消抖 */
if( Key_Scan(KEY_GPIO_PORT, KEY_GPIO_PIN) == KEY_ON )
{
LED_G_TOGGLE;
// LED_G(NO);
}
Delay(0xff); /* 软件消抖 */
}
// else
// {
// LED_G(OFF);
// }
}
}
- 结果
* 1. 按下 按键 ,LED 0110110交替亮灯