0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

概要

物置で、stm32F4-discoveryが3台、見つかったので、最新、開発環境、入れてみた。

STM32F4とは

STM32F4シリーズは、STマイクロエレクトロニクス社が開発したArm Cortex-M4コアを搭載する高性能な32ビットマイコン(プロファインルはMプロファイル)です。

  • STM32F4の核となるスペックと位置づけ
    プロファイル: Armの3つのタイプ(A/R/M)のうち、超低消費電力・リアルタイム制御に特化したMプロファイルに属します。
    実行状態: 完全な32ビットマイコンであり、先述の分類ではAArch32(T32/Thumb-2命令セット)の流れを組むマイコン専用の実行環境で動作します
    (AArch64には対応していません)。
    コア性能: Cortex-M4を搭載。最大動作周波数は84MHz-180MHz(型番による)と、マイコンとしては非常に高速です。
    FPU(浮動小数点演算ユニット): 単精度FPU(浮動小数点演算の専用ハードウェア)を標準搭載しているため、信号処理や物理計算、センサーデータのフィルタリング(カルマンフィルタ等)を高速に処理できます。

  • 主な用途と強み
    高度な組み込み制御: ドローン、3Dプリンター、ロボットのモーター制御
    オーディオ処理: I2Sインターフェースを搭載し、高音質な音声再生・録音システムに採用
    グラフィックス: TFT液晶ディスプレイを直接駆動できるコントローラー(LTDC)を内蔵したモデルもあり、UI付きの機器開発が可能
    豊富な周辺機能: 大容量のフラッシュメモリ(最大2MB)とSRAM(最大256KB)、多数のタイマーや通信ポート(UART, SPI, I2C, CAN, USB OTG)を1チップに凝縮

  • Armの3つのタイプ(プロファイル)
    Armプロセッサは、用途に合わせて「A」「R」「M」という3つの「プロファイル」に分かれて設計されています。
    頭文字を合わせると「ARM」になります。

プロファイル 主な用途 特徴 具体例
Aプロファイル (Application) スマートフォン、PC、サーバー LinuxやiOS、AndroidなどのリッチなOSを動かすための最高性能プロファイル。大容量メモリ(MMU)や高度な計算能力を持ちます。 iPhone(Apple Silicon)、Snapdragon、Raspberry Pi 4/5
Rプロファイル (Real-time) 自動車のブレーキ、HDD制御、5G通信 ミリ秒・マイクロ秒単位の遅延も許されないリアルタイム制御のためのプロファイル。高い信頼性と確実な応答速度が特徴です。 車載安全システム、SSDコントローラー
Mプロファイル (Microcontroller) 家電製品、スマートメーター、IoT機器 超低消費電力・低コストに特化したマイコン向けプロファイル。OSを載せないベタメタル制御や、軽量なRTOSで動作します。 電子工作で人気の「Raspberry Pi Pico(RP2040/RP2350)」
  • AArch32 と AArch64 の違い
    これらは、主に「Aプロファイル(Armv8-A以降)」で導入された2つの「実行状態(Execution State)」のことです。
    AArch32(32ビット実行状態)
    従来の32ビットArmアプリケーションやOSを動かすための互換モードです。
    使用する命令セットは、従来の A32(いわゆるARM命令)や T32(Thumb命令)です。
    古い資産をそのまま動かす(後方互換性)ために残されていますが、近年の最新スマホ向けCPUなどでは廃止(64ビット専用化)が進んでいます。
    AArch64(64ビット実行状態)
    近年の主流である最新の64ビット実行環境です。
    使用する命令セットは A64 で、レジスタの数が大幅に増え、広大なメモリ空間(アドレス空間)を効率よく扱えるようになっています。
    Apple Silicon(Mシリーズ/Aシリーズ)や最新のAndroid、サーバー向けArmチップは、基本的にこのAArch64上でOSが動作しています。

セキュリティ機能

STM32マイコンには、製品の模倣(ファームウェアの盗難)や不正な書き換え、マルウェアの実行を防ぐための強力なハードウェア・セキュリティ機能が多数用意されています。
世代(古くからあるSTM32F4と、近年のSTM32H7/L5/U5など安全性を強化した最新世代)によって搭載されている機能が異なりますが、主なセキュリティ機能は以下の4つのレイヤーに分類されます。

1. ファームウェアの盗難・流出を防ぐ機能

競合他社などにフラッシュメモリ内のプログラム(アセット)を読み出されないようにする機能です。

