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?

DeepLearning学習日誌12 誤差逆伝播法バックプロパゲーション XORの学習データで推論 Nucleo-F446RE

Last updated at Posted at 2026-01-20

Geminiとの対話をベースに、記事を構成しています。

参考書:
ゼロから作るDeepLearning Pythonで学ぶディープラーニングの理論と実践 斎藤康毅 著

開発環境:
VScode + 拡張機能Python(microsoft) + anaconda(統計処理、参考書の推薦ライブラリ)

この記事は、ゼロから作るDeep Learning 第5章の学習記録と、補足知識の記録になります。
内容は、徐々に追記していきます。

XORの重みとバイアスの学習結果をSTM32をつかって、推論させてみた。

IMG_5497.JPG

前回のつづきです。マイコンSTM32を使って推論させます。
PCで学習したパラメータを使い、順伝播のみをコーディング。
予想値が、PC上のpythonと同じ値になるか、確かめてみました。

「PCで学習させたAIモデル(重み)を、そのままマイコンに移植して推論させる」 という一連のエッジAI開発フローが開通しました。
パソコンSTM32結果.png

重みをC言語の配列にする。
#c言語の配列形式で、パラメータを出力するヘルパー関数
#ex.)行番号 * 列数 + 列番号
# W1 shape: (4, 2) -> 列数(幅)は 2
# W[i][j] -> W_flat[i * 2 + j]
def to_c_array(name, params):
    print("//使う時にインデックスを計算する: W[i][j] -> W_flat[i * 2 + j]")
    print(f"// {name} shape: {params.shape}")
    print(f"float {name}[] = {{")

    flat_params = params.flatten() #1次元に平坦化
    for i, val in enumerate(flat_params): #enumerate indexとvlueを返す
        end = ","
        if i == len(flat_params) -1: end = "" #最後の要素にカンマをつけない
        print(f"    {val:.8f}f{end}")#float型として出力

    print("};")
    print()

nucleo-F446RE 誤差逆伝播法 XOR推論コード

neuralNetWeight.h 学習済みパラメータ
neuralNetWeight.h
/*
 * neuralNetWeight.h
 *
 *  Created on: 2026/01/20
 *      Author: h
 */

#ifndef INC_NEURALNETWEIGHT_H_
#define INC_NEURALNETWEIGHT_H_

#include "main.h"

/**
 * @struct
 * @brief
 * 行列情報の格納
 */
typedef struct
{
	char name[6];//配列名
	int shape[2];//形状
	float *values;//学習データへのポインタ
}matrixItems;

extern matrixItems Xtrain,W1,b1,W2,b2;
extern matrixItems Y1out,Y2out;

//行番号 * 列数 + 列番号
// W1 shape: (4, 2) -> 列数(幅)は 2
// W[i][j] -> W_flat[i * 2 + j]
extern const float val_Xtrain[];

//行番号 * 列数 + 列番号
// W1 shape: (2, 4) -> 列数(幅)は 4
// W[i][j] -> W_flat[i * 4 + j]
extern const float val_W1[];

// b1 shape: (4,1) -> 列数(幅)は 1
// W[i][j] -> W_flat[i * 1 + j]
extern const float val_b1[];

// W2 shape: (4, 2) -> 列数(幅)は 2
// W[i][j] -> W_flat[i * 2 + j]
extern const float val_W2[];

// b1 shape: (2,1) -> 列数(幅)は 1
// W[i][j] -> W_flat[i * 1 + j]
extern const float val_b2[] ;

//計算バッファ用行列
extern float val_Y1out[100];
extern float val_Y2out[100];


#endif /* INC_NEURALNETWEIGHT_H_ */

neuralNetWeight.c 学習済みパラメータ
neuralNetWeight.c
/*
 * neuralNetWeight.c
 *
 *  Created on: 2026/01/20
 *      Author: h
 */

#include "neuralNetWeight.h"

//計算用バッファ
float val_Y1out[100];
float val_Y2out[100];

