STM32L4系列四、跑马灯实验

记录一下,方便以后翻阅~
备注:原子哥的教材有很多不重要的错误,这里顺便就删减修改了。
主要内容:
1)STM32L4 IO 口简介;
2)硬件设计;
3)实验准备;
4)STM32CubeMX 配置 IO 口输入;
5)部分代码解读。

一、STM32L4 IO 简介
在讲解跑马灯实验案例之前,先通过跑马灯例程学习一下一个工程文件的分类(个人觉得原子哥写的工程文件分类清晰,方便整理),如下图所示:
在这里插入图片描述
简单说明下工程目录下面的组以及重要文件:
1)①组USER下面主要存放用户代码。system_stm32l4xx.c文件用户不用修改,stm32l4xx_it.c 里面存放的是中断服务函数,main.c函数主要存放主函数;
2)②组CORE下面主要存放固件库必须的核心头文件和启动文件。这些文件用户不用修改,可以根据芯片型号选择对应的启动文件;
3)③组SYSTEM是原子哥提供的共用代码,比较好用;
4)④组HALLIB下面主要存放ST官方提供的HAL库文件;
5)⑤组HARDWARE下面主要存放每个实验的外设驱动代码,通过调用HALLIB下面的HAL库文件函数实现,如led.c中函数调用stm32l4xx_hal_gpio.c内定义的函数对led进行初始化。

同STM32F1一样,STM32L4的IO由软件配置成如下8种模式中的任何一种(可关注其他文章,有更详细的讲解):
1、输入浮空
2、输入上拉
3、输入下拉
4、模拟输入
5、开漏输出
6、推挽输出
7、推挽式复用功能
8、开漏式复用功能

操作IO口的简单步骤为:
1) 使能 IO 口时钟,调用函数__HAL_RCC_GPIOX_CLK_ENABLE(其中 X=A~K);
2) 初始化IO参数,调用函数 HAL_GPIO_Init();
3) 操作IO输入输出。

实验功能简介
开机上电后,先初始化与RGB灯连接的IO口,然后每500ms改变一下RGB灯的颜色,实现类似跑马灯的效果。

二、硬件设计
本章用到的硬件只有RGB灯。LED_R接PE7,LED_G接PE8,LED_B接PE9,连接原理图如下图所示:
在这里插入图片描述
三、实验准备
1)使用Micro USB线将PC的USB口与潘多拉开发板的ST LINK USB口连接起来;
2)打开实验1跑马灯(RGB)实验例程,编译通过后将程序下载到MCU;
3)实验结果验证。

四、STM32CubeMX 配置 IO 口输出
关于STM32CubeMX工具的入门使用之前有讲过,这里不再重复。本节主要介绍怎么配置GPIO口的相关参数。
打开 STM32CubeMX 工具,RCC 相关配置可参考STM32L4系列二、STM32CubeMX 图形配置工具基本操作过程
GPIO口的配置步骤如下:
第一步,在引脚图中选择要配置的IO口,以PE7为例,在弹出的下拉菜单中选择要配置的IO口模式,如下图所示:
在这里插入图片描述
上图的下拉菜单中,除了配置IO口为输入输出之外,还可以选择IO口的复用功能或者作为外部中断引脚功能,比如要选择IO口复用为SAI1功能,那么选择SAI1_SD_B即可。对于跑马灯实验,PE7作为输出,所以选择GPIO_Output。

第二步,进入Configuration->GPIO,在弹出的界面配置IO口的详细参数,如下图所示:
在这里插入图片描述
在这里插入图片描述
在IO口详细参数配置界面,点击要配置的IO口,会在窗口下方显示该 IO 口配置的详细参数表,这些配置项的含义具体为:
1)GPIO output level:默认输出电平,可设为Low和High,即低电平或高电平,本实验默认关闭LED_R、LED_G和LED_B,择设为 High;
2)GPIO mode:用来设置输出模式为:Output Push Pull(推挽输出)或Output Open Drain(开漏输出),本实验均设置为推挽输出;
3)选项GPIO Pull-up/Pull-down用来设置IO口是上拉/下拉/没有上下拉。本实验设置为上拉(Pull-up);
4)选项Maxinum ouput speed用来设置输出速度为超高速(Very High)/高速(High)/中速(Medium)/低速(Low),本实验设置为高速 High;
5)选项User Label是用来设置初始化的IO口Pin值为我们自定义的宏,一般可以不用设置。
PE8 和 PE9 的配置方法和参数都一样,就不重复讲解。

GPIO配置完成后,参考STM32L4系列二、STM32CubeMX 图形配置工具基本操作过程生成工程源码。

打开工程的main.c文件,该文件内部由STM32CubeMX生成函数MX_GPIO_Init,内容如下:

static void MX_GPIO_Init(void) 
{
    
    
 GPIO_InitTypeDef GPIO_InitStruct; 
 /* GPIO Ports Clock Enable */ 
 __HAL_RCC_GPIOH_CLK_ENABLE(); 
 __HAL_RCC_GPIOE_CLK_ENABLE(); 
 /*Configure GPIO pin Output Level */ 
 HAL_GPIO_WritePin(GPIOE, GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9, GPIO_PIN_SET); 
 /*Configure GPIO pins : PE7 PE8 PE9 */ 
 GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9; 
 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; 
 GPIO_InitStruct.Pull = GPIO_PULLUP; 
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; 
 HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); 
}

五、部分函数解读
对案例库进行适当修改后(主要将两个子函数分离出来,这样代码显得清晰),部分代码如下:
1)main.c函数