RDP (Readout Protection / 読み出し保護)
最も基本かつ強力な保護機能です。デバッガ(ST-LINKなど)からのアクセスを遮断します。
Level 0: 保護なし(開発時)。
Level 1: デバッガからのフラッシュ読み出しを禁止。ただし、レベルを0に戻すことで再開発は可能です(その際、フラッシュメモリは全消去されます)。
Level 2: 完全ロック。デバッガ接続をハードウェアレベルで永久に無効化します。製品出荷時に設定します(二度と書き換えやデバッグはできなくなります)。
PCROP (Proprietary Code Readout Protection / 独自コード読み出し保護)
フラッシュメモリの特定の領域を「実行専用(Execute-Only)」にする機能です。CPUが命令として実行することはできますが、C言語のポインタ等による「データの読み出し」や「コピー」をハードウェアが完全にブロックします。

2. 不正なコードの実行・改ざんを防ぐ機能

改ざんされたファームウェアが起動するのを防いだり、動作中のバッファオーバーフロー攻撃を防ぐ機能です。

WRP (Write Protection / 書き込み保護)
ブートローダーやシステムに重要なプログラムが配置されているセクターへの書き込み・消去を禁止し、誤消去や不正な書き換えを防ぎます。
Secure Boot (セキュアブート)
マイコン起動時に、内蔵された暗号鍵を使ってファームウェアの電子署名を検証します。もしプログラムが1ビットでも改ざんされていた場合、起動をパニック停止させます。
MPU (Memory Protection Unit / メモリ保護ユニット)
STM32F4などにも搭載されている機能です。
メモリ領域(RAMや周辺レジスタ)をタスクごとに分離し、特定のユーザープログラムがシステムの重要な領域や他のタスクのメモリに不正アクセス(不正な書き換え)するのをハードウェアで検知・遮断します。

3. ハードウェア暗号化・鍵の管理

ソフトウェア処理では遅く、脆弱になりがちな暗号化をハードウェアアクセラレータで行います。

PKA (Public Key Accelerator) / AES / TRNG
公開鍵暗号(RSAや楕円暗号 ECC)や共通鍵暗号(AES)の計算を高速に行うハードウェアです。
TRNG(真の乱数生成器)は、アナログの熱ノイズなどを元に予測不可能な乱数を生成し、暗号鍵の作成に利用されます。
HUK (Hardware Unique Key) / Secure Storage
マイコン製造時に個体ごとに埋め込まれる固有の暗号鍵です。外部から読み出すことはできず、ファームウェアの暗号化やデバイスの個体認証に使用されます。

4. 最先端の分離技術(STM32L5 / U5 / H5 / H7など)

IoT時代に対応した、比較的新しいSTM32に搭載されている高度なアーキテクチャです。

Arm TrustZone (Cortex-M33 / M55搭載モデル)
1つのCPU内部をハードウェアレベルで「セキュア世界(Secure)」と「非セキュア世界(Non-secure)」に完全に分離します。
暗号鍵の管理や通信処理をセキュア世界で行い、通常のアプリケーション(先ほどのメロディ演奏など)を非セキュア世界で動かすことで、アプリ側に脆弱性があっても暗号鍵などの重要資産が決して漏洩しない仕組みを作れます。
STM32Trust
ST社が提供するセキュリティのエコシステムで、上記のハードウェア機能と、セキュア・ブートローダーの組み込みを簡単にするソフトウェアツール(STM32CubeProgrammer等での鍵管理)を統合したソリューションです。

STM32F4(手元のボード)で使える機能は?

現在お使いの STM32F4シリーズ の場合、主に以下の機能が利用可能です。

  1. RDP (Level 1 / Level 2) によるデバッガからの読み出し完全ブロック
  2. WRP による特定セクターの書き込み禁止
  3. PCROP によるコードのコピー防止(一部のF4モデル)
  4. MPU によるタスク間メモリ保護

これらは、プログラム内からレジスタを操作するか、STM32CubeProgrammerの「Option Bytes(オプションバイト)」画面からマウス操作(またはCLIコマンド)で簡単に設定できます。

stm32F4-discovery 仕様と機能