/*******************************************
 ニューラルネット
 * 入力層、2ノード
 * 隠れ層1、4ノード
 * 出力層、2ノード
********************************************/

//入力データ
matrixItems Xtrain = {
		"Xtrain",
		{4,2},
		(float*)val_Xtrain
};

//重みW1
matrixItems W1={
	"W1",
	{2,4},
	(float*)val_W1
};

//バイアスb1
matrixItems b1={
	"b1",
	{4,1},
	(float*)val_b1
};

//重みW2
matrixItems W2={
	"W2",
	{4,2},
	(float*)val_W2
};

//バイアスb2
matrixItems b2 ={
	"b2",
	{2,1},
	(float*)val_b2
};

//計算用バッファ1 Y1out
matrixItems Y1out={
	"Y1out",
	{10,10},
	(float*)val_Y1out
};

//計算用バッファ2 Y2out
matrixItems Y2out={
	"Y2out",
	{10,10},
	(float*)val_Y2out
};

//**************************************
//XOR 学習済み重み、バイアスデータ
//**************************************

//行番号 * 列数 + 列番号
// W1 shape: (4, 2) -> 列数(幅)は 2
// W[i][j] -> W_flat[i * 2 + j]
const float val_Xtrain[]={
		0.f, 0.f,
		0.f, 1.f,
		1.f, 0.f,
		1.f, 1.f
};

//行番号 * 列数 + 列番号
// W1 shape: (2, 4) -> 列数(幅)は 4
// W[i][j] -> W_flat[i * 4 + j]
const float val_W1[] = {
    0.53015456f,
    4.15742941f,
    0.60971763f,
    5.51955458f,
    1.01142231f,
    4.17652562f,
    0.16316377f,
    5.51023840f
};


// b1 shape: (4,1) -> 列数(幅)は 1
// W[i][j] -> W_flat[i * 1 + j]
const float val_b1[] = {
    -0.02964760f,
    -6.41160849f,
    0.61649058f,
    -2.28508588f
};

// W2 shape: (4, 2) -> 列数(幅)は 2
// W[i][j] -> W_flat[i * 2 + j]
const float val_W2[] = {
    0.69770619f,
    0.05081438f,
    6.12618934f,
    -5.17675507f,
    1.35918113f,
    -0.36441186f,
    -4.74886656f,
    6.64432100f
};

// b1 shape: (2,1) -> 列数(幅)は 1
// W[i][j] -> W_flat[i * 1 + j]
const float val_b2[] = {
    2.21948071f,
    -1.57753516f
};
neuralNet.h 関数ヘッダー
neuralNet.h

#ifndef INC_NEURALNET_H_
#define INC_NEURALNET_H_

#include "main.h"
#include <stdio.h>  // printf用
#include <math.h>   // expf用
#include "neuralNetWeight.h"

extern void matrixPrint(char *name,float *x, int i, int j);
extern void matrixDot(matrixItems *x1, matrixItems *x2,  matrixItems *y1);
extern void matrixAdd(matrixItems *x1, matrixItems *x2,  matrixItems *y1);
extern void matrixSigmoid(matrixItems *x1, matrixItems *y1);
extern float sigmoid(float val);
extern void matrixSoftmax(matrixItems *x1);

#endif /* INC_NEURALNET_H_ */
neuralNet.c 関数
neuralNet.c
/*
 * neuralNet.c
 *
 *  Created on: 2026/01/20
 *      Author: h
 */

#include "neuralNet.h"

char matrixName[3];

/**
 * @fn void matrixPrint(char*, float*, int, int)
 * @brief 行列の表示
 *
 * @param name
 * @param x
 * @param rowMax
 * @param columnMax
 */
void matrixPrint(char *name,float *x, int rowMax, int columnMax)
{
	int i, j;

	printf("%s\n",name);
	printf("Shape[%d %d]\r", rowMax, columnMax);
	for (i=0; i<rowMax; i++)
	{
		for(j=0; j<columnMax; j++)
		{
			printf("%2.8f ",x[i*columnMax +j]);
		}
		printf("\r");
	}
}


