32单片机3.用按钮控制LED灯

按键:常见的输入设备,按下导通,松手断开
按键抖动:由于按键内部使用的是机械式弹簧片来进行通断的,所以在按下和松手的瞬间会伴随由一连串的抖动

单片机上按键的电路,第一个按键连接的是接口GPIOA的0脚,第二个按键连接的是接口GPIOC的13脚,当按钮按下的时候,相应的引脚就是高电平,按钮松开,就恢复了原来的低电平。

因为前面一个工程是点亮LED灯,直接封装函数就行创建一个LED.c还有一个LED.h文件

LED.c代码如下

#include "stm32f10x.h"                  // Device header

void LED_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//打开APB2外设的时钟
	
	GPIO_InitTypeDef GPIO_InitStructure;   //创建一个 GPIO_InitTypeDef 结构体
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;  //利用结构体配置端口模式
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5|GPIO_Pin_0|GPIO_Pin_1;//利用结构体配置引脚
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;//设置输出频率
	GPIO_Init(GPIOB,&GPIO_InitStructure); //用Init函数配置GPIOB端口
	
	GPIO_SetBits(GPIOB,GPIO_Pin_5|GPIO_Pin_0|GPIO_Pin_1); //让一开始等灯是灭的
}
void LEDR_ON(void)     //501 RGB     //红灯开
{
	GPIO_ResetBits(GPIOB,GPIO_Pin_5);
}
void LEDR_OFF(void)   //红灯灭
{
	GPIO_SetBits(GPIOB,GPIO_Pin_5);
}
void LEDG_ON(void)     //501 RGB    //绿灯开
{
	GPIO_ResetBits(GPIOB,GPIO_Pin_0);
}
void LEDG_OFF(void)         //绿灯关
{
	GPIO_SetBits(GPIOB,GPIO_Pin_0);
}
void LEDB_ON(void)     //501 RGB  //蓝灯开
{
	GPIO_ResetBits(GPIOB,GPIO_Pin_1);
}
void LEDB_OFF(void) //蓝灯关
{
	GPIO_SetBits(GPIOB,GPIO_Pin_1);
}

LED.h代码如下

#ifndef __LED_H
#define __LED_H

void LED_Init(void);
void LEDR_ON(void);
void LEDR_OFF(void);
void LEDG_ON(void);
void LEDG_OFF(void);
void LEDB_ON(void);
void LEDB_OFF(void);
#endif

函数封装完成,接下来就是封装按键代码。和上面的LED封装一样,都需要两个文件,分别是Key.c、Key.h。在c文件中我们要给两个按钮初始化,初始化的步骤就是1.打开时钟。2.利用结构体进行配置。3.用Init函数通过结构体对端口进行配置。和LED不同的是,引脚的模式要调成上拉输入。初始化两个按钮之后,还需要写一个按钮读取函数,作用是对两个按钮哪一个按下进行判断,还需要软件消抖。读取函数还要用到一个函数GPIO_ReadInputDataBit,作用是对GPIO端口具体引脚进行数据读取。

Key.c代码如下

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
void Key1_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU; //读取按钮,调试成上拉输入
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
}
void Key2_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,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_10MHz;
	GPIO_Init(GPIOC,&GPIO_InitStructure);
}
uint8_t Key_GetNum(void) //按键读取的函数
{
	uint8_t KeyNum=0;
	if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==0)
	{
		Delay_ms(20);
		while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==0);
		Delay_ms(20);
		KeyNum=1;
	}
	if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_13)==0)
	{
		Delay_ms(20);
		while(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_13)==0);
		Delay_ms(20);
		KeyNum=2;
	}
	return KeyNum;
}

Key.h代码如下

#ifndef __KEY_H
#define __KEY_H

void Key1_Init(void);
void Key2_Init(void);
uint8_t Key_GetNum(void);
#endif

现在就是完事具备,只需要把main函数写完就行,main函数代码如下:

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

uint8_t KeyNum;  //全局变量

int main(void)
{
	LED_Init();    //LED初始化
	Key1_Init();   //按键1初始化
	Key2_Init();   //按键2初始化
	while(1)
	{
		KeyNum=Key_GetNum();  //按键读取
		if(KeyNum==1)        //如果按键1被按下红灯闪烁
		{
			LEDR_ON();       
			Delay_ms(500);
			LEDR_OFF();
			Delay_ms(500);
		}
		if(KeyNum==2)     //如果按键2被按下绿灯闪烁
		{
			LEDG_ON();
			Delay_ms(500);
			LEDG_OFF();
			Delay_ms(500);
		}
	}
}

但是工程出了一点问题,目标作用是,当按钮一按下,红灯闪烁,当按钮二按下,绿灯闪烁,但是下载进去板子发现实现不了,板子上的作用是:单独按两个按键没有用,但是按完第一个按键,再去摁第二个按键,绿灯闪烁,要想让绿灯再次闪烁的话,必须再按一下按键一才行。不知道哪里出了问题,是因为APB2上的时钟不能及时的调整嘛,还是因为初始化的时候智能初始化一个按钮,是因为这两个按钮不在一个接口上控制的嘛,按钮一是GPOIOA,按钮2是GPIOC,不知到。

今天就这样吧,明天加油。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值