プロセッサ:ARM Cortex-M4F(最高動作周波数 168MHz、FPU・DSP命令対応)
メモリ:Flash 1MB、RAM 192KB
オンボードデバッガ:ST-LINK/V2(USB経由で書き込み・デバッグ、仮想COMポート機能を利用可能)
オーディオ機能:オーディオDAC(CS43L22、クラスDスピーカー用ドライバ内蔵)、デジタルマイク(MP45DT02)
センサー:3軸デジタル加速度・ジャイロスコープ(L3GD20)
インターフェース:USB OTG FS(Micro-AB)、ユーザーLED(4個+電源等)、プッシュボタン(ユーザー・リセット)、全LQFP100ピンを引き出した拡張ヘッダ
電源:USBバスパワー(5V)または外部3V/5V電源

stm32命令表

機械語の命令長(ビット幅)は「16bitまたは32bit」です。

ニーモニック 呼び名 動作
ADC Add with carry Rd := Rn + Op2 + Carry
ADD Add Rd := Rn + Op2
AND AND Rd := Rn & Op2
B Branch R15 := address
BIC Bit Clear Rd := Rn AND NOT Op2
BL Branch with Link R14 := R15, R15 := address
BX Branch and Exchange R15 := Rn, T bit := Rn[0]
CDP Coprocesor Data Processing (Coprocessor-specific)
CMN Compare Negative CPSR flags := Rn + Op2
CMP Compare CPSR flags := Rn - Op2
EOR Exclusive OR Rd := Rn ^ Op2
LDC Load coprocessor from memory Coprocessor load
LDM Load multiple registers Stack manipulation (Pop)
LDR Load register from memory Rd := (address)
MCR Move CPU register to coprocessor register cRn := rRn {(op)cRm}
MLA Multiply Accumulate Rd := (Rm * Rs) + Rn
MOV Move register or constant Rd : = Op2
MRC Move from coprocessor register to CPU register Rn := cRn {(op)cRm}
MRS Move PSR status/flags to register Rn := PSR
MSR Move register to PSR status/flags PSR := Rm
MUL Multiply Rd := Rm * Rs
MVN Move negative register Rd := 0xFFFFFFFF EOR Op2
ORR OR Rd := Rn OR Op2
RSB Reverse Subtract Rd := Op2 - Rn
RSC Reverse Subtract with Carry Rd := Op2 - Rn - 1 + Carry
SBC Subtract with Carry Rd := Rn - Op2 - 1 + Carry
STC Store coprocessor register to memory address := CRn
STM Store Multiple Stack manipulation (Push)
STR Store register to memory (address) := Rd
SUB Subtract Rd := Rn - Op2
SWI Software Interrupt OS call
SWP Swap register with memory Rd := [Rn], [Rn] := Rm
TEQ Test bitwise equality CPSR flags := Rn EOR Op2
TST Test bits CPSR flags := Rn AND Op2

レジスタ

32bit の r0 から r15までの16個
r13 -- スタックポインタ
r14 -- リンクレジスタ
r15 -- プログラムカウンタ

レジスタ 別名
r7 wr
r9 sb
r10 sl
r11 fp
r12 ip
r13 sp
r14 lr
r15 pc

写真

stm32f4_discovery.jpg

ピン配置

pin.jpg

比較

Arduino Uno Spresense stm32f4-discovery
Processor type AVR ARM M4F ARM M4F
Bits 8 32 32
Number of cores 1 6 1
Clock speed 16 MHz 156 MHz 168 MHz
Operating system None Nuttx None
Boot time 0 <1 second 0 Seconds
RAM 0.002MB 1.5 MB 0.1MB
FLASH 0.032MB 8 MB 2 MB
SD Card Shield On-Board, optional Shield
eMMC None Shield None
EEPROM 0.001MB Use Flash Use Flash
Voltage 5v or 6-20V 5V or LiPo(3.7V) 5V
Typical Operating Power 50 mW 100mW + low power modes ??mW
audio Quality Shield High Low
Microphones Shield up to 8 microphone Stereo
Speakers Shield Stereo Stereo
GNSS Shield GPS & GLONASS Shield
Time Shield RTC Shield
IO Pins 14 29 + 4 LED 32
IO voltage 5V 5V/3.3V/1.8V 3.6V
UART 1 2 2
SPI 1 1 (3.3/5v) +1 (1.8V) 1
I2C 1 1 (3.3/5V) +1 (1.8V/camera) 2
PWM 6 4 1
adc Channels 6 6 None
Bits 10 10 None
Fastest rate ~10 kHz 500 kSPS None
USB 1 device 2 device 1 otg
Camera Shield 5M Pixel shield
Video display None SPI up to 360x240 Pixel None
WiFi Shield Shield Shield
Bluetooth Shield Shield Shield
Ethernet Shield Shield Shield
Cellular Shield Shield Shield
価格 約1,000円 約6,000円 約2,000円

