STM32按键控制学习指南

一.按键控制

1.封装

直接复制之前做过的文件更方便,不用再重头配置,改名为按键控制,点开

在改文件夹下新建文件夹Hardware,存放硬件驱动

如之前新建同样的操作(上一篇),在魔术棒和三角堆加入Hardware

新建.c 文件,用来封装LED驱动文件

.h 存放驱动程序可以对外提供的函数或变量声明

.c右键添加头文件

.h中添加防止头文件重复包含的代码,这里是固定格式

注意:这里前面是两个下划线,而且下划线前要加空格,最后空行结尾

打开LED.c文件,写入初始化函数void LED_Init(void),在函数里打开时钟,配置端口模式

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //打开时钟

配置端口模式

不提示代码的话试一下,按ctrl+alt+空格

GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOA, &GPIO_InitStructure);  

这里的(GPIOA, &GPIO_InitStructure),第一个参数初始化GPIOA外设,第二个是结构体变量名,&是取地址符号,地址传递

在.h文件添加void LED_Init(void)声明函数可被外部调用

在main.c上面添加 #include "LED.h" 包含LED的模块的头文件

在主函数中调用LED_init,完成初始化,编译下载两个LED都是亮的状态

在LED.c文件中再加入这句,这样不操作LED就是熄灭状态

GPIO_SetBits(GPIOA,GPIO_Pin_1 | GPIO_Pin_2);  

定义LED的开和关

void LED1_ON(void)
{
    GPIO_ResetBits(GPIOA, GPIO_Pin_1);
}
void LED1_OFF(void)
{
    GPIO_SetBits(GPIOA, GPIO_Pin_1);

void LED2_ON(void)
{
    GPIO_ResetBits(GPIOA, GPIO_Pin_2);
}
void LED2_OFF(void)
{
    GPIO_SetBits(GPIOA, GPIO_Pin_2);

然后在.h文件中声明

在主函数中调用,下载编译可以看到两个LED灯交替闪烁

main.c代码

#include "stm32f10x.h"                 // Device header

#include "Delay.h"

#include "LED.h" ​

int main(void)

{

        LED_Init();

        while(1)

        {

                LED1_ON(); 

                LED2_OFF();

                Delay_ms(500);

                LED1_OFF();

                LED2_ON();

                Delay_ms(500);

        }

} ​

2.按键

同上步一样,右键Hardware,新建.c .h文件

在.c添加头文件,.h搭建基本框架

#ifndef __LED_H
#define __LED_H

#endif

在Key.c文件写初始化函数 void Key_Init(void)

将按键的两个端口初始化为上拉输入的模式(按下低电平,松手高电平)

添加读取按键值的函数

uint8_t就是unsigned char(用于表示0到255之间的整数值,不包含负数)

uint8_t Key_GetNum(void)     //调用函数,返回按下按键的键码

定义变量    uint8_t KeyNum = 0;   

接下来写读取按键端口的功能           

打开Library,找到gpio.h滑到最后


GPIO的读取函数

GPIO_ReadInputDataBit 读取输入数据寄存器某一端口的输入值

GPIO_ReadInputData 读取整个输入数据寄存器

GPIO_ReadOutputDataBit 读取输出数据寄存器的某一位

GPIO_ReadOutputData 读取整个输出数据寄存器


0代表低电平,1代表高电平

如果读取PB1端口=0,就代表按键按下

if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)

按键按下时会有抖动,在上面添加 #include "Delay.h"

然后添加 Delay_ms消除抖动

Delay_ms(20);
while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0);
Delay_ms(20);
KeyNum = 1;  //传递键码

然后在.h文件声明函数(这里uint8出错可以不管,想解决看最后)

在main.c文件上加入 #include "Key.h"

主循环之前初始化按键 Key_Init();

然后定义全局变量 

uint8_t KeyNum;   //存放键码的返回值

main.c完整代码

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LED.h"
#include "Key.h"

uint8_t KeyNum;

int main(void)
{
    LED_Init();
    Key_Init();
    
    while(1)
    {
        KeyNum = Key_GetNum();
        if (KeyNum == 1)
        {
            LED1_ON();
        }
        if (KeyNum == 2)
        {
            LED2_OFF();
        }
    }
}
 

想要实现按下点亮,再按熄灭

驱动文件中调用 void LED1_Turn(void) 函数,LED状态取反

调用 GPIO_ReadOutputDataBit 函数,读取当前端口输出状态,输出0,置1,否则置0,实现端口电平翻转

LED.c代码

#include "stm32f10x.h"                  // Device header

