zoukankan      html  css  js  c++  java
  • STM32F412应用开发笔记之二:基本GPIO控制

    NUCLEO-F412ZG板子上的元器件并没有完全焊接,除去ST-LINK部分和电源部分后,还有用一个USB主机接口,三个LED灯和两个按钮,不过很多功能引脚都已经引到了插针。查看原理图可发现,由原理图模块的5大部分与电源部分组成,即连接端子、ST-LINK、MCU、USB、以太网和电源部分。

    电源部分考虑的非常充分,5V有三路输入,一路是有外部输入6-15VDC电源经U5(LD1117S50TR)转为5VDC电源;第二路是USB端口提供的5V电源,同时还有电流限制保护U4(ST890CDR);第三路则是由外部直接输入5V电源。默认是选择的USB口电源输入,并U6(LD39050PU33R)输出3.3VDC电源。当然还有ST-LINK部分的电源以及USB主机部分的电源。而且这两部分也是上述3路5VDC供电。

     

    以太网部分的电路并未焊接。时钟部分ST-LINK使用了8M的外部晶振(X1),而F412的主时钟输入有两路,一路是从ST-LINK的主控芯片MCO引来,一路也是外界的8M外部晶振(X3)。板子采用的是从MCO引来的时钟。此外还有一个32.768K的外部晶振(X2)。

    在了解了基本电路后,开始编程之旅,使用的开发环境是IAR EWARM7.5。首先使用STM32CubeMX创建一个项目。打开STM32CubeMX出现如下的界面。

     

    点击“New Project”新建一个项目,弹出新项目对话框:

     

    由于使用的是NUCLEO-F412ZG开发板,所以选择Board Selector标签,并选择板子的类型为Nucleo144,选择MCU系列为STM32F4,点击“OK”按钮创建项目,出现如下界面:

     

    在第一个项目中我们简单的利用开发板上提供的按钮B1来控制开发板上的三个指示灯LD1(绿色)、LD2(蓝色)、LD3(红色)其中:

    按钮B1对应的输入引脚为:PC13

    绿色指示灯LD1对应的引脚为:PB0

    蓝色指示灯LD2对应的引脚为:PB7

    红色指示灯LD3对应的引脚为:PB14

    同时通过引脚PG2来驱动外围的继电器电路,这部分电路由自己搭建。原理图如下:

     

    对于IO的配置可以在STM32CubeMX中完成,将PC13配置为GPIO_EXIT13;将PB0、PB7、PB14与PG2都配置为GPIO_OUTPUT。配置好GPIO引脚的类型后就可以在”Configuration“标签(如下图所示)中配置GPIO口了。

     

    在“System“下,选择GPIO弹出”Pin Configuration“对话框。在对话框中一一配置各个GPIO引脚,在本次中我配置个引脚如下:

     

    完成以上配置后,生成IAR EWARM项目则会在生成的源码中出现GPIO的配置,源码如下:

    GPIO_InitTypeDef GPIO_InitStruct;

    /* GPIO Ports Clock Enable */

    __HAL_RCC_GPIOC_CLK_ENABLE();

    __HAL_RCC_GPIOH_CLK_ENABLE();

    __HAL_RCC_GPIOB_CLK_ENABLE();

    __HAL_RCC_GPIOD_CLK_ENABLE();

    __HAL_RCC_GPIOG_CLK_ENABLE();

    __HAL_RCC_GPIOA_CLK_ENABLE();

    /*Configure GPIO pin : B1_Pin */

    GPIO_InitStruct.Pin = B1_Pin;

    GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;

    GPIO_InitStruct.Pull = GPIO_NOPULL;

    HAL_GPIO_Init(B1_GPIO_Port, &GPIO_InitStruct);

    /*Configure GPIO pins : LD1_Pin LD3_Pin LD2_Pin */

    GPIO_InitStruct.Pin = LD1_Pin|LD3_Pin|LD2_Pin;

    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

    GPIO_InitStruct.Pull = GPIO_NOPULL;

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    /*Configure GPIO pins : STLK_RX_Pin STLK_TX_Pin */

    GPIO_InitStruct.Pin = STLK_RX_Pin|STLK_TX_Pin;

    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

    GPIO_InitStruct.Pull = GPIO_NOPULL;

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

    GPIO_InitStruct.Alternate = GPIO_AF7_USART3;

    HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

    /*Configure GPIO pins : Relay_Ctrl_Pin USB_PowerSwitchOn_Pin */

    GPIO_InitStruct.Pin = Relay_Ctrl_Pin|USB_PowerSwitchOn_Pin;

    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

    GPIO_InitStruct.Pull = GPIO_NOPULL;

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

    HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

    /*Configure GPIO pin : USB_OverCurrent_Pin */

    GPIO_InitStruct.Pin = USB_OverCurrent_Pin;

    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;

    GPIO_InitStruct.Pull = GPIO_NOPULL;

    HAL_GPIO_Init(USB_OverCurrent_GPIO_Port, &GPIO_InitStruct);

    /*Configure GPIO pins : USB_SOF_Pin USB_ID_Pin USB_DM_Pin USB_DP_Pin */

    GPIO_InitStruct.Pin = USB_SOF_Pin|USB_ID_Pin|USB_DM_Pin|USB_DP_Pin;

    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

    GPIO_InitStruct.Pull = GPIO_NOPULL;

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

    GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;

    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /*Configure GPIO pin Output Level */

    HAL_GPIO_WritePin(GPIOB, LD1_Pin|LD3_Pin|LD2_Pin, GPIO_PIN_RESET);

    /*Configure GPIO pin Output Level */

    HAL_GPIO_WritePin(GPIOG, Relay_Ctrl_Pin|USB_PowerSwitchOn_Pin, GPIO_PIN_RESET);

    在硬件配置方面,STM32CubeMX能够完成全部的基础工作,我们只需要完成自己的控制逻辑,非常方便。如果设计的好,我们自己学的程序的通用性可以大大提高,极大降低与底层硬件的耦合强度。不过在使用中发现STM32CubeMX似乎与中文操作系统配合得不太好,总是出现全角字符的困扰,估计ST不久会解决。

    我的测试逻辑比较简单,一开始三个指示灯全部亮,继电器不导通。按钮B1按一下,LD1灭,再按一下LD2灭,再按一下LD3灭同时继电器吸合,再按一下三个灯全亮同时继电器断开,如此循环。

    这部分的源码实现也比较简单,首先定义了一个表示状态的枚举类型,然后根据不通的状态定义逻辑操作。

    typedef enum

    {

      STATE0 = 0,

      STATE1,

      STATE2,

      STATE3,

      STATENUM

    }STATE;

    /*逻辑控制的实现*/

    void LogicCtrol(void)

    {

      GPIO_PinState b1State=HAL_GPIO_ReadPin(B1_GPIO_Port,B1_Pin);

      if(b1State==GPIO_PIN_SET)

      {

        status++;

      }

      if(status>=STATENUM)

      {

        status=STATE0;

      }

      switch(status)

      {

      case STATE0:

        {

          HAL_GPIO_WritePin(GPIOB, LD1_Pin|LD3_Pin|LD2_Pin, GPIO_PIN_SET);

          HAL_GPIO_WritePin(GPIOG, Relay_Ctrl_Pin, GPIO_PIN_RESET);

          break;

        }

      case STATE1:

        {

          HAL_GPIO_WritePin(GPIOB, LD1_Pin, GPIO_PIN_RESET);

          HAL_GPIO_WritePin(GPIOB, LD3_Pin|LD2_Pin, GPIO_PIN_SET);

          HAL_GPIO_WritePin(GPIOG, Relay_Ctrl_Pin, GPIO_PIN_RESET);

          break;

        }

      case STATE2:

        {

          HAL_GPIO_WritePin(GPIOB, LD1_Pin|LD2_Pin, GPIO_PIN_RESET);

          HAL_GPIO_WritePin(GPIOB, LD3_Pin, GPIO_PIN_SET);

          HAL_GPIO_WritePin(GPIOG, Relay_Ctrl_Pin, GPIO_PIN_RESET);

          break;

        }

      case STATE3:

        {

          HAL_GPIO_WritePin(GPIOB, LD1_Pin|LD2_Pin|LD3_Pin, GPIO_PIN_RESET);

          HAL_GPIO_WritePin(GPIOG, Relay_Ctrl_Pin, GPIO_PIN_SET);

          break;

        }

      default:

        {

          break;

        }

      }

    }

    下载到NUCLEO-F412ZG开发板测试,结果与预期一致。

  • 相关阅读:
    ORACLE 查看进程数,已执行任务数, 剩余任务数,删除指定任务
    ORACLE 收集统计整个用户数据
    解决Hystrix dashboard Turbine 一直 Loading…… 及其他坑
    利用 Maven 构造 Spring Cloud 微服务架构 模块使用 spring Boot构建
    AES加解密
    JAVA POI XSSFWorkbook导出扩展名为xlsx的Excel,附带weblogic 项目导出Excel文件错误的解决方案
    JAVA 文件的上传下载
    shell启停服务脚本模板
    JAVA 设计模式之 原型模式详解
    JAVA 设计模式之 工厂模式详解
  • 原文地址:https://www.cnblogs.com/foxclever/p/6164225.html
Copyright © 2011-2022 走看看