前回の記事ではプロジェクトの作成方法を紹介しました。STM32CubeMXでテンプレートプロジェクトを作成したら、試しにオンボードのLEDを点灯させてみましょう。

プログラムのメインループは基本的に「Src/main.c」ファイルに記述します。STM32CubeMXでは既存のプロジェクトに追加でコード生成を行うと「/* USER CODE BEGIN [TAG] */」~「/* USER CODE END [TAG] */」に記述されたコード以外をすべて書き直します。そのため、生成されるコードには逐一このコメントが追加されます。

ライブラリーが増えるにつれてコメントでソースファイルが見にくくなっていくので、MPLAB Harmonyのように「Src/app.c」といった独立したファイルを作り、自前のプログラムをメインループから呼び出すようにするのもひとつの方法でしょう。

STM32CubeMXで生成されるGPIO関連のHALライブラリーAPIはこれらのものがあります。
初期化についてはフレームワークが自動で作成するので、もっぱら下の3つをプログラムで使うことになります。

いずれの関数も、第1引数はGPIOポートを定義した構造体(GPIOA~GPIOK)、第2引数はピンの番号(GPIO_PIN_0~GPIO_PIN_15,GPIO_PIN_ALL)を指定します。CubeMXのピン設定において「User Label」を記入しておくと、そのラベルの名称を使用したポート定義が出力されます。例えば、この画像のプロジェクトにおいては、以下のコードは同義です。
// ラベルが「LD2」のピンを切り替える
HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);

// ポートAの5番ピンを切り替える
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
ピンの状態はHAL_GPIO_ReadPin()を使ってGPIO_PinState列挙体(通常はGPIO_PIN_SET=1でHigh)の値を取得します。逆にピンの状態を変更するにはHAL_GPIO_WritePin()を使用します。

以上を踏まえたプログラム例がこちらです。「HAL_Delay」で指定したミリ秒ウェイト処理を行い、一定間隔でオンボードのLEDを点滅させています。
/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "app.h"
/* USER CODE END Includes */

int main(void)
{
    /* Infinite loop */
    /* USER CODE BEGIN WHILE */
    while (1)
    {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
        OnMyTask();
    }
    /* USER CODE END 3 */
}
#ifndef APP_H_
#define APP_H_

void OnMyTask();

#endif /* APP_H_ */
void OnMyTask()
{
    HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
    HAL_Delay(1000);
}
また、Nucreo-F446REのArduino互換D4ピンはPB5に相当するので、以下のようにピンとラベルを設定し、プログラミングすれば、ブレッドボードに設置したLEDを点滅させることができます。
void OnMyTask()
{
    HAL_GPIO_TogglePin(D4_GPIO_Port, D4_Pin);
    HAL_Delay(1000);
}
もし、デバッグを実行するたびにmain()・1行目でブレークするのが煩わしいようであれば、環境設定の「GDB→Stop on start up at」のチェックを外しましょう。
それでもmain()で止まってしまうようであれば、「実行→デバッグの構成」より、デバッグ実行時にブレークポイントを設置するスクリプトが存在するようであれば、その箇所を削除してみましょう。