本帖最后由 小恶魔owo 于 2024-12-3 22:21 编辑

(一)简介
我们可以提供,一个按钮控制板载LED灯,来学习GPIO的输入和输出
板载LED的引脚为PC13,我们选择一个按钮引脚为PA0
(将按钮一段连接PA0,另一端连接GND)

(二)讲解
为了main函数的简洁,同时让操作不用很复杂,我们可以将LED和按钮KEY,创建一个库
然后在main里面调用LED和KEY库,类似于arduino那样的编程方法
image.png

我们先复制一个工程模板,然后在Hardware里面添加两个库
LED.c,LED.h
Key.c,Key.h
image.png

然后在库文件管理里面添加
image.png
image.png

LED.C
首先引用一下stm32库
#include "stm32f10x.h"   
复制代码

初始化PC13,这个在上节课讲过
void LED_Init(void)
  • {
  •         /*开启时钟*/
  •         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);                //开启GPIOC的时钟
  •         
  •         /*GPIO初始化*/
  •         GPIO_InitTypeDef GPIO_InitStructure;
  •         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  •         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
  •         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  •         GPIO_Init(GPIOC, &GPIO_InitStructure);                                                //将PC13引脚初始化为推挽输出
  •         

  • }
  • 复制代码

    然后,我们可以定义三个函数,LED的开关
    void LED1_ON(void)
  • {
  •         GPIO_SetBits(GPIOC, GPIO_Pin_13);                //设置PC13引脚为高电平
  • }

  • void LED1_OFF(void)
  • {
  •         GPIO_ResetBits(GPIOC, GPIO_Pin_13);                //设置PC13引脚为低电平
  • }
  • 复制代码

    还有LED的电平转换
    电平转换的就是先检测PC13引脚的状态,然后如果状态为0则设置为1,反之为1设置为0
    void LED1_Turn(void)
  • {
  •         if (GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_13) == 0)                //获取输出寄存器的状态,如果当前引脚输出低电平
  •         {
  •                 GPIO_SetBits(GPIOC, GPIO_Pin_13);                                        //则设置PA1引脚为高电平
  •         }
  •         else                                                                                                        //否则,即当前引脚输出高电平
  •         {
  •                 GPIO_ResetBits(GPIOC, GPIO_Pin_13);                                        //则设置PA1引脚为低电平
  •         }
  • }
  • 复制代码


    LEC.H
    为了让main的函数能够调用LED库的函数,我们还需要一个.H文件
    其中#ifndef __LED_H、#define __LED_H、#endif为固定格式,名称根据.C函数来定义
    中间放我们定义的函数名字,格式为 void xxxx(void);
    #ifndef __LED_H
  • #define __LED_H

  • void LED_Init(void);
  • void LED1_ON(void);
  • void LED1_OFF(void);
  • void LED1_Turn(void);


  • #endif
  • 复制代码


    Key.C
    同理,按钮库也是要引用标准库,而且因为要软件消抖,还要一个delay延迟库
    #include "stm32f10x.h"
  • #include "Delay.h"
  • 复制代码

    初始化,按钮引脚PA0,和设置LED差不多,但是注意模式我们选择了GPIO_Mode_IPU上拉输入模式
    void Key_Init(void)
  • {
  •         /*开启时钟*/
  •         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);                //开启GPIOA的时钟
  •         
  •         /*GPIO初始化*/
  •         GPIO_InitTypeDef GPIO_InitStructure;
  •         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  •         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  •         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  •         GPIO_Init(GPIOA, &GPIO_InitStructure);                                                //将PA0引脚初始化为上拉输入
  • }
  • 复制代码

    声明一个无符号的8位整型变量,意味着这个变量可以输出0-255的整数
    代码内定义了一个KeyNum=0,当检测到PA0为1时,即按钮按下时
    延时20毫秒消抖然后再次判断,如果还是为1,那就将KeyNum设置为1
    然后函数Key_GetNum返回一个1,如果没有进入按钮模式,那就返回0
    uint8_t Key_GetNum(void)
  • {
  •         uint8_t KeyNum = 0;                //定义变量,默认键码值为0
  •         
  •         if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 1)                        //读PA0输入寄存器的状态,如果为1,则代表按键1按下
  •         {
  •                 Delay_ms(20);                                                                                        //延时消抖
  •                 while (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 1);        //等待按键松手
  •                 Delay_ms(20);                                                                                        //延时消抖
  •                 KeyNum = 1;                                                                                                //置键码为1
  •         }
  •         

  •         
  •         return KeyNum;                        //返回键码值,如果没有按键按下,所有if都不成立,则键码为默认值0
  • }
  • 复制代码

    Key.H

    #ifndef __KEY_H
  • #define __KEY_H

  • void Key_Init(void);
  • uint8_t Key_GetNum(void);

  • #endif
  • 复制代码


    Main函数
    将所需的库全部引用出来
    同时定义一个整数型变量KeyNnm,用来储存按钮的状态
    #include "stm32f10x.h"
  • #include "Delay.h"
  • #include "LED.h"
  • #include "Key.h"
  • uint8_t KeyNum;  //定义用于接收按键键码的变量
  • 复制代码

    首先进行灯和按钮引脚的初始化,初始化完成之后进入while循环
    KeyNum获取Key库的Key_GetNum()函数
    当按钮按下时,Key_GetNum()函数会返回1,否则返回0
    当KeyNum接收到1时,执行LED1_Turn函数,将LED电平翻转
    int main(void)
  • {
  •         /*模块初始化*/
  •         LED_Init();                //LED初始化
  •         Key_Init();                //按键初始化
  •        
  •         while (1)
  •         {
  •                 KeyNum = Key_GetNum();                //获取按键键码
  •                
  •                 if (KeyNum == 1)                        //按键1按下
  •                 {
  •                         LED1_Turn();                        //LED1翻转
  •                 }

  •         }
  • }
  • 复制代码


    (三)程序现象

    eacd143316237a24a92f -small-original.gif