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開發板測試,結果與預期一致。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM