初学者学习笔记,错误不足望指正。
上一篇:STM32学习(基础)——从流水灯开始了解GPIO https://blog.csdn.net/qq_37241109/article/details/104156883
本篇任务:完成POLLING按键实例——用按键控制小灯亮灭
在User文件夹中新建Key文件夹。
在Led文件夹中新建main.c、bsp_key.c、bsp_key.h这三个文件。
打开工程,将main.c、bsp_key.c、bsp_key.h添加到工程的USER组中。(注意先移除之前的main函数)
main.c
#include "bsp_led.h"
#include "bsp_key.h"
int main(void)
{
/* config the led */
LED_GPIO_Config();
LED1_ON;
/* config the key */
Key_GPIO_Config();
while(1)
{
if(Key_Scan(GPIOC,GPIO_Pin_13) == KEY_ON )
{
/*LED1··´×ª*/
LED1_TOGGLE;
}
}
}
bsp_led.c
#include "bsp_led.h"//调用头文件
void LED_GPIO_Config(void)//初始化LED的IO
{
//定义一个GPIO_InitTypeDef类型的结构体
GPIO_InitTypeDef GPIO_InitStructure;
//开启LED的外设时钟
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB,ENABLE);
/*选择要控制的引脚*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
//设置引脚模式为通用推挽输出
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
//设置引脚速率为50MHZ
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//调用库函数,进行端口初始化
GPIO_Init(GPIOB,&GPIO_InitStructure);
}
bsp_led.h
#ifndef __LED_H
#define __LED_H
#include "stm32f10x.h"//STM32的地址映射,包含了STM32的所有寄存器的地址
/*直接操作寄存器方法控制IO*/
#define digitalHi(p,i) {p->BSRR = i;}
#define digitalLo(p,i) {p->BRR = i;}
#define digitalToggle(p,i){p->ODR ^= i;}
/* 定义控制IO的宏 */
#define LED1_TOGGLE digitalToggle(GPIOB,GPIO_Pin_8)
#define LED1_OFF digitalHi(GPIOB,GPIO_Pin_8)
#define LED1_ON digitalLo(GPIOB,GPIO_Pin_8)
void LED_GPIO_Config(void);//初始化LED端口
#endif
bsp_key.c
#include "stm32f10x.h"
#include "bsp_led.h"
#include "bsp_key.h"
void Delay(__IO uint32_t nCount)
{
for(;nCount !=0; nCount--);
}
void Key_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* 开启按键端口(pc) 的时钟 */
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
//GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOC,&GPIO_InitStructure);
}
uint8_t Key_Scan(GPIO_TypeDef* GPIOx,u16 GPIO_Pin)
{
/* 监测是否有按键按下 */
if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON)
{
/*延时消抖*/
Delay(10000);
if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON)
{
/* 等待按键释放 */
while(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON);
return KEY_ON;
}
else
return KEY_OFF;
}
else
return KEY_OFF;
}
bsp_key.h
#ifndef __KEY_H
#define __KEY_H
#include "stm32f10x.h"
#define KEY_ON 0
#define KEY_OFF 1
void Key_GPIO_Config(void);
uint8_t Key_Scan(GPIO_TypeDef* GPIOx,u16 GPIO_Pin);
#endif
外设时钟使能寄存器、端口配置高寄存器、端口输出数据寄存器在上一篇介绍https://blog.csdn.net/qq_37241109/article/details/104156883
1.端口输入数据寄存器
从main.c入手。
main函数分为三个部分:小灯配置、按键配置、按键控制小灯
小灯配置和流水灯配置大同小异,只是这里小灯的亮灭采用/直接操作寄存器方法控制I/O(流水灯采用的是库函数方式)
按键配置和小灯配置差不多不同的地方是模式选择上拉输入模式 GPIO_Mode_IPU
按键控制小灯主要关注按键扫描函数
判断是否有按键按下,若有则延时消抖再判断一遍,有的话再判断一遍,确认按键按下之后循环释等待按键释放,按键释放之后返回1,按键未按下返回0
主函数内,判断按键按下,小灯反转一次。
判断是否按键按下调用如下函数:
在对流水灯的原理了解之后,掌握按键控制并不难。