stm32--按键控制LED灯和蜂鸣器

最终实现效果:按下一个按键,灯亮蜂鸣器响一下。复位后才可按下一个按键。

main.c部分代码

​
#include "led.h"
#include "key.h"
#include "beep.h"

//备注: LED1--PC4 LED2--PC5  LED3--PC6 LED4--PC7 0亮1灭
// WKUP-PA0 KEY2-PE2 KEY3-PE3 KEY4-PE4

int main()
{
	
	u8 key_val;
	
	LED_Init(); //LED初始化
	KEY_Init(); //按键初始化
	BEEP_Init(); //蜂鸣器初始化
	
	while(1) //使循环不断进行
	{
			key_val = KEY_Scan();
		  switch(key_val)
			{
				case 1: beep_on(); GPIOC->ODR ^= 1 << 4; break; //ODR初始状态高电平1 1异或 
                                     1为0 低电平灯亮;再次循环时 ODR为0  0异或1为1 高电平灯灭
				case 2: beep_on(); GPIOC->ODR ^= 1 << 5; break;
				case 3: beep_on(); GPIOC->ODR ^= 1 << 6; break;
				case 4: beep_on(); GPIOC->ODR ^= 1 << 7; break;
			}
	}
			
}

​

key.c部分

#include "key.h"

//函数的功能:LED初始化
//形参:void
//返回值:void
//备注:PA0-没有按下低电平,按下为高电平

void KEY_Init(void)  //函数的功能:LED初始化(函数名根据习惯自定义)
{
	RCC->AHB1ENR |= 1 << 0;  //使能GPIOA时钟
	RCC->AHB1ENR |= 1 << 4;  //使能GPIOE时钟
	
	/*PA0配置*/
	GPIOA->MODER &= ~(3 << (2 * 0));  //输入模式
	
	GPIOA->PUPDR &= ~(3 << (2 * 0));  //清零
	GPIOA->PUPDR |= 2 << (2 * 0);  	//配置为下拉模式(此处用无上下拉也可)
	
	/*PE2配置*/
	GPIOE->MODER &= ~(3 << (2 * 2));  //输入模式
	GPIOE->PUPDR &= ~(3 << (2 * 2));  //清零
	GPIOE->PUPDR |= 2 << (1 * 2);  	//上拉
	
	/*PE3配置*/
	GPIOE->MODER &= ~(3 << (2 * 3));  //输入模式
	GPIOE->PUPDR &= ~(3 << (2 * 3));  //清零
	GPIOE->PUPDR |= 2 << (1 * 3);  	//上拉
	
	/*PE4配置*/
	GPIOE->MODER &= ~(3 << (2 * 4));  //输入模式
	GPIOE->PUPDR &= ~(3 << (2 * 4));  //清零
	GPIOE->PUPDR |= 2 << (1 * 4);  	//上拉
}

void delay(u32 t)
{
	while(t--);
}

//按键扫描
//形参:void
//返回值:返回1 -- 按键1按下
//备注:PA0 - 没有按下低电平 按下高电平

u8 KEY_Scan(void)  //扫描函数
	
{
	//static 让该函数调用完后flag的值依旧为1
	static u8 flag = 1; //定义没有按下的状态 0:未按下 1:按下
	u8 key = 0;  //初始值
	
	if((KEY1 || KEY2 || KEY3 || KEY4) && flag == 1)  //此刻是高电平
			{
					delay(200000);  //约10ms 延时消抖:先读 延时 再读
				
					if(KEY1)  //此刻是高电平
					{
						flag = 0; //清零
						key = 1;
					}
					else if(KEY2)
					{
						flag = 0;
						key = 2;
					}
					else if(KEY3)
					{
						flag = 0;
						key = 3;
					}
					else if(KEY4)
					{
						flag = 0;
						key = 4;
					}
				
			}
			
			else if(!KEY1 && !KEY2 && !KEY3 && !KEY4) //此时低电平0 未按下
			{
					flag = 1;  //为下一次按键按下做准备
			}
			return key;  //如果没有按下返回初始值0 按下则返回1
}


