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?

Nucleo-F446RE 2.USART2

Last updated at Posted at 2025-12-09

USARTの送信と受信/printf文の設定

CUBE MXのコード生成の設定は、LL(Low Layer Library)でおこなっています。

IMG_5467.JPG

コネクタ 番号 名称
CN10 35 RA2 USART2 TX
CN10 36 RA3 USART2 RX

USART2は、STLINKに配線されているので、別途配線する必要はなし。USB経由で、通信する。

printf文を使うためにすること

syscalls.cのなかにある
extern int __io_putchar(int ch) attribute((weak));
自分のファイルで、同名で関数を記述する。weakアトリビュートなので、上書き優先。F446REのレジスタで動く内容を記述しておく。printf文が、文字列を作成した後、その文字列を出力するために使用する関数。

printfの下層インターフェース関数の作りこみ
void putch(USART_TypeDef *_USARTx, uint8_t ch)
{
	if((_USARTx->SR & USART_SR_TXE)==USART_SR_TXE)
	{
		_USARTx->DR = ch;
		while((_USARTx->SR&USART_SR_TXE)==0);
	}
}

int __io_putchar(int ch)//<-printfが最終的に読み出す
{
	putch(USART2,ch);
	return 0;
}

それと同時に、標準入出力のバッファを無効化しておく。ここは、C99コンパイラの機構の問題。

setbuf(stdout,NULL);//Printfのバッファ無効化

この一文がないと、出力されない。
これで、STM32で、printf文を使用できるようになります。

USARTの受信割り込み許可。

USARTの受信割り込み許可は、NVICと、USARTの両方に許可ビットがある。NVICは、MXが自動生成して、Enableになっているが、USARTのCR1レジスタRXNEIEは、ユーザーがセットしなければならない。
ここに気づくのに時間がかかった。
LL_USART_EnableIT_RXNE(USART2);で実行。

USARTのコード

peripheral.h
#ifndef INC_PERIPHERAL_H_
#define INC_PERIPHERAL_H_

#include "main.h"
#include <stdio.h>
#include <stdbool.h>


//USART---------------------------------------------
#define USART_RX_BUFFER_LENGTH_MAX 30
typedef struct
{
	uint8_t buf[USART_RX_BUFFER_LENGTH_MAX];
	uint32_t length;
	bool rxCompleted;
}_usartRXdata;

extern _usartRXdata USART2RX;
extern void putch(USART_TypeDef *_USARTx, uint8_t ch);
extern void USART_SendData(USART_TypeDef *_USARTx, uint8_t *buf, uint8_t _len);
extern void USART_Initialize_Printf(void);
#endif /* INC_PERIPHERAL_H_ */
peripheral.c
#include "peripheral.h"

//USART----------------------------------------------------------------------
_usartRXdata USART2RX;

/**
 * @brief 一文字出力
 * @param USART_TypeDef
 * @param ch
 */
void putch(USART_TypeDef *_USARTx, uint8_t ch)
{
	if((_USARTx->SR & USART_SR_TXE)==USART_SR_TXE)
	{
		_USARTx->DR = ch;
		while((_USARTx->SR&USART_SR_TXE)==0);
	}
}

/**
 * @breif 多文字出力
 * @param USART_TypeDef
 * @param *buf 出力バッファ
 * @param _len 長さ
 */
void USART_SendData(USART_TypeDef *_USARTx, uint8_t *buf, uint8_t _len)
{
	uint8_t i;

	i=0;
	do{
		 _USARTx->DR=buf[i++];
		 while((_USARTx->SR&USART_SR_TXE)==0);
		_len--;
	}while(_len);
}

/*
 * printf文がバッファを使用しないように設定する関数。
 * printf文を使う前に、一回実行する。
 */
void USART_Initialize_Printf()
{
	setbuf(stdout,NULL);//Printfのバッファ無効化
}

/*
 * @brief printf文の下層処理用関数
 */
int __io_putchar(int ch)
{
	putch(USART2,ch);
	return 0;
}

割り込み処理

stm32fxx_it.c
/**
  * @brief This function handles USART2 global interrupt.
  */
void USART2_IRQHandler(void)
{
  /* USER CODE BEGIN USART2_IRQn 0 */

  /* USER CODE END USART2_IRQn 0 */
  /* USER CODE BEGIN USART2_IRQn 1 */
  uint8_t ch;
  if((USART2->SR&USART_SR_RXNE)==USART_SR_RXNE)
  {
	  ch=USART2->DR;
	  USART2RX.buf[USART2RX.length]=ch;
	  USART2RX.length++;
	  if(ch=='\n')
	  {
		  USART2RX.rxCompleted=true;
		  USART2RX.buf[USART2RX.length-2]=0x00;
		  USART2->CR1^=USART_CR1_RXNEIE;
          //実処理は、mainで行う。
	  }
  }
  /* USER CODE END USART2_IRQn 1 */
}
USART初期化(MX生成コード)
※最後のユーザーコードのところで、受信割り込み許可RXNEIESETする。
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 */

}
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?