我最近在某宝买了一块stm32f103的开发板,于是开启了我的stm32学习之旅。在学习了GPIO的操作之后,于是突发奇想,可不可以用一个按键实现多个功能呢?经过思考于是就实现了(第一次按下按键LED灯亮,第二次按下按键蜂鸣器发出声音,第三次按下按键LED熄灭,第四次按下按键蜂鸣器停止发出声音,实验现象:https://b23.tv/VxFXfMd)这个功能。当然在写代码的时候出现了一些问题,下面就有我来分享一下经验(参考代码在最下面):
一、首先我们操作的是外设,当然要把这个外设·对应的GPIO口使能时钟。
二、由于我们用到了LED、蜂鸣器、按键,我们肯定要配置GPIO输入,和输出模式。
三、读出对应GPIO口的电平状态,或者输出高低电平。
逻辑分享:
由于我们使用了GPIO的输出模式点亮LED(蜂鸣器发出声音)或者熄灭LED灯(蜂鸣器停止发出声音),所以要把GPIO设置成推完输出模式,至于输出速度,我是选择50mhz,我们还使用了按键,肯定要配置相应GPIO口为输入模式,至于是上拉输入模式还是下拉模式,取决于硬件的连接(如果按键的一端的电平为低电平,我们就采用上拉输入,如果按键的一端的电平为高电平,那么我们就采用下拉输入)我们这个按键采用的是上拉输入模式。
我们到底怎么实现这个功能呢?要实现一个按键实现多个功能,我们可以想到定义一个标志位,当按键按下,这个标志就加一,然后再主函数里面用switch语句,根据标志位的值的不同,我们case语句实现不同的功能,那么就有一个问题出来了,我们怎么再主函数面使用这个标志位的值?这个时候我们会想到用函数返回值,但是这个时候就会出现怎么判断按键按下呢?这个时候extern这个关键字就非常的重要,它可以扩大变量的范围,我们在LED.c文件中定义全局变量flag ,然后用extern在main.c来声明这个变量,于是我们就可以使用这个变量的值,在mian.c中。我们写一个普通的按键按下的函数,当按键按下我们就认flag加一。最后在主函数里面用switch就可以了。
#include "LED.h"
#include "delay.h"
u8 flag=0;
void LED_init(void)
{
GPIO_InitTypeDef GPIO_InitStructe;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitStructe.GPIO_Pin= GPIO_Pin_5;
GPIO_InitStructe.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStructe.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructe);
GPIO_SetBits(GPIOB,GPIO_Pin_5);
}
void BEEP_init(void)
{
GPIO_InitTypeDef GPIO_InitStructe;
GPIO_InitStructe.GPIO_Pin= GPIO_Pin_8;
GPIO_InitStructe.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStructe.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructe);
GPIO_ResetBits(GPIOB,GPIO_Pin_8);
}
void key_init(void)
{
GPIO_InitTypeDef GPIO_InitStructe1;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);
GPIO_InitStructe1.GPIO_Pin=GPIO_Pin_3;
GPIO_InitStructe1.GPIO_Mode=GPIO_Mode_IPU;
GPIO_Init(GPIOE,&GPIO_InitStructe1);
}
u8 key_scan()
{
if(KEY==0)
{
delay_ms(20);
if(KEY==0)
{
flag++;
if(flag>4)
flag=0;
return 1;
}
}
return 0;
}
#include "LED.h"
#include "delay.h"
extern u8 flag;
int main()
{
LED_init();
BEEP_init();
key_init();
delay_init();
while(1)
{ delay_ms(200);
if(key_scan())
{
switch (flag)
{
case 1: GPIO_ResetBits(GPIOB,GPIO_Pin_5); break;//led灯开
case 3: GPIO_SetBits(GPIOB,GPIO_Pin_5); break;//led灯关
case 2: GPIO_SetBits(GPIOB,GPIO_Pin_8); break;//蜂鸣器开
case 4: GPIO_ResetBits(GPIOB,GPIO_Pin_8); break;//蜂鸣器关
}
}
}
}