初學者學習筆記,錯誤不足望指正。
上一篇: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
二、挖掘代碼(部分)
2.1寄存器初識
外設時鐘使能寄存器、端口配置高寄存器、端口輸出數據寄存器在上一篇介紹https://blog.csdn.net/qq_37241109/article/details/104156883
1.端口輸入數據寄存器
2.2代碼分析
從main.c入手。
main函數分爲三個部分:小燈配置、按鍵配置、按鍵控制小燈
小燈配置和流水燈配置大同小異,只是這裏小燈的亮滅採用/直接操作寄存器方法控制I/O(流水燈採用的是庫函數方式)
按鍵配置和小燈配置差不多不同的地方是模式選擇上拉輸入模式 GPIO_Mode_IPU
按鍵控制小燈主要關注按鍵掃描函數
判斷是否有按鍵按下,若有則延時消抖再判斷一遍,有的話再判斷一遍,確認按鍵按下之後循環釋等待按鍵釋放,按鍵釋放之後返回1,按鍵未按下返回0
主函數內,判斷按鍵按下,小燈反轉一次。
判斷是否按鍵按下調用如下函數:
三、總結
在對流水燈的原理了解之後,掌握按鍵控制並不難。