【HAL库每天一例】第002例:GPIO-流水灯

【HAL库每天一例】系列例程从今天开始持续更新。。。。。
我们将坚持每天至少发布一个基于YS-F1Pro开发板的HAL库例程,
该系列例程将带领大家从零开始使用HAL库,后面会持续添加模块应用例程。
同样的,我们还程序发布基于HAL库的指导文档和视频教程,欢迎持续关注,并提出改进意见。

例程下载:
资料包括程序、相关说明资料以及软件使用截图
链接:http://pan.baidu.com/s/1i574oPv
密码:r3s3
(硬石YS-F1Pro开发板HAL库例程持续更新\1. 软件设计之基本裸机例程(HAL库版本)\YSF1_HAL-002. GPIO-流水灯)

/**
  ******************************************************************************
  *                           硬石YS-F1Pro开发板例程功能说明
  *
  *  例程名称: YSF1_HAL-002. 流水灯
  *   
  ******************************************************************************
  * 说明:
  * 本例程配套硬石stm32开发板YS-F1Pro使用。
  *
  * 淘宝:
  * 论坛:ing10bbs
  * 版权归硬石嵌入式开发团队所有,请勿商用。
  ******************************************************************************
  */

【1】例程简介
  使用stm32 HAL库函数实现LED流水灯效果。通过这个例程熟悉stm32 HAL库函数编程思想。

  stm32拥有非常多的IO引脚,这些IO引脚可以用作最简单的控制电平控制,可以设置为输出高电
平(数字量:1,对应3.3V)或者低电平(数字量:0,对应0V),也可以设置为输入模式,读取这个IO引
脚的电平(比如用于按键状态读取)。  本例程我们调用HAL库函数方法来实现对IO引脚的输出高低
电平进行控制。
   
  通过开发板原理图我们可以知道:
   
  LED1灯负极接在GND(0V)上,正极通过一个电阻接在stm32f103zet6芯片的PB0引脚上(中间还
有一个JP3默认使用跳线帽短路),如果我们控制PB0引脚为高电平(3.3V)的话,此时电路存在电压
差,电流从LED1灯正极流向负极再经电阻流入GND,此时LED1灯是亮的;另外,如果我们控制PB0
引脚为低电平(0V)的话,此时电路没有电流,所以LED1灯是灭的。如此看来,只要我们控制PB0引
脚的高或者低电平就可以自由控制LED1灯的亮灭。
  
  LED2和LED3控制原理与LED1是相同的。
  
  在使用IO引脚之前我们需要对IO引脚相关资源进行初始化配置,首先我们需要调用使能GPIOB
端口时钟函数LED1_RCC_CLK_ENABLE函数(实际是__HAL_RCC_GPIOB_CLK_ENABLE函数)。开启时钟
之后,我们就先通过HAL_GPIO_WritePin(LED1_GPIO, LED1_GPIO_PIN, GPIO_PIN_SET)函数设置
PB0初始化为高电平。然后设置可以来配置IO引脚的功能,这里我们需要把PB0引脚配置为推挽
输出模式,调用HAL_GPIO_Init(LED1_GPIO, &GPIO_InitStruct)函数实现初始化配置。
  在初始化PB0之后,就可以使用HAL_GPIO_WritePin函数非常方便控制输出的高电平或者低电平。
   
  
【2】跳线帽情况
******* 为保证例程正常运行,必须插入以下跳线帽 **********
丝印编号     IO端口      目标功能引脚        出厂默认设置
  JP3        PB0           LED1               已接入
  JP4        PG6           LED2               已接入
  JP5        PG7           LED3               已接入
  
【3】操作及现象
  使用开发板配套的MINI USB线连接到开发板标示“调试串口”字样的MIMI USB接口为开发板供电。
下载完程序之后,可以观察到开发板上三颗LED以不同形式先后亮灭。

/******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/

bsp_led.h文件内容:
#ifndef __BSP_LED_H__
#define __BSP_LED_H__

/* 包含头文件 ----------------------------------------------------------------*/
#include "stm32f1xx_hal.h"

/* 类型定义 ------------------------------------------------------------------*/
typedef enum
{
LED_OFF = 0,
LED_ON = 1,
LED_TOGGLE = 2,
}LEDState_TypeDef;
#define IS_LED_STATE(STATE) (((STATE) == LED_OFF) || ((STATE) == LED_ON) || ((STATE) == LED_TOGGLE))

/* 宏定义 --------------------------------------------------------------------*/
#define LED1 (uint8_t)0x01
#define LED2 (uint8_t)0x02
#define LED3 (uint8_t)0x04
#define IS_LED_TYPEDEF(LED) (((LED) == LED1) || ((LED) == LED2) || ((LED) == LED3))

