マイクロマウス研修(のり) マウス自作研修

マイクロマウス研修(のり)[31]STM32F446 STEP2 UART通信&printf関数

マイクロマウス研修(のり)

記事一覧 のり マイクロマウス研修

LEDとスイッチの確認ができたので、次はSTEP2 UART通信&printf関数になります。UART通信は前回やりましたが、printf関数を使えるようにします。

既に先達が出しているので、それを行います。

printf - しゅうの自作マウス研修 part9
こんにちは、しゅうです。 今日は結構短いです! 今まで、HAL_UART_Transmit関数を使っていましたが、それをおなじみprintf関数で行うことができるのでご紹介します。 変数ごとにしか表示できなかったり、引数が多かった...
ショウのマイクロマウス制作-Part5
前回はNucleoボードを使ってLチカをするところまで進みました。今回はシリアル通信を使ってNucleoボードとPCの通信の準備と、STM32G4に用意されているFPUの機能を使えるようにします。
マイクロマウス研修(kora編)[23] STM32マイコンでシリアル通信
こんにちは。koraです。 今回はシリアル通信を使ってマイコンからPCにデータを送れるようにしたいと思います。 HALを使ったシリアル通信 HAL_UART_Transmit()関数を使用します。第一引数がUARTハンドル、第...
STM32+HALのUSARTでprintf(float),scanf, CMSISを有効可 | Sora's Activity Record
STM32マイコンのペリフェラル関連記事を一覧にまとめました。 stm32 + makefileでのprintf,scanf,CMSIS(FPU)の設定の仕方をやっていきたいと思い...

回路図

回路図を見て、どのポートを使っているかを見直します。Tx(送信ポート)はPC10、Rx(受信ポート)はPC11にしています。

STM32CubeMX

CubeMXで設定を行います。不具合が起こったときの切り分けのため、前回のプロジェクトに追加・編集せず、新規でプロジェクトを作成していきます。

最初に、Pinout viewのPC10とPC11のピンを、左クリックでそれぞれUSART3_RXとUSART3_TXを設定してから、UART3 Mode and ConfigurationでAsynchronous(非同期)を選択します。

USART3は他のピンにも割り振ることができるため、別のところが選択されることがあります。予めピンを直接設定してあげると、やり直す手間が減ります。

通信速度の設定を行うので、Parameter Settingsタブをクリックして、Baud Rateを入力します。デフォルトでは115200 Bits/sになっていますが。端末エミュレータのTera Termで簡単に設定できる上限である最大ボーレート921600 Bits/sにします。

ただし、そのままだとエラー率が+2.12%になるぞとワーニングが出てきます。CPUや周辺回路の通信速度がデフォルトだと遅すぎるため、そちらも編集します。ここはSTEP1と同じように設定します。

UARTに関わるクロックは、「USARTクロック(FCK)は、いくつかの供給源から選択することができる:システムクロック、ペリフェラルクロック(APBクロック)、HSI 16 MHzクロック、LSE 32.768kHzクロック。 」とのこと。

APB peripheral clocksはAPB1とAPB2の2つあるのですが、データシートのBlock Diagramを見ると、APB1の方が接続されているようです。

プログラム

最初に、stdio.hをmain.cにインクルードします。

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
/* USER CODE END Includes */

UART通信を標準出力に設定することができるように__io_putcharと__io_getcharという関数を定義します。鉄鼠はUSART3にしているので、HAL関数内の引数も変更しています。

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
int __io_putchar(int ch) {
    HAL_UART_Transmit(&huart3, (uint8_t *)&ch, 1, 100);
    return ch;
}
int __io_getchar(int ch) {
	HAL_StatusTypeDef Status = HAL_BUSY;
	uint8_t Data;

	while(Status != HAL_OK)
	Status = HAL_UART_Receive(&huart3, &Data, 1, 10);

	return(Data);
}
/* USER CODE END 0 */

setbuf関数でバッファのリセットをします。あと、変数も用意。

  /* USER CODE BEGIN 2 */
  setbuf(stdout, NULL);
  setbuf(stdin, NULL );
  printf("Started!\n\r");
  int32_t val = 0;
  float a = 0.0;
  /* USER CODE END 2 */

ループ内に、printf関数とscanf関数、演算を入れます。

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  printf("Input integer val = ");
	  scanf("%d", &val);
	  printf("%d\n\r", val);

	  printf("Input float a = ");
	  scanf("%f", &a);
	  printf("%f\n\r", a);

	  val = val * val;
	  a = a * a;

	  printf("val^2 = %d, a^2 = %f\n\r", val, a);
    /* USER CODE END WHILE */

これでRunを押すと、Floatのフォーマットサポートに問題があると注意されて、チェックを入れるよう指示をされます。

実際にTera Termで入力してみると、Integerであるvalの入力はうまくいきますが、floatのaの入力で暴走します。

なので、Propertiesで下記のようにチェックを入れて、printfとscanfでfloatを使えるようにします。

実行

実行すると、出力と入力の両方ができるようになりました。

次は、ADCの動作確認を行います。

タイトルとURLをコピーしました