STM32之GPIO按键实验

时间:2021-04-11 17:50:04


实验板:带有按键的Stm32开发板一块,本人用得是Open107V实验板,型号是107的

库函数:STM32官方3.5的库

其他材料:ST-LINK、跳线若干

实验原理:按键实验和LED实验类似, GPIO点灯是向led的pin脚输出高低电平, 而按键则是向pin口输入高低电平。 对于按键有两种输入模式可以选择, 一,采用上拉输入模式,二,采用浮动浮空输入模式,上拉输入模式在没有按键按下的时候是默认是高电平。符合这个要求。原理图如下:

实验描述:PE5连接到key1,用扫描的方式查询是否有按键按下,key1按下时,LED1状态取反。

库文件:startup/start_stm32f10x_cl.s

              CMSIS/core_cm3.c

              CMSIS/system_stm32f10x.c

               FWlib/stm32f10x_gpio.c

               FWlib/stm32f10x_rcc.c

用户文件:USER/main.c

                  USER/ stm32f10x_it.c

                  USER/led.c

                  USER/key.c

首先配置好工程环境,添加h头文件,接着初始化配置GPIO

******************************led.c******************************

#include"led.h"

void LED_GPIO_Config(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3 | GPIO_Pin_4 |GPIO_Pin_5;
 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
 GPIO_Init(GPIOC,&GPIO_InitStructure);
 GPIO_SetBits(GPIOC,GPIO_Pin_3 | GPIO_Pin_4 |GPIO_Pin_5);
}

****************************led.h**********************************

#ifndef __LED_H
#define __LED_H
#include "stm32f10x.h"
#define ON 1
#define OFF 0
#define LED1(a) if(a) \
     GPIO_SetBits(GPIOC,GPIO_Pin_3);\
      else            \
   GPIO_ResetBits(GPIOC,GPIO_Pin_3)
#define LED2(a) if(a) \
     GPIO_SetBits(GPIOC,GPIO_Pin_4);\
      else            \
   GPIO_ResetBits(GPIOC,GPIO_Pin_4)   
#define LED3(a) if(a) \
     GPIO_SetBits(GPIOC,GPIO_Pin_5);\
      else            \
   GPIO_ResetBits(GPIOC,GPIO_Pin_5) 
void LED_GPIO_Config(void);
#endif             

********************************key.c******************************

#include"led.h"
void Key_GPIO_Config(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);
 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;
 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;
 GPIO_Init(GPIOE,&GPIO_InitStructure);
 
}

******************************main.c****************************

#include "stm32f10x.h"
#include "led.h"
#define KEY_ON 0
#define KEY_OFF 1
void Delay(__IO u32 nCount);
u8 Key_Scan(GPIO_TypeDef* GPIOx,u16 GPIO_Pin);

int main(void)
{
  LED_GPIO_Config();
 LED1(ON);
 
 /*config key*/
 Key_GPIO_Config();
 //GPIO_SetBits(GPIOC,GPIO_Pin_3);
 while(1)
 {
  if(Key_Scan(GPIOE,GPIO_Pin_5)==KEY_ON)
  {
     /*config key*/
   GPIO_WriteBit(GPIOC,GPIO_Pin_3,(BitAction)((1-GPIO_ReadOutputDataBit(GPIOC,GPIO_Pin_3))));
  }
 }
}

u8 Key_Scan(GPIO_TypeDef* GPIOx,u16 GPIO_Pin)
{
 
 if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin)==KEY_ON)
  {
      Delay(0x7ffff);
        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;
}

void Delay(__IO u32 nCount)
{
   for(;nCount != 0; nCount--);
}

实验中采用的是3.5版本的库,上电后,启动文件已经调用了SystemInit()将我们的系统时钟SYSCLK配置为72MHZ。进入mian函数,第一步先调用了在LED灯例程中编写的GPIO_Config(),配置为LED用到的I/O。再使用LED1(ON)宏把LED设置为点亮状态。为了使用LED的工程代码,将led.c和led.h文件也添加到工程中直接调用,将led.c添加到工程中就可以了。在main函数中,检测到有按键按下,就开始执行LED反转的操作。

        最后的实验现象是将配套的STM32开发板供电后,插上ST-LINK,将编译好的程序下载到开发板,LED1亮,按下按键时LED1灭,再按下按键LED1亮,再按下灭,如此可以实现控制操作。