/**
 * @fn void matrixDot(matrixItems*, matrixItems*, matrixItems*)
 * @brief 行列の内積計算
 *
 * @param x1
 * @param x2
 * @param y1
 */
void matrixDot(matrixItems *x1, matrixItems *x2,  matrixItems *y1)
{
	int i,j,k;
	float fval1;
	for(i=0; i<x1->shape[0]; i++)//1..4
	{
		for(j=0; j<x2->shape[1]; j++)//1..4
		{
			fval1=0;
			for(k=0; k < x1->shape[1]; k++)//1..2
			{
				fval1 += x1->values[i*x1->shape[1]+k] * x2->values[k*x2->shape[1]+j];
				//printf("(%2.3f,%2.3f)",x1->values[h*x1->shape[1]+i] , x2->values[i*x2->shape[1]+k]);
				/*if(i!=((x1->shape[1])-1))
				{
					printf("*");
				}*/
			}
			y1->values[i*x2->shape[1]+j] = fval1;
			//printf("%4.3f ", fval1);
		}
	}
	y1->shape[0]=x1->shape[0];
	y1->shape[1]=x2->shape[1];
}

/**
 * @fn void matrixAdd(matrixItems*, matrixItems*, matrixItems*)
 * @brief 行列の足し算
 *
 * @param x1
 * @param x2
 * @param y1
 */
void matrixAdd(matrixItems *x1, matrixItems *x2,  matrixItems *y1)
{
	int i,j;

	for(i = 0; i<x1->shape[0]; i++)
	{
		for(j = 0; j<x1->shape[1]; j++)
		{
			y1->values[i*x1->shape[1]+j]= x1->values[i*x1->shape[1]+j]+ x2->values[j];
		}
	}
}

/**
 * @fn void matrixSigmoid(matrixItems*, matrixItems*)
 * @brief 活性化関数 シグモイド関数(行列計算)
 *
 * @param x1
 * @param y1
 */
void matrixSigmoid(matrixItems *x1, matrixItems *y1)
{
	int i,j;

	for(i = 0; i<x1->shape[0]; i++)
		{
			for(j = 0; j<x1->shape[1]; j++)
			{
				y1->values[i*x1->shape[1]+j]= sigmoid(x1->values[i*x1->shape[1]+j]);
			}
		}
}

/**
 * @fn float sigmoid(float)
 * @brief 活性化関数 シグモイド関数
 *
 * @param val
 * @return
 */
float sigmoid(float val)
{
	return 1/(1+expf(-1*val));
}

/**
 * @fn void matrixSoftmax(matrixItems*)
 * @brief softmax関数
 *
 * @param x1
 */
void matrixSoftmax(matrixItems *x1)
{
	int i,j;

	float max =0;
	float sum =0;


	for(i = 0; i<x1->shape[0]; i++)
	{
		max =x1->values[i*x1->shape[1]];
		for(j = 1; j<x1->shape[1]; j++)
		{
			if(max < x1->values[i*x1->shape[1]+j])
			{
				max = x1->values[i*x1->shape[1]+j];
			}
		}

		sum = 0;
		for(j = 0; j<x1->shape[1]; j++)
		{
			float e =expf(x1->values[i*x1->shape[1]+j]-max);
			x1->values[i*x1->shape[1]+j] = e;
			sum += e;
		}

		for(j = 0; j<x1->shape[1]; j++)
		{
			x1->values[i*x1->shape[1]+j] /= sum;
		}
	}
}


