专注电子技术学习与研究
当前位置:单片机教程网 >> STM32 >> 浏览文章

STM32库开发之按键控制LED灯

作者:寒竹子   来源:用户上传   点击数:  更新时间:2014年05月18日   【字体:

 /*****************主要的用户自己编写的文件*********************/

/**
  ***********************************************************************
  * @file     : main.c
  * @author   : xr
  * @date     : 2014年5月14日08:23:25
  * @version  : V1.0
  * @brief    : 采用轮询方式检测按键 STM32F103VE T6 MCU
  ***********************************************************************
  * @attention 
  * 实验平台  : 野火ISO-MINI-STM32开发板
  * 实验现象  : 按下按键K2,实现LED1小灯的亮灭反转 
  *             按下按键K3,实现LED2小灯的亮灭反转
  ***********************************************************************
  */
#include "stm32f10x.h" /* 上帝之手 STM32库头文件 */
#include "led.h"
#include "key.h"
 
 
/**
  * @brief    : 主函数
  * @param    : 无
  * @retval   : 无
  */
int main(void)
{
    ConfigLed();      /* 初始化LED控制端口 */  
    ConfigKey();      /* 初始化按键控制端口 */
    
    LED1( ON );       /* 开始时点亮LED1 */
    LED2( ON );       /* 开始时点亮LED2 */
    
    while (1)
    {
        /* add your codes ^_^ */
        /* 检测按键K2是否按下 */
        if ( KeyScan( GPIOA, GPIO_Pin_0 ) == KEY_ON )
        {
            /* LED1反转 读取GPIOB 0端口位的值并用1减去之后再写入此位即LED1的控制位 */
            GPIO_WriteBit( GPIOB,  GPIO_Pin_0,  (BitAction)(1 -  GPIO_ReadOutputDataBit( GPIOB, GPIO_Pin_0 )));
        }
        /* 检测按键K3是否按下 */
        if ( KeyScan( GPIOC, GPIO_Pin_13 ) == KEY_ON )
        {
            /* LED2反转 */
            GPIO_WriteBit( GPIOC, GPIO_Pin_4, (BitAction)(1 - GPIO_ReadOutputDataBit( GPIOC, GPIO_Pin_4 )));
        }
    }
}
 
/**********************************************END OF FILE******************/
 
/**
  ***************************************************************
  * @file    led.h
  * @author  xr
  * @date    2014年5月17日13:00:58
  * @brief   LED小灯驱动头文件
  ***************************************************************
  * @attention
  * 实验平台        : 野火ISO-MINI开发板
  * LED小灯硬件连接 : -------------------
  *                   | LED1 ---- PB0   |
  *                   | LED2 ---- PC4   |
  *                   | LED3 ---- PC3   | 
  *                   -------------------  
  ***************************************************************
  */
#ifndef _LED_H_
#define _LED_H_
 
#include "stm32f10x.h" /* 使用stm32库 */
 
/* 控制小灯: 1 灭 0 亮 */
#define ON 0
#define OFF 1
 
/* 带参宏 */
#define LED1(a) if (a) \
                    GPIO_SetBits( GPIOB, GPIO_Pin_0 ); \
                 else \
                    GPIO_ResetBits( GPIOB, GPIO_Pin_0 )
#define LED2(a) if (a) \
                    GPIO_SetBits( GPIOC, GPIO_Pin_4 ); \
                else \
                    GPIO_ResetBits( GPIOC, GPIO_Pin_4 )
#define LED3(a) if (a) \
                   GPIO_SetBits( GPIOC, GPIO_Pin_3 ); \
                else \
                   GPIO_ResetBits( GPIOC, GPIO_Pin_3 )
 
void ConfigLed(void);
 
#endif /* _LED_H_ */
/*******************************************************END OF FILE*****/
/**
  ***************************************************************
  * @file    led.c
  * @author  xr
  * @date    2014年5月17日13:00:58
  * @brief   LED小灯驱动
  ***************************************************************
  * @attention
  * 实验平台        : 野火ISO-MINI开发板
  * LED小灯硬件连接 : -------------------
  *                   | LED1 ---- PB0   |
  *                   | LED2 ---- PC4   |
  *                   | LED3 ---- PC3   | 
  *                   -------------------  
  ***************************************************************
  */