CMSIS と HAL とは

STM32F4シリーズのファームウェア開発における CMSIS と HAL は、それぞれ異なる抽象度(レイヤー)を持つソフトウェアコンポーネントです。
STM32CubeF4パッケージ を使用する際、これらは組み合わせて利用されます。

  • 概要と違い
項目 CMSIS (Cortex Microcontroller Software Interface Standard) HAL (Hardware Abstraction Layer)
提供元 ARM社(およびST社によるデバイス定義) STMicroelectronics社
抽象度 低レイヤー(レジスタへの直接アクセス) 高レイヤー(関数ベースの抽象化)
特徴 オーバーヘッドがなく軽量。自由度が高いが、ハードウェア(リファレンスマニュアル)の深い知識が必要。 周辺機能(GPIO, UART, I2Cなど)を簡単な関数呼び出しで制御可能。ポータビリティが高い。
記述例 `GPIOA->ODR = (1 << 5);`

‐ レイヤー構造
STM32CubeF4 のアーキテクチャでは、HALはCMSISの構造体やレジスタ定義を内部的に利用して動作しています。

+-------------------------------------------------------+

|                 ユーザーアプリケーション              |
+-------------------------------------------------------+

|        HAL (Hardware Abstraction Layer) Drivers       |
+-------------------------------------------------------+

|  CMSIS-Core (レジスタ定義 / クロック設定 / NVIC等)     |
+-------------------------------------------------------+

|             STM32F4 ハードウェア (Cortex-M4)          |
+-------------------------------------------------------+

基本的な実装フローの比較

  • HALドライバを使用する場合(標準的)
    STM32CubeMXSTM32CubeIDE で自動生成されるコードの形式です。
#include "stm32f4xx_hal.h"
int main(void) {
    // 1. HALライブラリの初期化
    HAL_Init(); 
    
    // 2. クロック・周辺機能(GPIOなど)の初期化 (CubeMX生成コード等)
    __HAL_RCC_GPIOA_CLK_ENABLE();
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin = GPIO_PIN_5;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    while (1) 
    {
        // LEDの反転
        HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
        HAL_Delay(500); // 500ms待機
    }
}
  • CMSISのみ(レジスタ直叩き)で制御する場合
    コードサイズを極限まで小さくしたい場合や、高速な処理が必要な場合に使用します。
#include "stm32f4xx.h" // CMSISデバイスヘッダー
void delay_ms(uint32_t ms) {
    // 簡易的なループ遅延(正確なタイマーではない)
    uint32_t count = ms * 16000; 
    while(count--) { __NOP(); }
}
int main(void) {
    // 1. GPIOAのクロックを有効化 (RCC_AHB1ENRレジスタ)
    RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
    
    // 2. GPIOAのピン5を出力モードに設定 (MODERレジスタ)
    GPIOA->MODER &= ~(3U << (5 * 2)); // 一度クリア
    GPIOA->MODER |= (1U << (5 * 2));  // 01: General purpose output mode

    while (1) 
    {
        // LEDの反転 (ODRレジスタ)
        GPIOA->ODR ^= (1U << 5);
        delay_ms(500);
    }
}

環境

windows10

Lチカ手順

CubeMX インストール

image.png

CubeIDE インストール

image.png

サンプルコード

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2026 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usb_host.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
I2C_HandleTypeDef hi2c1;

I2S_HandleTypeDef hi2s3;

SPI_HandleTypeDef hspi1;

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C1_Init(void);
static void MX_I2S3_Init(void);
static void MX_SPI1_Init(void);
void MX_USB_HOST_Process(void);

/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_I2C1_Init();
  MX_I2S3_Init();
  MX_SPI1_Init();
  MX_USB_HOST_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
    MX_USB_HOST_Process();

    /* USER CODE BEGIN 3 */
    HAL_GPIO_TogglePin(LD6_GPIO_Port, LD3_Pin);
    HAL_Delay(250);
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 8;
  RCC_OscInitStruct.PLL.PLLN = 336;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 7;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief I2C1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_I2C1_Init(void)
{

  /* USER CODE BEGIN I2C1_Init 0 */

  /* USER CODE END I2C1_Init 0 */

  /* USER CODE BEGIN I2C1_Init 1 */

  /* USER CODE END I2C1_Init 1 */
  hi2c1.Instance = I2C1;
  hi2c1.Init.ClockSpeed = 100000;
  hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
  hi2c1.Init.OwnAddress1 = 0;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN I2C1_Init 2 */

  /* USER CODE END I2C1_Init 2 */

}

/**
  * @brief I2S3 Initialization Function
  * @param None
  * @retval None
  */
static void MX_I2S3_Init(void)
{

  /* USER CODE BEGIN I2S3_Init 0 */

  /* USER CODE END I2S3_Init 0 */

  /* USER CODE BEGIN I2S3_Init 1 */

  /* USER CODE END I2S3_Init 1 */
  hi2s3.Instance = SPI3;
  hi2s3.Init.Mode = I2S_MODE_MASTER_TX;
  hi2s3.Init.Standard = I2S_STANDARD_PHILIPS;
  hi2s3.Init.DataFormat = I2S_DATAFORMAT_16B;
  hi2s3.Init.MCLKOutput = I2S_MCLKOUTPUT_ENABLE;
  hi2s3.Init.AudioFreq = I2S_AUDIOFREQ_96K;
  hi2s3.Init.CPOL = I2S_CPOL_LOW;
  hi2s3.Init.ClockSource = I2S_CLOCK_PLL;
  hi2s3.Init.FullDuplexMode = I2S_FULLDUPLEXMODE_DISABLE;
  if (HAL_I2S_Init(&hi2s3) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN I2S3_Init 2 */

  /* USER CODE END I2S3_Init 2 */

}

/**
  * @brief SPI1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_SPI1_Init(void)
{

  /* USER CODE BEGIN SPI1_Init 0 */

  /* USER CODE END SPI1_Init 0 */

  /* USER CODE BEGIN SPI1_Init 1 */

  /* USER CODE END SPI1_Init 1 */
  /* SPI1 parameter configuration*/
  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi1.Init.NSS = SPI_NSS_SOFT;
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 10;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN SPI1_Init 2 */

  /* USER CODE END SPI1_Init 2 */

}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  /* USER CODE BEGIN MX_GPIO_Init_1 */

  /* USER CODE END MX_GPIO_Init_1 */

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOE_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(CS_I2C_SPI_GPIO_Port, CS_I2C_SPI_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(OTG_FS_PowerSwitchOn_GPIO_Port, OTG_FS_PowerSwitchOn_Pin, GPIO_PIN_SET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOD, LD4_Pin|LD3_Pin|LD5_Pin|LD6_Pin
                          |Audio_RST_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin : CS_I2C_SPI_Pin */
  GPIO_InitStruct.Pin = CS_I2C_SPI_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(CS_I2C_SPI_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pin : OTG_FS_PowerSwitchOn_Pin */
  GPIO_InitStruct.Pin = OTG_FS_PowerSwitchOn_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(OTG_FS_PowerSwitchOn_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pin : PDM_OUT_Pin */
  GPIO_InitStruct.Pin = PDM_OUT_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
  HAL_GPIO_Init(PDM_OUT_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pin : B1_Pin */
  GPIO_InitStruct.Pin = B1_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_EVT_RISING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(B1_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pin : BOOT1_Pin */
  GPIO_InitStruct.Pin = BOOT1_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(BOOT1_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pin : CLK_IN_Pin */
  GPIO_InitStruct.Pin = CLK_IN_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
  HAL_GPIO_Init(CLK_IN_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pins : LD4_Pin LD3_Pin LD5_Pin LD6_Pin
                           Audio_RST_Pin */
  GPIO_InitStruct.Pin = LD4_Pin|LD3_Pin|LD5_Pin|LD6_Pin
                          |Audio_RST_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

  /*Configure GPIO pin : OTG_FS_OverCurrent_Pin */
  GPIO_InitStruct.Pin = OTG_FS_OverCurrent_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(OTG_FS_OverCurrent_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pin : MEMS_INT2_Pin */
  GPIO_InitStruct.Pin = MEMS_INT2_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_EVT_RISING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(MEMS_INT2_GPIO_Port, &GPIO_InitStruct);

  /* USER CODE BEGIN MX_GPIO_Init_2 */

  /* USER CODE END MX_GPIO_Init_2 */
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

書込み

USBminiで、パソコンに繋ぐ。

image.png

以上。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?