/*
* 以下宏定义内容跟开发板硬件息息相关,需要查看开发板电路原理图才能正确编写。
* 例如,查原理图可在LED1灯接在stm32f103芯片的PB0引脚上,所以有关LED1的宏定义
* 都是与GPIOB,GPIO_Pin_0相关的,我们专门把这些与开发板硬件相关的内容定义为宏,
* 这对于修改或者移植程序非常方便。
*/
#define LED1_RCC_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
#define LED1_GPIO_PIN GPIO_PIN_0
#define LED1_GPIO GPIOB


#define LED2_RCC_CLK_ENABLE() __HAL_RCC_GPIOG_CLK_ENABLE()
#define LED2_GPIO_PIN GPIO_PIN_6
#define LED2_GPIO GPIOG


#define LED3_RCC_CLK_ENABLE() __HAL_RCC_GPIOG_CLK_ENABLE()
#define LED3_GPIO_PIN GPIO_PIN_7
#define LED3_GPIO GPIOG

#define LED1_ON HAL_GPIO_WritePin(LED1_GPIO,LED1_GPIO_PIN,GPIO_PIN_SET) // 输出高电平
#define LED1_OFF HAL_GPIO_WritePin(LED1_GPIO,LED1_GPIO_PIN,GPIO_PIN_RESET) // 输出低电平
#define LED1_TOGGLE HAL_GPIO_TogglePin(LED1_GPIO,LED1_GPIO_PIN) // 输出反转

#define LED2_ON HAL_GPIO_WritePin(LED2_GPIO,LED2_GPIO_PIN,GPIO_PIN_SET) // 输出高电平
#define LED2_OFF HAL_GPIO_WritePin(LED2_GPIO,LED2_GPIO_PIN,GPIO_PIN_RESET) // 输出低电平
#define LED2_TOGGLE HAL_GPIO_TogglePin(LED2_GPIO,LED2_GPIO_PIN) // 输出反转

#define LED3_ON HAL_GPIO_WritePin(LED3_GPIO,LED3_GPIO_PIN,GPIO_PIN_SET) // 输出高电平
#define LED3_OFF HAL_GPIO_WritePin(LED3_GPIO,LED3_GPIO_PIN,GPIO_PIN_RESET) // 输出低电平
#define LED3_TOGGLE HAL_GPIO_TogglePin(LED3_GPIO,LED3_GPIO_PIN) // 输出反转


/* 扩展变量 ------------------------------------------------------------------*/
/* 函数声明 ------------------------------------------------------------------*/
void LED_GPIO_Init(void);
void LEDx_StateSet(uint8_t LEDx,LEDState_TypeDef state);

#endif // __BSP_LED_H__

/******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/

bsp_led.c文件内容:
/**
******************************************************************************
* 文件名程: bsp_led.c
* 作 者: 硬石嵌入式开发团队
* 版 本: V1.0
* 编写日期: 2015-10-04
* 功 能: 基于HAL库的板载LED灯底层驱动实现
******************************************************************************
* 说明:
* 本例程配套硬石stm32开发板YS-F1Pro使用。
*
* 淘宝:
* 论坛:ing10bbs
* 版权归硬石嵌入式开发团队所有,请勿商用。
******************************************************************************
*/
/**
* 很多初学者可能会疑惑bsp_led.c和bsp_led.h这两个文件哪里来的??是不是官方下载
* 的??实际上,这两个文件是要求我们自己创建的,内容也是我们自己敲代码的。
* 这个已经属于应用层次的代码ST官方是不提供的,需要我们根据自己的开发板硬件来
* 编写我们的程序,所以需要我们自己新建文件编写。
*/

/* 包含头文件 ----------------------------------------------------------------*/
#include "led/bsp_led.h"

/* 私有类型定义 --------------------------------------------------------------*/
/* 私有宏定义 ----------------------------------------------------------------*/
/* 私有变量 ------------------------------------------------------------------*/
/* 扩展变量 ------------------------------------------------------------------*/
/* 私有函数原形 --------------------------------------------------------------*/
/* 函数体 --------------------------------------------------------------------*/

