在这做个代码总结
main函数代码如下:
/********************************************************
实验名称: 按键检测实验
硬件模块: STM32F407核心板V2.0
硬件接线:
实验现象: 按下按键 KEY_UP 则 DS0 和 DS1 状态改变
按下按键 KEY0 则 DS2 和 DS3 状态改变
按下按键 KEY1 则 DS4 和 DS5 状态改变
按下按键 KEY2 则 DS6 和 DS7 状态改变
更新时间:2018-11-26
********************************************************/
#include "stm32f4xx.h"
#include "delay.h"
#include "led.h"
#include "key.h"
int main(void)
{
uint8_t key = 0; //获取按键状态的变量
Delay_Init(); //延时初始化
LED_Hardware_Init(); //LED初始化配置函数
Key_Hardware_Init(); //按键初始化配置函数
while(1)
{
key = Key_Scan(0); //按键扫描
switch(key)
{
case 1: //满足条件key==1
LED0_TOGGLE(); //翻转LED0和LED1
LED1_TOGGLE();
Delay_ms(500); //延时
break;
case 2: //满足条件key==2
LED2_TOGGLE(); //翻转LED2和LED3
LED3_TOGGLE();
Delay_ms(500); //延时
break;
case 3: //满足条件key==3
LED4_TOGGLE(); //翻转LED4和LED5
LED5_TOGGLE();
Delay_ms(500); //延时
break;
case 4: //满足条件key==4
LED6_TOGGLE(); //翻转LED6和LED7
LED7_TOGGLE();
Delay_ms(500); //延时
break;
default: //默认结果/其他结果
break;
}
}
}
delay延时函数代码如下:
#include "stm32f4xx.h"
#include "delay.h"
static uint32_t fam_nus = 0;
static uint32_t fam_nms = 0;
/**********************************************************
功 能: 延时初始化
参 数: 无
返回值: 无
**********************************************************/
void Delay_Init(void)
{
//关闭计时、不触发中断、计数时钟为AHB/8
SysTick->CTRL = 0x0;
//微秒级初值
fam_nus = SystemCoreClock/8000000;
//毫秒级初值
fam_nms = fam_nus * 1000;
//计数器清零
SysTick->VAL = 0;
}
/**********************************************************
功 能: 毫秒级延时
参 数: ctr 微秒倍数、例如 ctr = 1 则 延时1ms
最大延时Delay_ms(798);
返回值: 无
**********************************************************/
void Delay_ms(uint16_t ctr)
{
uint32_t tick_flag = 0;
SysTick->LOAD = ctr * fam_nms;
SysTick->VAL = 0;
SysTick->CTRL = 0x01;
do
{
tick_flag = SysTick->CTRL;
}
while(!(tick_flag & (1<<16)) && (tick_flag & 0x01));
SysTick->CTRL = 0x00;
}
/**********************************************************
功 能: 微秒级延时
参 数: ctr 微秒倍数、例如 ctr = 1 则 延时1us
返回值: 无
**********************************************************/
void Delay_us(uint16_t ctr)
{
uint32_t tick_flag = 0;
//定时器初值
SysTick->LOAD = ctr*fam_nus;
//计数器清零
SysTick->VAL = 0;
//开启定时器
SysTick->CTRL |= 0x01;
do
{
//获取定时器状态
tick_flag = SysTick->CTRL;
}
//状态判断
while(!(tick_flag&(1<<16)) && (tick_flag&0x01));
//关闭计时
SysTick->CTRL = 0x00;
}
key函数代码如下:
#include "stm32f4xx.h"
#include "key.h"
#include "delay.h"
/**********************************************************
功 能:按键初始化配置函数
参 数: KEY_UP GPIOA0
KEY0 GPIOE4
KEY1 GPIOE3
KEY2 GPIOE2
返回值:无
**********************************************************/
void Key_Hardware_Init(void)
{
GPIO_InitTypeDef GPIO_TypeDefStructure;
//开启时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOE,ENABLE);
//选择端口
GPIO_TypeDefStructure.GPIO_Pin =(GPIO_Pin_10);
//输入模式
GPIO_TypeDefStructure.GPIO_Mode = (GPIO_Mode_AIN);
//内部下拉
GPIO_TypeDefStructure.GPIO_PuPd = (GPIO_PuPd_UP);
//初始化配置
GPIO_Init(GPIOA,&GPIO_TypeDefStructure);
//选择端口
GPIO_TypeDefStructure.GPIO_Pin =(GPIO_Pin_10) ;
//输入模式
GPIO_TypeDefStructure.GPIO_Mode =(GPIO_Mode_AIN) ;
//内部上拉
GPIO_TypeDefStructure.GPIO_PuPd =(GPIO_PuPd_UP) ;
//初始化配置
GPIO_Init(GPIOE,&GPIO_TypeDefStructure);
}
/**********************************************************
功 能: 按键扫描函数,每次只能按一个按键
参 数: Mode 0:按下返回键值 (支持长按检测)
1:按下后松开才返回键值
返回值: 返回按键值
KEY_UP 1
KEY0 2
KEY1 3
KEY2 4
**********************************************************/
uint8_t Key_Scan(uint8_t Mode)
{
uint8_t key_value = 0 , key = 0 ;
//同时读取四个键值
key_value = (key) ;
//判断是否有按键按下
if( key_value )
{
//延时消抖
Delay_ms(10);
//再次读取键值
key_value = (key) ;
//判断是否有按键按下
if( key_value )
{
//判断是哪一个按键按下
switch( key_value )
{
//按键KEY_UP按下
case 1<<3 : key = 1;
break;
//按键KEY0按下
case 1<<2 : key = 2;
break;
//按键KEY1按下
case 1<<1 : key = 3;
break;
//按键KEY2按下
case 1 : key = 4;
break;
//其他情况:比如按下多个键,不做反应
default: break;
}
//如果模式为1时,松开按键才会返回值
if(Mode)
{
//先读取再判断do{}while();
do
{
key_value = READ_KEY_UP()<<3 | READ_KEY0()<<2 | READ_KEY1()<<1 | READ_KEY2() ;
}
while( key_value ); //等待按键释放
}
}
}
return key;
}
led.c代码如下:
#include "stm32f4xx.h"
#include "delay.h"
#include "led.h"
/**********************************************************
功 能:LED初始化配置函数
参 数:无
返回值:无
**********************************************************/
void LED_Hardware_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//开启时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOF,ENABLE);
//选择端口
GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_10);
//输出模式
GPIO_InitStructure.GPIO_Mode = (GPIO_Mode_AIN);
//推挽输出
GPIO_InitStructure.GPIO_OType = (GPIO_OType_PP);
//输出速度
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
//初始化配置
GPIO_Init(GPIOF,&GPIO_InitStructure);
//选择端口
GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_10);
//初始化配置
GPIO_Init(GPIOC,&GPIO_InitStructure);
//初始化引脚后熄灭LED
GPIO_SetBits(GPIOF, GPIO_Pin_9 | GPIO_Pin_10);
GPIO_SetBits(GPIOC, GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2
| GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5);
}
/****************************************************************
功 能:流水灯测试函数
参 数:无
返回值:无
*****************************************************************/
void LED_Test(void)
{
LED0(1); //点亮LED0
Delay_ms(200); //延时等待
LED0(0); //熄灭LED0
LED1(1); //点亮LED1
Delay_ms(200); //延时等待
LED1(0); //熄灭LED1
LED2(1); //点亮LED2
Delay_ms(200); //延时等待
LED2(0); //熄灭LED2
LED3(1); //点亮LED3
Delay_ms(200); //延时等待
LED3(0); //熄灭LED3
LED4(1); //点亮LED4
Delay_ms(200); //延时等待
LED4(0); //熄灭LED4
LED5(1); //点亮LED5
Delay_ms(200); //延时等待
LED5(0); //熄灭LED5
LED6(1); //点亮LED6
Delay_ms(200); //延时等待
LED6(0); //熄灭LED6
LED7(1); //点亮LED7
Delay_ms(200); //延时等待
LED7(0); //熄灭LED7
}