/**
 ********************************  STM32L4x  *********************************
 * @文件名称: main.c
 * @修改作者: 闲人Ne
 * @库版本号: V3.5.0
 * @工程版本: V1.0.0
 * @开发日期: 2020年12月07日
 * @摘要简述: 主函数
 ******************************************************************************/
/*----------------------------------------------------------------------------
 * @更新日志:
 * @无
 * ---------------------------------------------------------------------------*/
/* Includes ------------------------------------------------------------------*/
#include "stm32l4xx_hal.h"
#include "led.h"    // 初始化LED灯的引脚配置
#include "sys.h"    // 初始化时钟用
#include "delay.h"
/************************************************
函数名称:int main()
函数功能:主函数
入口参数:无
返回参数:无
*************************************************/
int main(void)
{
    
    
 u8 color=0;
 HAL_Init();
 SystemClock_Config();
 MX_LED_Init();
 delay_init(80);     // 初始化延时函数,80M系统时钟
 while (1)
 {
    
    
  switch(color%8)       // 取余数
  {
    
    
   case 0:             // 余数为0时
    LED_R(0);
    LED_G(0);
    LED_B(0);
    break;
   case 1:       // 余数为1时
    LED_R(0);
    LED_G(0);
    LED_B(1);
    break;
   case 2:       // 余数为2时
    LED_R(0);
    LED_G(1);
    LED_B(0);
    break;
   case 3:       // 余数为3时
    LED_R(0);
    LED_G(1);
    LED_B(1);
    break;
   case 4:       // 余数为4时
    LED_R(1);
    LED_G(0);
    LED_B(0);
    break;
   case 5:       // 余数为5时
    LED_R(1);
    LED_G(0);
    LED_B(1);
    break;
   case 6:       // 余数为6时
    LED_R(1);
    LED_G(1);
    LED_B(0);
    break;
   case 7:       // 余数为7时
    LED_R(1);
    LED_G(1);
    LED_B(1);
    break;
   default:
    break;
  }
  color++;
  delay_ms(500);    // 延时500ms就改变一次颜色
 }
}
/****** Copyright (C)2020 闲人Ne. All Rights Reserved ****** END OF FILE *******/

2)led.h头文件

/**
 ********************************  STM32L4x  *********************************
 * @文件名称: led.h
 * @修改作者: 闲人Ne
 * @库版本号: V3.5.0
 * @工程版本: V1.0.0
 * @开发日期: 2020年12月07日
 * @摘要简述: led.h头文件
 ******************************************************************************/
/*----------------------------------------------------------------------------
 * @更新日志:
 * @无
 * ---------------------------------------------------------------------------*/
#ifndef __LED_H
#define __LED_H
/* RGB接口定义 ----------------------------------------------------------------*/
#define LED_R(n)     (n?HAL_GPIO_WritePin(GPIOE,GPIO_PIN_7,GPIO_PIN_SET):HAL_GPIO_WritePin(GPIOE,GPIO_PIN_7,GPIO_PIN_RESET))
#define LED_R_TogglePin  HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_7)    // LED_R电平翻转
#define LED_G(n)     (n?HAL_GPIO_WritePin(GPIOE,GPIO_PIN_8,GPIO_PIN_SET):HAL_GPIO_WritePin(GPIOE,GPIO_PIN_8,GPIO_PIN_RESET))
#define LED_G_TogglePin   HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_8)   // LED_G电平翻转
#define LED_B(n)     (n?HAL_GPIO_WritePin(GPIOE,GPIO_PIN_9,GPIO_PIN_SET):HAL_GPIO_WritePin(GPIOE,GPIO_PIN_9,GPIO_PIN_RESET))
#define LED_B_TogglePin   HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_9)   // LED_B电平翻转
/* 函数申明 ------------------------------------------------------------------*/
void MX_LED_Init(void);
#endif /* __LED_H */
/****** Copyright (C)2020 闲人Ne. All Rights Reserved ****** END OF FILE *******/

3)led.c源文件

/**
 ********************************  STM32L4x  *********************************
 * @文件名称: led.c
 * @修改作者: 闲人Ne
 * @库版本号: V3.5.0
 * @工程版本: V1.0.0
 * @开发日期: 2020年12月07日
 * @摘要简述: led.c源文件
 ******************************************************************************/
/*----------------------------------------------------------------------------
 * @更新日志:
 * @无
 * ---------------------------------------------------------------------------*/
/* Includes ------------------------------------------------------------------*/
#include "led.h"
#include "stm32l4xx_hal.h"
/************************************************
函数名称:MX_LED_Init()
函数功能:LED管脚配置
入口参数:无
返回参数:无
*************************************************/
void MX_LED_Init(void)
{
    
    
  GPIO_InitTypeDef GPIO_InitStruct;
  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOE_CLK_ENABLE();
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOE, GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9, GPIO_PIN_SET);
  /*Configure GPIO pins : PE7 PE8 PE9 */
  GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
}
/****** Copyright (C)2020 闲人Ne. All Rights Reserved ****** END OF FILE *******/

备注:在用STM32CubeMX生成代码的时候,main函数里的SystemClock_Config()子函数里少一行代码 RCC_OscInitStruct.PLL.PLLM = 1,导致前期在main函数里设延迟时间,总感觉与实际时间不符。补上这行代码后就好了。

猜你喜欢

转载自blog.csdn.net/Leisure_ksj/article/details/110733376