void LED_Init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  //打开时钟

    GPIO_InitTypeDef GPIO_InitStructure;     //定义结构体变量
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    GPIO_SetBits(GPIOA,GPIO_Pin_1 | GPIO_Pin_2);
}
void LED1_ON(void)
{
    GPIO_ResetBits(GPIOA, GPIO_Pin_1);
}
void LED1_OFF(void)
{
    GPIO_SetBits(GPIOA, GPIO_Pin_1);
}
void LED1_Turn(void)
{
    if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_1) == 0)
    {
        GPIO_SetBits(GPIOA, GPIO_Pin_1);
    }
    else
    {
        GPIO_ResetBits(GPIOA, GPIO_Pin_1);
    }
}
void LED2_ON(void)
{
    GPIO_ResetBits(GPIOA, GPIO_Pin_2);
}
void LED2_OFF(void)
{
    GPIO_SetBits(GPIOA, GPIO_Pin_2);
}
void LED2_Turn(void)
{
    if (GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_2) == 0)
    {
        GPIO_SetBits(GPIOA, GPIO_Pin_2);
    }
    else
    {
        GPIO_ResetBits(GPIOA, GPIO_Pin_2);
    }
}
 

在头文件中声明

主文件中改为 LED1_Turn,编译下载

二.光敏传感器控制蜂鸣器

1.封装蜂鸣器

复制上面的文件改名为光敏传感器控制蜂鸣器,同样右键Hardware,新建.c和.h文件

同之前一样.c文件添加头文件,.h文件添加框架

复制LED.c的内容到Buzzer.c中,修改为Buzzer_Init、Buzzer_ON、Buzzer_OFF、Buzzer_Turn,引脚改为开启GPIOB的时钟,GPIOB, GPIO_Pin_12

#include "stm32f10x.h"                  // Device header

void Buzzer_Init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    GPIO_SetBits(GPIOB, GPIO_Pin_12);
}
void Buzzer_ON(void)
{
    GPIO_ResetBits(GPIOB, GPIO_Pin_12);
}
void Buzzer_OFF(void)
{
    GPIO_SetBits(GPIOB, GPIO_Pin_12);
}
void Buzzer_Turn(void)
{
    if (GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_12) == 0)
    {
        GPIO_SetBits(GPIOB, GPIO_Pin_12);
    }
    else
    {
        GPIO_ResetBits(GPIOB, GPIO_Pin_12);
    }
}

声明函数

修改main.c,编译下载测试,蜂鸣器鸣响

#include "stm32f10x.h"                 // Device header

#include "Delay.h"

#include "Buzzer.h" ​

uint8_t KeyNum; ​

int main(void)

{

        Buzzer_Init();  //初始化蜂鸣器

        while(1)

        {

                Buzzer_ON();

                Delay_ms(500);

                Buzzer_OFF();

                Delay_ms(500);

                Buzzer_Turn();

                Delay_ms(500);

                Buzzer_Turn();

                Delay_ms(500);

        }

}

2.封装光敏传感器

同样右键Hardware,新建.c和.h文件

添加头文件,添加框架

LightSensor.c文件中添加函数 void LigtSensor_Init(void) 

复制按键中的初始化程序,光敏传感器连接13号口,这里改为GPIO_Pin_13

#include "stm32f10x.h"                  // Device header

void LigtSensor_Init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);         

    GPIO_InitTypeDef GPIO_InitStructure;              //定义结构体              
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;                
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    
    GPIO_Init(GPIOB, &GPIO_InitStructure);    
}

uint8_t LightSensor_Get(void) //返回端口值
{
    return GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_13);

}
 

声明函数

最后在主函数中测试,上面添加 #include "LightSensor.h"

编译下载,遮住,响,去掉,不响

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "Buzzer.h"
#include "LightSensor.h"

uint8_t KeyNum;

int main(void)
{
    Buzzer_Init();
    LigtSensor_Init();  //初始化光敏传感器
    
    while(1)
    {
        if (LightSensor_Get() == 1) //光线暗的情况
        {
            Buzzer_ON();
        }
        else
        {
            Buzzer_OFF();
        }
    }
}
 


终于写完了,虽然写的不是特别完善,后面学明白了会慢慢更改,加入更详细的原理解释和效果图,太累了,先这样吧,感谢美女帅哥的阅读,如果有哪里不合适还请多多指教


uint8报错问题,加一句 #include "stdint.h"

作者:鲨鱼爱吃菜

物联沃分享整理
物联沃-IOTWORD物联网 » STM32按键控制学习指南

发表回复