main.c
main.c
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2025 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"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include "myUsart.h"
#include "myTimer.h"
#include "myI2C.h"
#include "mySPI.h"
#include "neuralNetWeight.h"
#include "neuralNet.h"
/* 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 ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);
static void MX_TIM2_Init(void);
static void MX_I2C1_Init(void);
static void MX_SPI2_Init(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 */
	uint32_t delayTime;
	uint32_t portValue;
  /* USER CODE END 1 */

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

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SYSCFG);
  LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);

  /* System interrupt init*/
  NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);

  /* 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_USART2_UART_Init();
  MX_TIM2_Init();
  MX_I2C1_Init();
  MX_SPI2_Init();
  /* USER CODE BEGIN 2 */
  delayTime=500;
  USART_Initialize_Printf();

  //neuralnet XOR start-----------------------------
  printf("*********neural net XOR************ \r");
  matrixPrint(Xtrain.name,Xtrain.values,Xtrain.shape[0],Xtrain.shape[1]);
  matrixPrint(W1.name,W1.values,W1.shape[0],W1.shape[1]);
  matrixPrint(b1.name,b1.values,b1.shape[0],b1.shape[1]);
  matrixPrint(W2.name,W2.values,W2.shape[0],W2.shape[1]);
  matrixPrint(b2.name,b2.values,b2.shape[0],b2.shape[1]);

  printf("----Input Layer-----\n");
  matrixDot(&Xtrain, &W1, &Y1out);
  //matrixPrint(Y1out.name,Y1out.values,Y1out.shape[0],Y1out.shape[1]);
  matrixAdd(&Y1out,&b1,&Y1out);
  matrixPrint(Y1out.name,Y1out.values,Y1out.shape[0],Y1out.shape[1]);
  printf("----Sigmoid-----\n");
  matrixSigmoid(&Y1out,&Y1out);
  matrixPrint(Y1out.name,Y1out.values,Y1out.shape[0],Y1out.shape[1]);
  printf("----hidden Layer-----\n");
  matrixDot(&Y1out, &W2, &Y2out);
  //matrixPrint(Y2out.name,Y2out.values,Y2out.shape[0],Y2out.shape[1]);
  matrixAdd(&Y2out, &b2, &Y2out);
  matrixPrint(Y2out.name,Y2out.values,Y2out.shape[0],Y2out.shape[1]);
  printf("----soft max-----\n");
  matrixSoftmax(&Y2out);
  matrixPrint(Y2out.name,Y2out.values,Y2out.shape[0],Y2out.shape[1]);
  /* USER CODE END 2 */

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

    /* USER CODE BEGIN 3 */
	if(USART2RX.rxCompleted==true)
	{
		  USART2RX.rxCompleted=false;
		  USART2RX.length=0;
		  printf("%s\r",USART2RX.buf);
		  USART2->CR1 |= USART_CR1_RXNEIE;
	}

	if(tm2.completed==true)
	{
		tm2.completed=false;
		LL_GPIO_TogglePin(GPIOA,LL_GPIO_PIN_5);
		LL_TIM_EnableIT_UPDATE(TIM2);
	}
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  LL_FLASH_SetLatency(LL_FLASH_LATENCY_5);
  while(LL_FLASH_GetLatency()!= LL_FLASH_LATENCY_5)
  {
  }
  LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1);
  LL_PWR_EnableOverDriveMode();
  LL_RCC_HSE_Enable();

   /* Wait till HSE is ready */
  while(LL_RCC_HSE_IsReady() != 1)
  {

  }
  LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_4, 180, LL_RCC_PLLP_DIV_2);
  LL_RCC_PLL_Enable();

   /* Wait till PLL is ready */
  while(LL_RCC_PLL_IsReady() != 1)
  {

  }
  while (LL_PWR_IsActiveFlag_VOS() == 0)
  {
  }
  LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
  LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_4);
  LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_2);
  LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);

   /* Wait till System clock is ready */
  while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
  {

  }
  LL_Init1msTick(180000000);
  LL_SetSystemCoreClock(180000000);
  LL_RCC_SetTIMPrescaler(LL_RCC_TIM_PRESCALER_TWICE);
}

