STM32驱动按键和LED灯实时显示二进制值

基于STM32F407ZE开发板的驱动按键和LED灯实时显示二进制值应用实例:
要求:
①按键S1按下变量+1
②按键S2按下变量-1
③按键S3按下变量清零
④LED实时显示这个变量的二进制值(变量的范围:0~15)
⑤工程管理(函数封装)

文件结构:
在这里插入图片描述

main.c部分:

#include <stm32f4xx.h>
#include "sys.h"
#include "LED/led.h"
#include "KEY/key.h"
#include "delay/delay.h"

int main()
{
    
    	
	LED_Init();								//LED灯初始化
	KEY_Init();								//KEY按键初始化
	int num = 0;							//计数初始化
	int key = 1;							//按键标志位
	
	while(1)
	{
    
    
		if(PAin(0) == 0 && key == 1)		//Key1被按下,且标志位为1
		{
    
    
			KEY_tone();						//按键提示音
			delay_ms(100);
			
			if(PAin(0) == 0)
			{
    
    
				key = 0;					//标志位置0
				num ++;						//计数+1
			}
		}
		
		if(PEin(2) == 0 && key == 1)		//Key2被按下,且标志位为1
		{
    
    
			KEY_tone();						//按键提示音
			delay_ms(100);
			if(PEin(2) == 0)
			{
    
    
				key = 0;					//标志位置0
				num --;						//计数-1
			}
		}
		
		if(PEin(3) == 0 && key == 1)		//Key3被按下,且标志位为1
		{
    
    
			KEY_tone();						//按键提示音
			key = 0;						//标志位置0
			num = 0;						//计数清零
		}
		
		if(PAin(0) == 1 || PEin(2) == 1 || PEin(3) == 1)	//Key1、Key2、Key3被松开
			key = 1;						//标志位置1
		
		sum(num);							//二进制实时显示计数大小
	}
}

sys.h部分:

#ifndef __SYS_H
#define __SYS_H	 
#include "stm32f4xx.h" 

//IO口操作宏定义
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) 
#define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr)) 
#define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum)) 
//IO口地址映射
#define GPIOA_ODR_Addr    (GPIOA_BASE+20) //0x40020014
#define GPIOB_ODR_Addr    (GPIOB_BASE+20) //0x40020414 
#define GPIOC_ODR_Addr    (GPIOC_BASE+20) //0x40020814 
#define GPIOD_ODR_Addr    (GPIOD_BASE+20) //0x40020C14 
#define GPIOE_ODR_Addr    (GPIOE_BASE+20) //0x40021014 
#define GPIOF_ODR_Addr    (GPIOF_BASE+20) //0x40021414    
#define GPIOG_ODR_Addr    (GPIOG_BASE+20) //0x40021814   
#define GPIOH_ODR_Addr    (GPIOH_BASE+20) //0x40021C14    
#define GPIOI_ODR_Addr    (GPIOI_BASE+20) //0x40022014     

#define GPIOA_IDR_Addr    (GPIOA_BASE+16) //0x40020010 
#define GPIOB_IDR_Addr    (GPIOB_BASE+16) //0x40020410 
#define GPIOC_IDR_Addr    (GPIOC_BASE+16) //0x40020810 
#define GPIOD_IDR_Addr    (GPIOD_BASE+16) //0x40020C10 
#define GPIOE_IDR_Addr    (GPIOE_BASE+16) //0x40021010 
#define GPIOF_IDR_Addr    (GPIOF_BASE+16) //0x40021410 
#define GPIOG_IDR_Addr    (GPIOG_BASE+16) //0x40021810 
#define GPIOH_IDR_Addr    (GPIOH_BASE+16) //0x40021C10 
#define GPIOI_IDR_Addr    (GPIOI_BASE+16) //0x40022010 
 
//IO口操作,只对单一的IO口!
//确保n的值小于16!
#define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //输出 
#define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  //输入 

#define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //输出 
#define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)  //输入 

#define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)  //输出 
#define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)  //输入 

#define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)  //输出 
#define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)  //输入 

#define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)  //输出 
#define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)  //输入

#define PFout(n)   BIT_ADDR(GPIOF_ODR_Addr,n)  //输出 
#define PFin(n)    BIT_ADDR(GPIOF_IDR_Addr,n)  //输入