/**
* 函数功能: 板载LED灯IO引脚初始化.
* 输入参数: 无
* 返 回 值: 无
* 说 明:使用宏定义方法代替具体引脚号,方便程序移植,只要简单修改bsp_led.h
* 文件相关宏定义就可以方便修改引脚。
*/
void LED_GPIO_Init(void)
{
/* 定义IO硬件初始化结构体变量 */
GPIO_InitTypeDef GPIO_InitStruct;

/* 使能(开启)LED引脚对应IO端口时钟 */
LED1_RCC_CLK_ENABLE();
LED2_RCC_CLK_ENABLE();
LED3_RCC_CLK_ENABLE();

/* 配置LED1引脚输出电压 */
HAL_GPIO_WritePin(LED1_GPIO, LED1_GPIO_PIN, GPIO_PIN_RESET);

/* 配置LED2引脚输出电压 */
HAL_GPIO_WritePin(LED2_GPIO, LED2_GPIO_PIN, GPIO_PIN_RESET);
/* 配置LED3引脚输出电压 */
HAL_GPIO_WritePin(LED2_GPIO, LED3_GPIO_PIN, GPIO_PIN_RESET);

/* 设定LED1对应引脚IO编号 */
GPIO_InitStruct.Pin = LED1_GPIO_PIN;
/* 设定LED1对应引脚IO为输出模式 */
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
/* 设定LED1对应引脚IO操作速度 */
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
/* 初始化LED1对应引脚IO */
HAL_GPIO_Init(LED1_GPIO, &GPIO_InitStruct);

/* 设定LED2对应引脚IO编号 */
GPIO_InitStruct.Pin = LED2_GPIO_PIN;
/* 设定LED2对应引脚IO为输出模式 */
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
/* 设定LED2对应引脚IO操作速度 */
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
/* 初始化LED2对应引脚IO */
HAL_GPIO_Init(LED2_GPIO, &GPIO_InitStruct);

/* 设定LED3对应引脚IO编号 */
GPIO_InitStruct.Pin = LED3_GPIO_PIN;
/* 设定LED3对应引脚IO为输出模式 */
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
/* 设定LED3对应引脚IO操作速度 */
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
/* 初始化LED3对应引脚IO */
HAL_GPIO_Init(LED3_GPIO, &GPIO_InitStruct);

}

/**
* 函数功能: 设置板载LED灯的状态
* 输入参数: LEDx:其中x可甚至为(1,2,3)用来选择对应的LED灯
* 输入参数:state:设置LED灯的输出状态。
* 可选值:LED_OFF:LED灯灭;
* LED_ON: LED灯亮。
* LED_TOGGLE:反转LED
* 返 回 值: 无
* 说 明:该函数使用类似标准库函数的编程方法,方便理解标准库函数编程思想。
*/
void LEDx_StateSet(uint8_t LEDx,LEDState_TypeDef state)
{
/* 检查输入参数是否合法 */
assert_param(IS_LED_TYPEDEF(LEDx));
assert_param(IS_LED_STATE(state));

/* 判断设置的LED灯状态,如果设置为LED灯灭 */
if(state==LED_OFF)
{
if(LEDx & LED1)
LED1_OFF;/* LED1灭 */

if(LEDx & LED2)
LED2_OFF;/* LED2灭 */

if(LEDx & LED3)
LED3_OFF;/* LED3灭 */
}
else if(state==LED_ON) /* 设置LED灯为亮 */
{
if(LEDx & LED1)
LED1_ON;/* LED1亮 */

if(LEDx & LED2)
LED2_ON;/* LED2亮 */

if(LEDx & LED3)
LED3_ON;/* LED3亮 */
}
else
{
if(LEDx & LED1)
LED1_TOGGLE;/* 设置引脚输出反转 */

if(LEDx & LED2)
LED2_TOGGLE;/* 设置引脚输出反转 */

if(LEDx & LED3)
LED3_TOGGLE;/* 设置引脚输出反转 */
}
}

/******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/
已邀请:
楼主能不能弄个高级流水灯案例...
就是类似大厦外层那种,像下雨一样,一串灯从上到下,像瀑布一样,下面的灯最亮,往上一次渐渐的变暗,
效果就是拖拽出一条流星一样的流水灯,O(∩_∩)O~

yingshi - www.ing10bbs.com

赞同来自: 啥也不会的小黑黑

对楼上这个要求我只能呵呵

yingshi - www.ing10bbs.com

赞同来自:

发现这个帖子发错了,本来要发文章,选成问题了

Tangoo - 70后健男

赞同来自:

还是没有弄懂呀,

小白兔找蘑菇

赞同来自:

为什么要自己写头文件啊

hncjs - it老人

赞同来自:

不错的学习了

蓝天xi白云

赞同来自:

好好学习下


一心向前

赞同来自:

怎么弄头文件,加到哪一个文件夹,能搜索流水灯的你想想你直接弄这些看的得懂吗?

蘑菇弹

赞同来自: R1326

这种简单工程,完全没有必要弄什么bsp,直接用cubemx设置了之后在main的while中处理就可以了

lyagp03 - 80后IT男

赞同来自:

这代码看起来真是爽,这编程风格真的是好

星忆月

赞同来自: 恒宇科技

#define LED1                          (uint8_t)0x01
这个后面的0x01指的是什么

gprs08

赞同来自:

能注明使用的什么软件吗?软件版本,编译器版本?

要回复问题请先登录注册