/**
  * @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 */

  LL_I2C_InitTypeDef I2C_InitStruct = {0};

  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

  LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB);
  /**I2C1 GPIO Configuration
  PB6   ------> I2C1_SCL
  PB7   ------> I2C1_SDA
  */
  GPIO_InitStruct.Pin = LL_GPIO_PIN_6|LL_GPIO_PIN_7;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
  GPIO_InitStruct.Alternate = LL_GPIO_AF_4;
  LL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /* Peripheral clock enable */
  LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1);

  /* USER CODE BEGIN I2C1_Init 1 */

  /* USER CODE END I2C1_Init 1 */

  /** I2C Initialization
  */
  LL_I2C_DisableOwnAddress2(I2C1);
  LL_I2C_DisableGeneralCall(I2C1);
  LL_I2C_EnableClockStretching(I2C1);
  I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C;
  I2C_InitStruct.ClockSpeed = 100000;
  I2C_InitStruct.DutyCycle = LL_I2C_DUTYCYCLE_2;
  I2C_InitStruct.OwnAddress1 = 0;
  I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK;
  I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT;
  LL_I2C_Init(I2C1, &I2C_InitStruct);
  LL_I2C_SetOwnAddress2(I2C1, 0);
  /* USER CODE BEGIN I2C1_Init 2 */
  //LL_I2C_Enable(I2C1);
  /* USER CODE END I2C1_Init 2 */

}

/**
  * @brief SPI2 Initialization Function
  * @param None
  * @retval None
  */
static void MX_SPI2_Init(void)
{

  /* USER CODE BEGIN SPI2_Init 0 */

  /* USER CODE END SPI2_Init 0 */

  LL_SPI_InitTypeDef SPI_InitStruct = {0};

  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* Peripheral clock enable */
  LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2);

  LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOC);
  LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB);
  /**SPI2 GPIO Configuration
  PC1   ------> SPI2_MOSI
  PC2   ------> SPI2_MISO
  PB10   ------> SPI2_SCK
  */
  GPIO_InitStruct.Pin = LL_GPIO_PIN_1;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
  GPIO_InitStruct.Alternate = LL_GPIO_AF_7;
  LL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = LL_GPIO_PIN_2;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
  GPIO_InitStruct.Alternate = LL_GPIO_AF_5;
  LL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = LL_GPIO_PIN_10;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
  GPIO_InitStruct.Alternate = LL_GPIO_AF_5;
  LL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /* USER CODE BEGIN SPI2_Init 1 */

  /* USER CODE END SPI2_Init 1 */
  /* SPI2 parameter configuration*/
  SPI_InitStruct.TransferDirection = LL_SPI_FULL_DUPLEX;
  SPI_InitStruct.Mode = LL_SPI_MODE_MASTER;
  SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_8BIT;
  SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_LOW;
  SPI_InitStruct.ClockPhase = LL_SPI_PHASE_1EDGE;
  SPI_InitStruct.NSS = LL_SPI_NSS_SOFT;
  SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV32;
  SPI_InitStruct.BitOrder = LL_SPI_MSB_FIRST;
  SPI_InitStruct.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE;
  SPI_InitStruct.CRCPoly = 10;
  LL_SPI_Init(SPI2, &SPI_InitStruct);
  LL_SPI_SetStandard(SPI2, LL_SPI_PROTOCOL_MOTOROLA);
  /* USER CODE BEGIN SPI2_Init 2 */
  LL_SPI_Enable(SPI2);
  /* USER CODE END SPI2_Init 2 */

}

/**
  * @brief TIM2 Initialization Function
  * @param None
  * @retval None
  */