#include "led.h"
 
/**
  * @brief  :  配置LED小灯的GPIO端口
  * @param  :  无
  * @retval :  无
  */
void ConfigLed(void)
{
    GPIO_InitTypeDef GPIO_InitStruct; /* 定义GPIO_InitTyPeDef结构体变量 */
    
    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE ); /* 开启APB2总线上的GPIOB和GPIOC时钟 */
    
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
    
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; /* 设置引脚为通用强推挽输出 */
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; /* 设置输出为50MHZ */
    
    /* 调用库函数初始化GPIOB端口 */
    GPIO_Init  ( GPIOB, &GPIO_InitStruct );
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_3; /* 选择3,4引脚 */
    /* 调用库函数初始化GPIOC的34引脚 */
    GPIO_Init  (GPIOC, &GPIO_InitStruct );
    
    /* 关闭LED */
    GPIO_SetBits  ( GPIOB,  GPIO_Pin_0 );
    GPIO_SetBits  ( GPIOC,  GPIO_Pin_4 | GPIO_Pin_3 );
}
/*************************************************END OF FILE***********/
/**
  ***************************************************************
  * @file    key.h
  * @author  xr
  * @date    2014年5月17日13:00:58
  * @brief   按键驱动头文件
  ***************************************************************
  * @attention
  * 实验平台        : 野火ISO-MINI开发板
  * 按键硬件连接    : ------------------
  *                   | K2 ----  PA0   |
  *                   | K3 ----  PC13  | 
  *                   ------------------  
  ***************************************************************
  */
#ifndef _KEY_H_
#define _KEY_H_
 
#include "stm32f10x.h"
 
#define KEY_ON  0
#define KEY_OFF 1
 
void ConfigKey( void );
uint8_t KeyScan( GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin_x );
 
#endif /* _KEY_H_ */
/**********************************************END OF FILE*******/
/**
  ***************************************************************
  * @file    key.c
  * @author  xr
  * @date    2014年5月17日13:00:58
  * @brief   按键驱动
  ***************************************************************
  * @attention
  * 实验平台        : 野火ISO-MINI开发板
  * 按键硬件连接    : ------------------
  *                   | K2 ----  PA0   |
  *                   | K3 ----  PC13  | 
  *                   ------------------  
  ***************************************************************
  */
#include "key.h"
 
/**
  * @brief   :  不精确延时
  * @param   :  nCounter
  * @retval  :  无
  */
static void KeyDelay( uint32_t nCounter )
{
    while ( nCounter-- );
}
 
/**
  * @brief   : 配置按键用到的I/O口
  * @param   : 无
  * @retval  : 无
  */
void ConfigKey( void )
{
    GPIO_InitTypeDef GPIO_InitStructure; /* 定义初始化端口的结构体变量 */
    /* 开启按键2的时钟 */
    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE );
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    //输入模式不需要配置端口的输出速率GPIO_Speed
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  /* 配置按键的引脚为上拉 */
    
    /* 调用库函数初始化key引脚 */
    GPIO_Init( GPIOA, &GPIO_InitStructure );
}
 
/**
  * @brief  : 按键按下检测
  * @param  : 端口 : GPIOx  端口位 : GPIO_Pin_x
  * @retval : 按键的状态 : 按下 弹起
  */
uint8_t KeyScan( GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin_x )
{
    /* 检测是否有按键按下 */
    if ( GPIO_ReadInputDataBit( GPIOx, GPIO_Pin_x ) == KEY_ON )
    {
        KeyDelay(0x57E40);  /* 延时消抖 延时大约5ms */
        if ( GPIO_ReadInputDataBit( GPIOx, GPIO_Pin_x ) == KEY_ON )
        {
            while ( GPIO_ReadInputDataBit( GPIOx, GPIO_Pin_x ) == KEY_ON ); /* 等待按键释放 */
            return KEY_ON;
        }
        else
        {
            return KEY_OFF;
        }
    }
    return KEY_OFF;
}
 
/**************************************************END OF FILE*******/
关闭窗口