#define PGout(n)   BIT_ADDR(GPIOG_ODR_Addr,n)  //输出 
#define PGin(n)    BIT_ADDR(GPIOG_IDR_Addr,n)  //输入

#define PHout(n)   BIT_ADDR(GPIOH_ODR_Addr,n)  //输出 
#define PHin(n)    BIT_ADDR(GPIOH_IDR_Addr,n)  //输入

#define PIout(n)   BIT_ADDR(GPIOI_ODR_Addr,n)  //输出 
#define PIin(n)    BIT_ADDR(GPIOI_IDR_Addr,n)  //输入


#endif

led.h部分:

#ifndef LED_H
#define LED_H

#include <stm32f4xx.h>
#include "../sys.h"

void LED_Init();
void sum(int n);

#endif

led.c部分:

#include "led.h"

void LED_Init()
{
    
    
	GPIO_InitTypeDef led1,led2;
	//先开启对应用到的模块时钟节拍
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE);
	
	//初始化LED1、LED2、蜂鸣器
	led1.GPIO_Pin 	= GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_8;
	led1.GPIO_Mode 	= GPIO_Mode_OUT;
	led1.GPIO_Speed = GPIO_Fast_Speed;
	led1.GPIO_OType = GPIO_OType_PP;
	led1.GPIO_PuPd  = GPIO_PuPd_UP;
	GPIO_Init(GPIOF,&led1);
	
	//初始化LED3、LED4
	led2.GPIO_Pin 	= GPIO_Pin_13 | GPIO_Pin_14;
	led2.GPIO_Mode 	= GPIO_Mode_OUT;
	led2.GPIO_Speed = GPIO_Fast_Speed;
	led2.GPIO_OType = GPIO_OType_PP;
	led2.GPIO_PuPd  = GPIO_PuPd_UP;
	GPIO_Init(GPIOE,&led2);
	
	//所有LED灯置高电平(熄灯)
	PFout(9) 	= 1;
	PFout(10) 	= 1;
	PEout(13) 	= 1;
	PEout(14) 	= 1;
}

void sum(int n)
{
    
    
	PFout(9) 	= !(n & 0x01);
	PFout(10) 	= !(n & 0x02);
	PEout(13) 	= !(n & 0x04);
	PEout(14) 	= !(n & 0x08);
}

key.h部分:

#ifndef KEY_H
#define KEY_H

#include <stm32f4xx.h>
#include "../sys.h"
#include "../delay/delay.h"

void KEY_Init();
void KEY_tone();

#endif

key.c部分:

#include "key.h"

void KEY_Init()
{
    
    
	GPIO_InitTypeDef KEY1,KEY2;
	//先开启对应用到的模块时钟节拍
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE);
	
	//初始化KEY1
	KEY1.GPIO_Pin 	= GPIO_Pin_0 ;
	KEY1.GPIO_Mode 	= GPIO_Mode_IN;
	KEY1.GPIO_Speed 	= GPIO_Fast_Speed;
	KEY1.GPIO_OType 	= GPIO_OType_PP;
	KEY1.GPIO_PuPd  	= GPIO_PuPd_UP;
	GPIO_Init(GPIOA,&KEY1);
	
	//初始化KEY2、KEY3、KEY4
	KEY2.GPIO_Pin 	= GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4;
	KEY2.GPIO_Mode 	= GPIO_Mode_IN;
	KEY2.GPIO_Speed = GPIO_Fast_Speed;
	KEY2.GPIO_OType = GPIO_OType_PP;
	KEY2.GPIO_PuPd  = GPIO_PuPd_UP;
	GPIO_Init(GPIOE,&KEY2);
}

//按键提示音
void KEY_tone()				
{
    
    
	PFout(8) = 1;
	delay_ms(3);
	PFout(8) = 0;
}

delay.h部分:

#ifndef DELAY_H
#define DELAY_H

#include <stm32f4xx.h>
#include "../sys.h"

void delay_ms(int ms);

#endif

delay.c部分:

#include "delay.h"

void delay_ms(int ms)					//延时函数
{
    
    
	int i,j;
	for(i=0; i<ms; i++)
		for(j=0; j<10000;j++);
}

猜你喜欢

转载自blog.csdn.net/weixin_43793181/article/details/109035205