一、任务要求
任务一:用STM32F103开发板点亮LED0、LED1两个led灯,同时亮 同时灭
任务二:用按键控制两个led
按键灯需求:
按键1控制 LED0亮
按键2 控制 LED1 亮
按键3 控制 LED0 和 LED1 翻转
WK_UP 关闭 LED0 和 LED1
二、任务一
硬件电路
其中 PWR 是系统电源指示灯,为蓝色。LED0(DS0)和 LED1(DS1)分别接在PB5和PE5上。
为了方便大家判断,我们选择了 DS0 为红色的 LED,DS1 为绿色的 LED。
代码
led.h
#ifndef _LED_H
#define _LED_H
#include "./SYSTEM/sys/sys.h"
//宏定义
//开启GPIOB时钟
#define LED0_CLK_ENABLE do{__HAL_RCC_GPIOB_CLK_ENABLE();}while(0)
//开启GPIOE时钟
#define LED1_CLK_ENABLE do{__HAL_RCC_GPIOE_CLK_ENABLE();}while(0)
//设置PB5引脚电平
#define LED0(x) do{x ?\
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,(GPIO_PinState)1):\
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,(GPIO_PinState)0);}\
while(0)
//设置PE5引脚电平
#define LED1(x) do{x ?\
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,(GPIO_PinState)1):\
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,(GPIO_PinState)0);}\
while(0)
//翻转电平
#define LED0_OVER HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5)
#define LED1_OVER HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_5)
//函数声明
void Led_Init(void);
#endif
led.c
#include "./BSP/LED/led.h"
#include "./BSP/KEY/key.h"
/***************************************
*函数名 :led_init
*函数功能 :led引脚初始化
*函数参数 :void
*函数返回值:void
*函数描述 :
* LED0 ------ PB5
* LED1 ------ PE5
*****************************************/
void Led_Init(void)
{
//开启对应时钟
LED0_CLK_ENABLE;
LED1_CLK_ENABLE;
//引脚配置
GPIO_InitTypeDef GPIO_Init = {0}; //赋初始值
GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP; //选择推挽输出模式
GPIO_Init.Pin = GPIO_PIN_5; //选择pin5引脚
GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW; //选择低速
HAL_GPIO_Init(GPIOB, &GPIO_Init);
GPIO_Init.Pin = GPIO_PIN_5;
HAL_GPIO_Init(GPIOE, &GPIO_Init);
//上电默认关灯
LED0(1);
LED1(1);
}
main.c
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/delay/delay.h"
#include "./SYSTEM/usart/usart.h"
#include "./BSP/LED/led.h"
#include "./BSP/KEY/key.h"
int main(void)
{
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟,72M */
delay_init(72); /* 初始化延时函数 */
Led_Init();
while(1)
{
LED0_OVER;
LED1_OVER;
delay_ms(500);
}
}
三、任务二
硬件电路
KEY0 和 KEY1 用作普通按键输入,分别连接在 PE4 和 PE3 上,这里并没有使用外部上拉
电阻,但是 STM32 的 IO 作为输入的时候,可以设置上下拉电阻,所以我们使用 STM32 的内
部上拉电阻来为按键提供上拉。按键按下为低电平。
KEY_UP 按键连接到 PA0(STM32 的 WKUP 引脚),它除了可以用作普通输入按键外,还可
以用作 STM32 的唤醒输入。这里需要设置为下拉电阻。注意:这个按键是高电平触发的。
机械按键有机械抖动,需要消除抖动(延时消抖)。
代码
key.h
#ifndef _KEY_H
#define _KEY_H
#include "./SYSTEM/sys/sys.h"
//宏定义
//开启GPIOE时钟
#define KEY_CLK_ENABLE do{__HAL_RCC_GPIOE_CLK_ENABLE();}while(0)
//开启GPIOA时钟
#define WKUP_CLK_ENABLE do{__HAL_RCC_GPIOA_CLK_ENABLE();}while(0)
//读取按键引脚电平
#define KEY0 HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_4)
#define KEY1 HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_3)
#define KEY2 HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_2)
#define WKUP HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)
//函数声明
void Key_Init(void);
uint8_t Key_Scan(void);
#endif
key.c
#include "./BSP/KEY/key.h"
#include "./SYSTEM/delay/delay.h"
/***************************************
*函数名 :Key_Init
*函数功能 :按键引脚初始化
*函数参数 :void
*函数返回值:void
*函数描述 : 按下低电平
* KEY0 ------ PE4
* KEY1 ------ PE3
* KEY2 ------ PE2
* WKUP ------ PA0
*****************************************/
void Key_Init(void)
{
//打开时钟
KEY_CLK_ENABLE;
WKUP_CLK_ENABLE;
//引脚配置
GPIO_InitTypeDef GPIO_Init = {0};
GPIO_Init.Mode = GPIO_MODE_INPUT; //选择输入模式
GPIO_Init.Pin = GPIO_PIN_4 | GPIO_PIN_3 | GPIO_PIN_2;
GPIO_Init.Pull = GPIO_PULLUP; //选择上拉电阻
GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW; //选择低速
HAL_GPIO_Init(GPIOE, &GPIO_Init);
GPIO_Init.Pin = GPIO_PIN_0;
GPIO_Init.Pull = GPIO_PULLDOWN; //选择下拉电阻
HAL_GPIO_Init(GPIOA, &GPIO_Init);
}
/***************************************
*函数名 :Key_Scan
*函数功能 :按键扫描
*函数参数 :void
*函数返回值:uint8_t
*函数描述 : 按下低电平
*****************************************/
uint8_t Key_Scan(void)
{
static uint8_t key_flag = 1; //按键标志位
uint8_t key_value = 0xff; //赋按键初始值
if((!KEY0 || !KEY1 || !KEY2 || WKUP) && key_flag)
{
delay_ms(10); //按键消抖
key_flag = 0; //锁死标志位,防止连续进入判断
if(!KEY0) key_value = 1; //如果按键0按下,赋按键值为1
else if(!KEY1) key_value = 2; //如果按键1按下,赋按键值为2
else if(!KEY2) key_value = 3; //如果按键2按下,赋按键值为3
else if(WKUP) key_value = 4; //如果按键WKUP按下,赋按键值为4
}
else if(KEY0 && KEY1 && KEY2 && !WKUP)
{
key_flag = 1; //如果按键全部松开,解锁标志位
}
return key_value; //返回按键值
}
led.c
#include "./BSP/LED/led.h"
#include "./BSP/KEY/key.h"
/***************************************
*函数名 :led_init
*函数功能 :led引脚初始化
*函数参数 :void
*函数返回值:void
*函数描述 :
* LED0 ------ PB5
* LED1 ------ PE5
*****************************************/
void Led_Init(void)
{
//开启对应时钟
LED0_CLK_ENABLE;
LED1_CLK_ENABLE;
//引脚配置
GPIO_InitTypeDef GPIO_Init = {0}; //赋初始值
GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP; //选择推挽输出模式
GPIO_Init.Pin = GPIO_PIN_5; //选择pin5引脚
GPIO_Init.Speed = GPIO_SPEED_FREQ_LOW; //选择低速
HAL_GPIO_Init(GPIOB, &GPIO_Init);
GPIO_Init.Pin = GPIO_PIN_5;
HAL_GPIO_Init(GPIOE, &GPIO_Init);
//上电默认关灯
LED0(1);
LED1(1);
}
void led_program(void)
{
uint8_t key;
key = Key_Scan(); //获取按键值
switch(key)
{
case 0: LED0(0);
break;
case 1: LED0_OVER;
LED1_OVER;
break;
case 2: LED1(0);
break;
case 3: LED0(1);
LED1(1);
break;
default:break;
}
}
led.h
#ifndef _LED_H
#define _LED_H
#include "./SYSTEM/sys/sys.h"
//宏定义
//开启GPIOB时钟
#define LED0_CLK_ENABLE do{__HAL_RCC_GPIOB_CLK_ENABLE();}while(0)
//开启GPIOE时钟
#define LED1_CLK_ENABLE do{__HAL_RCC_GPIOE_CLK_ENABLE();}while(0)
//设置PB5引脚电平
#define LED0(x) do{x ?\
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,(GPIO_PinState)1):\
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,(GPIO_PinState)0);}\
while(0)
//设置PE5引脚电平
#define LED1(x) do{x ?\
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,(GPIO_PinState)1):\
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,(GPIO_PinState)0);}\
while(0)
//翻转电平
#define LED0_OVER HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5)
#define LED1_OVER HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_5)
//函数声明
void Led_Init(void);
void led_program(void);
#endif
main.c
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/delay/delay.h"
#include "./SYSTEM/usart/usart.h"
#include "./BSP/LED/led.h"
#include "./BSP/KEY/key.h"
int main(void)
{
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟,72M */
delay_init(72); /* 初始化延时函数 */
Led_Init();
Key_Init();
while(1)
{
led_program();
}
}
开源地址: