【北京迅为】《STM32MP157开发板使用手册》- 第二十五章Cortex-M4 GPIO_LED实验

iTOP-STM32MP157开发板采用ST推出的双核cortex-A7+单核cortex-M4异构处理器,既可用Linux、又可以用于STM32单片机开发。开发板采用核心板+底板结构,主频650M、1G内存、8G存储,核心板采用工业级板对板连接器,高可靠,牢固耐用,可满足高速信号环境下使用。共240PIN,CPU功能全部引出:底板扩展接口丰富底板板载4G接口(选配)、千兆以太网、WIFI蓝牙模块HDMI、CAN、RS485、LVDS接口、温湿度传感器(选配)光环境传感器、六轴传感器、2路USB OTG、3路串口,CAMERA接口、ADC电位器、SPDIF、SDIO接口等


第二十五章Cortex-M4 GPIO_LED实验

本章节最终所完成的实验例程存放路径为“iTOP-STM32MP157开发板网盘资料汇总\06_Cortex-M4实验例程\01_LED.zip”。

25.1什么是GPIO

GPIO(general porpose intput output):通用输入输出端口的简称。可以通过软件控制其输出和输入。芯片的GPIO引脚与外部设备连接起来,从而实现与外部通信,控制以及数据采集的功能设备。

STM32MP157 的 GPIO 有 GPIOA 至 GPIOK 和 GPIOZ 共 12 组 GPIO,其中 GPIOA~GPIOK每组有 16 个 IO,而 GPIOZ 有 8 个 IO。所有的 GPIO 均带有中断功能,所有的 GPIO 都可以被Cortex-M4 和 Cortex-A7 共享访问,而 GPIOZ 可用于 TrustZone 安全性相关的设置(当用于此项时仅限于 Cortex-A7 访问),相关的外围设备的软件访问被定义为安全性访问,常用于安全解决方案中。这里,STM32MP157 共 16*5+8=176+8=184 个 IO,而我们的开发板总共引出了144个引脚。

25.2 实验目的

1)GPIO的工作模式的初步认识

2)STM32CubeIDE工具软件的使用与熟悉

3)GPIO口使用方法的学习

25.3 GPIO的工作模式

STM32MP157的GPIO可以通过软件的配置设置成以下八种工作模式:

1.GPIO浮空输入_IN_FLOATING模式

2.GPIO带上拉输入_IPU 模式

3.GPIO带下拉输入_IPD 模式

4.GPIO模拟输入_AIN 模式

5.GPIO开漏输出_OUT_OD 模式

6.GPIO推挽输出_OUT_PP模式

7.GPIO开漏复用输出_AF_OD模式

8.GPIO推挽复用输出_AF_PP模式

下面对这八种工作模式进行简单的分析:

浮空输入模式

当GPIO采用浮空输入模式时,STM32的引脚状态是不确定的,此时STM32得到的电平状态完全取决于GPIO外部的电平状态,所以说在GPIO外部的引脚悬空时,读取该端口的电平状态是个不确定的值。

上拉下拉输入模式

由于浮空模式时,在GPIO外部连接的电路未工作时,STM32读取的GPIO状态是不确定的,所以可以通过带上拉或者下拉输入的模式先给MCU一个确定的状态,当外部电路电平状态发生变化时,易于MCU的判断。这样可以增强MCU的抗干扰能力

模拟输入模式

最常用的场合是ADC模拟输入,不像其他输入模式只有0和1,模拟输入模式可以读取到很细微变化的值。

推挽输出模式

推挽结构一般是指两个三极管分别受两个互补信号的控制,总是在一个三极管导通的时候另一个截止。这种结构既可以输出高电平,也可以输出低电平,可以用于连接数字器件。

推挽电路是两个参数相同的三极管或MOSFET,以推挽方式存在于电路中,各负责正负半周的波形放大任务,电路工作时,两只对称的功率开关管每次只有一个导通,所以导通损耗小,效率高。输出既可以向负载灌电流,也可以从负载抽取电流。推拉式输出级既提高电路的负载能力,又提高开关速度。

开漏输出模式

一般开漏输出模式时,如果外部不接上拉电阻时,只能输出低电平,所以要想输出高电平必须要外接上拉电阻。这样做的有一个好处,可以用来匹配不同的电平信号,也就是用于不同电压的系统之间的通信;另外,因为要输出高电平需要有外部的上拉电阻,所以在进行通信时,通信的速度也受到上拉电阻阻值的影响,阻值小时,通信速度可以很快,阻值大时,通信速度变慢,但也不能为了通信速度把上拉电阻用的很小,也要注意在电阻很小时,功耗会变大,所以要平衡好这个度。

复用推挽,开漏输出模式

这两种模式,可以理解为把GPIO配置为第二功能使用的时候的配置,并非单纯的用作IO输入或输出。

比如使用外设IIC时,我们需要把GPIO配置为复用推挽输出,用于数据通信功能。再比如串口通信的TX,以及SPI外设的GPIO使用就要把引脚设置为复用开漏输出。

25.4 LED电路的分析

我们的LED电路的原理图如下:

可以看到LED发光二极管由Q1和Q2两个L9014的NPN三极管控制通断,当三极管导通时LED发光二极管也会导通,当三极管截止时LED发光二极管也会截止,所以我们只需要通过控制两个GPIO引脚输出的高低电平来控制三极管的通断,进而控制LED发光二极管的亮灭。

以下为两个LED对应的控制引脚

LED2

LED3

PE14

PE1

25.5 实验步骤

25.5.1建立LED工程

首先我们打开STM32CubeIDE软件,进入软件界面之后,我们点击File属性,选择NEW下的STM32 Project的选项,如下图所示:

 

然后我们会进入下图所示界面:在Part Number选择框输入STM32MP157A,然后在右边的选择界面选择STM32MP157AAA,然后点击Next选项

在Project Name框中输入工程名字LED,然后点击Finish选项即可,如下图所示: 

等待工程创建完毕,会询问我们是否要安装OpenSTLinux ,由于我们是在windows环境下,所以我们不需要安装,点击NO即可 

至此我们的工程创建完毕,进入工程界面如下图所示界面: 

 

25.5.2 GPIO功能引脚配置

首先我们在下面的搜索框之中输入我们要配置的引脚,我们在这里以PE1为例进行搜索,输入名称之后,对应的引脚在工程中会闪烁,如下图所示:

然后我们使用鼠标左键点击对应的引脚会弹出PE1的复用功能选择,我们在这里选择复用为GPIO_Output功能,如下图所示: 

配置完复用功能之后,我们还要配置 Pin Reserved 选项如果不配置此项,在生成工程代码的时候将不会看到有关这个 Pin 的初始化代码。继续选中 PE1,右键弹出设置项我们选择Pin ReservedàCortex-M4。如下图所示: 

第二个LED的控制管脚PE14按同样的方法进行配置。

配置完成之后打开左侧菜单的 System CoreàGPIO 进入 GPIO 模式配置界面:如下图所示:

 

 点击对应的引脚配置之后会弹出右下方的管脚配置界面,如上图所示:

在下方会列出要配置选项的具体说明和我们要进行的配置。

1)选项 GPIO output level 用来设置IO口的输出电平的高低,这这里我们选择LOW

2)选项GPIO mode 用来设置 IO 口输出模式为 Output Push Pull(推挽)还是 Output Open Drain(开漏)。本实验我们设置为推挽输出 Output Push Pull。

3)选项 GPIO Pull-up/Pull-down 用来设置 IO 口是上拉/下拉/没有上下拉。本实验我们设置为上拉(Pull-up)。

4)选项 Mzximum ouput speed 用来设置 IO 口输出速度为低速(Low)/中速(Medium)/高速 (Hign)/快速(Very High)。我们设置为高速 High 。

5)选项 User Label 是用来设置初始化的 IO 口 Pin 值为我们自定义的宏,这里我们填写为 LED3。按照如上要求设置后的界面如下(由于PE14的配置相同,只是最后的Label值不同,也在下方列了出来):

配置完成之后我们需要在Project Manage下的Code Generator选项下勾选 Generate peripheral initialization as a pair of ".c/.h' files per peripheral 选项,这样可以独立生成对应外设的初始化.h 和.c 文件(方便配置的查看),如下图所示: 

 

25.5.3工程的生成与完善

在上述的步骤完成之后,按下键盘的Ctrl+S组合键保存保存 LED.ioc 文件,系统开始生成初始化代码,工程生成之后如下图所示:

 

然后我们进行工程的完善,以及添加对应的逻辑代码。

25.5.3.1 对应文件与文件夹的添加

首先在左侧的工程浏览页之中通过鼠标右键在LED_CM4的Core目录下创建名字为BSP的文件,具体步骤如下图所示:

 

然后在BSP目录下以同样的方法创建led.c文件和Include目录,以及Include目录下的led.h文件,创建完成如下图所示:

25.5.3.2 led.h文件的完善

我们对led.h文件进行代码的添加,将以下内容复制到led.h文件之中如下图所示:

  1 #ifndef __LED_H
  2 #define __LED_H
  3 #include "gpio.h"
  4 #define LED2(x)   do{ x ? \
  5                       HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_SET) : \
  6                       HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_RESET); \
  7                   }while(0)
  8 #define LED3(x)   do{ x ? \
  9                       HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, GPIO_PIN_SET) : \
 10                       HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, GPIO_PIN_RESET); \
 11                   }while(0)
 12 #define LED2_TOGGLE()    do{ HAL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin); }while(0)
 13 #define LED3_TOGGLE()    do{ HAL_GPIO_TogglePin(LED3_GPIO_Port, LED3_Pin); }while(0)
 14 void led_init(void);
 15 #endif

下面我们将对该文件进行简单的讲解:

在第3行,我们引用了gpio.h文件,我们进入gpio.c文件之中,文件路径如下图所示:

在对应的位置下会看到MX_GPIO_Init()函数,很明显的可以看出该函数正是我们在3.5.2小节之中所配置的功能。 

返回led.h文件之中,在4-13行便是四个宏定义,其中前两个宏定义是用来设置LED状态的,后两个宏定义是使LED状态进行反转的。具体功能是通过两个函数来实现的分别为HAL_GPIO_WritePin和HAL_GPIO_TogglePin。

在stm32mp1xx_hal_gpio.c文件之中可以找到HAL_GPIO_WritePin和HAL_GPIO_TogglePin的定义如下图所示:

 1 void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
  2 {
  3   /* Check the parameters */
  4   assert_param(IS_GPIO_PIN(GPIO_Pin));
  5   assert_param(IS_GPIO_PIN_ACTION(PinState));
  6 
  7   if (PinState != GPIO_PIN_RESET)
  8   {
  9     GPIOx->BSRR = GPIO_Pin;
 10   }
 11   else
 12   {
 13     GPIOx->BSRR = (uint32_t)GPIO_Pin << GPIO_NUMBER;
 14   }
 15 }
 16 
 17 /**
 18   * @brief  Toggles the specified GPIO pins.
 19   * @param  GPIOx: Where x can be (A..K) to select the GPIO peripheral.
 20   * @param  GPIO_Pin: Specifies the pins to be toggled.
 21   * @retval None
 22   */
 23 void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
 24 {
 25   /* Check the parameters */
 26   assert_param(IS_GPIO_PIN(GPIO_Pin));
 27 
 28   if ((GPIOx->ODR & GPIO_Pin) != 0x00u)
 29   {
 30     GPIOx->BRR = (uint32_t)GPIO_Pin;
 31   }
 32   else
 33   {
 34     GPIOx->BSRR = (uint32_t)GPIO_Pin;
 35   }
 36 }

HAL_GPIO_WritePin函数所实现的功能为设置对应的管脚的输出状态,GPIO_PIN_RESET为低电平、GPIO_PIN_SET为高电平。

HAL_GPIO_TogglePin函数所实现的功能为使对应管脚的输出状态反转(从高电平转为低电平,从低电平转为高电平)

25.5.3.3 led.c文件的完善

在led.c文件下,添加以下内容,以下内容实现的功能为定义led_init函数,调用该函数之后使LED2导通、LED3截止。

   #include "./Include/led.h"
  void led_init(void)
   {
           LED2(1);
           LED3(0);
   } 
25.5.3.4 main.c文件的完善

我们要修改的main.c文件路径如下图所示:

打开main.c文件,为了规范我们在/* USER CODE BEGIN Includes */和/* USER CODE END Includes */之间添加以下内容

#include "../BSP/Include/led.h"

添加完成如下图所示:

 

然后在 /* USER CODE BEGIN 2 */和/* USER CODE END 2 */之间添加以下内容:

 led_init();

通过调用led_init()函数来使LED2和LED3的初始状态分别为亮和灭。

然后在/* USER CODE BEGIN 3 */下添加以下逻辑代码

LED2_TOGGLE();

HAL_Delay(500);

LED3_TOGGLE();

HAL_Delay(500);  

 

该逻辑代码所实现的功能为两个LED灯的状态进行依次反转,且每次翻转所持续的时间为500ms。

25.5.4工程的编译

在完成以上步骤之后我们点击工具栏的小锤子进行编译,编译图标如下图所示:

 

编译完成会在下方的终端中显示打印信息,如下图所示: 

 

如果报错,需要自己根据错误的提示信息来进行问题的寻找和改正。

25.5.5工程的调试

由于STM32MP157的裸机部分和一般的单片机有些区别,他没有内部的存储,所以只能在程序编译成功之后,通过debug的方式来进行调试(将程序放在内存之中),调试过程如下:

首先,点击菜单栏中的小甲虫Debug调试按钮,弹出以下界面,

 

在弹出来的界面,按步骤,选择响应的属性(该步骤为Jlink的步骤,如果是STLink,调试探头选择对应的即可)。如下图所示: 

 

选择完成之后,点击右下角的Debug按钮,点击之后,会进行再一次的编译,编译完成之后会弹出如下内容(作者用的是J-LinK),这里弹出的是J-link关于设备的选择,不同调试器的弹窗可能会不同 

在弹出来的界面中,选择Accept接受,会弹出以下内容,继续点击下方的OK。 

 

之后会来到设备选择界面,我们选择Cortex-M4,如下图所示: 

 

选择Cortex-M4之后,点击右下角的OK,会弹出以下界面,选择右下角Switch.

然后会弹出一个新的页面,选择菜单栏的 resume,按钮开始调试。 

此时,会看到开发板上两个LED灯在交替闪烁。

如果想关闭调试,则点击菜单栏的终止按钮即可。

 

  • 12
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值