static void MX_TIM2_Init(void)
{

  /* USER CODE BEGIN TIM2_Init 0 */

  /* USER CODE END TIM2_Init 0 */

  LL_TIM_InitTypeDef TIM_InitStruct = {0};

  /* Peripheral clock enable */
  LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2);

  /* TIM2 interrupt Init */
  NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),1, 0));
  NVIC_EnableIRQ(TIM2_IRQn);

  /* USER CODE BEGIN TIM2_Init 1 */

  /* USER CODE END TIM2_Init 1 */
  TIM_InitStruct.Prescaler = 16;
  TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
  TIM_InitStruct.Autoreload = 0x15F9;
  TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
  LL_TIM_Init(TIM2, &TIM_InitStruct);
  LL_TIM_EnableARRPreload(TIM2);
  LL_TIM_SetClockSource(TIM2, LL_TIM_CLOCKSOURCE_INTERNAL);
  LL_TIM_SetTriggerOutput(TIM2, LL_TIM_TRGO_RESET);
  LL_TIM_DisableMasterSlaveMode(TIM2);
  /* USER CODE BEGIN TIM2_Init 2 */
  LL_TIM_EnableCounter(TIM2);
  LL_TIM_EnableIT_UPDATE(TIM2);
  /* USER CODE END TIM2_Init 2 */

}

/**
  * @brief USART2 Initialization Function
  * @param None
  * @retval None
  */
static void MX_USART2_UART_Init(void)
{

  /* USER CODE BEGIN USART2_Init 0 */

  /* USER CODE END USART2_Init 0 */

  LL_USART_InitTypeDef USART_InitStruct = {0};

  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* Peripheral clock enable */
  LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART2);

  LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA);
  /**USART2 GPIO Configuration
  PA2   ------> USART2_TX
  PA3   ------> USART2_RX
  */
  GPIO_InitStruct.Pin = LL_GPIO_PIN_2|LL_GPIO_PIN_3;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
  GPIO_InitStruct.Alternate = LL_GPIO_AF_7;
  LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /* USART2 interrupt Init */
  NVIC_SetPriority(USART2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),1, 0));
  NVIC_EnableIRQ(USART2_IRQn);

  /* USER CODE BEGIN USART2_Init 1 */

  /* USER CODE END USART2_Init 1 */
  USART_InitStruct.BaudRate = 115200;
  USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B;
  USART_InitStruct.StopBits = LL_USART_STOPBITS_1;
  USART_InitStruct.Parity = LL_USART_PARITY_NONE;
  USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX;
  USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;
  USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16;
  LL_USART_Init(USART2, &USART_InitStruct);
  LL_USART_ConfigAsyncMode(USART2);
  LL_USART_Enable(USART2);
  /* USER CODE BEGIN USART2_Init 2 */
  LL_USART_EnableIT_RXNE(USART2);
  /* USER CODE END USART2_Init 2 */

}

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

  /* USER CODE END MX_GPIO_Init_1 */

  /* GPIO Ports Clock Enable */
  LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOC);
  LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOH);
  LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA);
  LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB);

  /**/
  LL_GPIO_ResetOutputPin(GPIOA, LD2_Pin|LL_GPIO_PIN_10);

  /**/
  LL_GPIO_SetOutputPin(GPIOB, LL_GPIO_PIN_5);

  /**/
  LL_SYSCFG_SetEXTISource(LL_SYSCFG_EXTI_PORTC, LL_SYSCFG_EXTI_LINE13);

  /**/
  EXTI_InitStruct.Line_0_31 = LL_EXTI_LINE_13;
  EXTI_InitStruct.LineCommand = ENABLE;
  EXTI_InitStruct.Mode = LL_EXTI_MODE_IT;
  EXTI_InitStruct.Trigger = LL_EXTI_TRIGGER_RISING;
  LL_EXTI_Init(&EXTI_InitStruct);

  /**/
  LL_GPIO_SetPinPull(GPIOC, LL_GPIO_PIN_13, LL_GPIO_PULL_NO);

  /**/
  LL_GPIO_SetPinMode(GPIOC, LL_GPIO_PIN_13, LL_GPIO_MODE_INPUT);

  /**/
  GPIO_InitStruct.Pin = LD2_Pin|LL_GPIO_PIN_10;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
  LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /**/
  GPIO_InitStruct.Pin = LL_GPIO_PIN_5;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
  LL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /* EXTI interrupt init*/
  NVIC_SetPriority(EXTI15_10_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),1, 0));
  NVIC_EnableIRQ(EXTI15_10_IRQn);

  /* 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 */

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?