基于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++);
}