key.h部分

#ifndef _LED_H_
#define _LED_H_

#include <stm32f4xx.h>
void KEY_Init(void);
void delay(u32 t);
u8 KEY_Scan(void);

#define KEY1 GPIOA->IDR & (1 << 0) //宏定义 此时是高电平 按下
#define KEY2 (!(GPIOE->IDR & (1 << 2))) //低电平 按下
#define KEY3 (!(GPIOE->IDR & (1 << 3))) //低电平 按下
#define KEY4 (!(GPIOE->IDR & (1 << 4))) //低电平 按下

#endif

led.c部分

#include "led.h"

void LED_Init(void)
	
{
	//使能GPIO时钟
	RCC->AHB1ENR |= 1 << 2;  //GPIO时钟使能
	
	//设置PC4工作模式
	GPIOC->MODER &= ~(3 << (2 * 4));
	GPIOC->MODER |= 1 << (2 * 4); //设为输出模式
	
	//设置输出类型
	GPIOC->OTYPER &= ~(1 << 5);  //设置为推挽输出
	
	//设置输出速度
	GPIOC->OSPEEDR &= ~(3 << (2 * 4));
	GPIOC->OSPEEDR |= 2 << (2 * 4);  //设置为50Hz
	
	//设置上下拉
	GPIOC->PUPDR &= ~(3 << (2 * 4));  //无上下拉

	//设置GPIO初始状态
	GPIOC->ODR |= 1 << 4;  //初始状态为高电平
	
	
	//设置P5工作模式
  GPIOC->MODER &= ~(3 << (2 * 5));
	GPIOC->MODER |= 1 << (2 * 5); //设为输出模式
	
	//设置输出类型
	GPIOC->OTYPER &= ~(1 << 6);  //设置为推挽输出
	
	//设置输出速度
	GPIOC->OSPEEDR &= ~(3 << (2 * 5));
	GPIOC->OSPEEDR |= 2 << (2 * 5);  //设置为50Hz
	
	//设置上下拉
	GPIOC->PUPDR &= ~(3 << (2 * 5));  //无上下拉

	//设置GPIO初始状态
	GPIOC->ODR |= 1 << 5;  //初始状态为高电平	
	
	
	//设置P6工作模式
  GPIOC->MODER &= ~(3 << (2 * 6));
	GPIOC->MODER |= 1 << (2 * 6); //设为输出模式
	
	//设置输出类型
	GPIOC->OTYPER &= ~(1 << 7);  //设置为推挽输出
	
	//设置输出速度
	GPIOC->OSPEEDR &= ~(3 << (2 * 6));
	GPIOC->OSPEEDR |= 2 << (2 * 6);  //设置为50Hz
	
	//设置上下拉
	GPIOC->PUPDR &= ~(3 << (2 * 6));  //无上下拉

	//设置GPIO初始状态
	GPIOC->ODR |= 1 << 6;  //初始状态为高电平
	
	
	//设置P7工作模式
  GPIOC->MODER &= ~(3 << (2 * 7));
	GPIOC->MODER |= 1 << (2 * 7); //设为输出模式
	
	//设置输出类型
	GPIOC->OTYPER &= ~(1 << 8);  //设置为推挽输出
	
	//设置输出速度
	GPIOC->OSPEEDR &= ~(3 << (2 * 7));
	GPIOC->OSPEEDR |= 2 << (2 * 7);  //设置为50Hz
	
	//设置上下拉
	GPIOC->PUPDR &= ~(3 << (2 * 7));  //无上下拉

	//设置GPIO初始状态
	GPIOC->ODR |= 1 << 7;  //初始状态为高电平	
	
	
	
}


led.h部分

#ifndef _LED_H
#define _LED_H

//防止名称冲突
#include<stm32f4xx.h>
void LED_Init(void); //函数声明

#endif

  • 5
    点赞
  • 75
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值