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

マイクロマウス研修(のり)[20]STM32F446UART通信

マイクロマウス研修(のり)[20]STM32F446UART通信 マイクロマウス研修(のり)

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

前回、STM32F446をUSART3経由とUSB経由で書込みができました。回路的には問題なさそうです。

今回は、パソコン↔STM32F446間でUART通信を行います。

UARTの設定

前回、STM32F446 CubeMXセットUSART3の設定を行いました。
その続きとなります。

プロジェクトコピー

STM32CubeIDEで新たにプロジェクトを作成しますが、毎回STM32CubeMXの設定をするのは面倒なので、前回作ったLED_Blinkをもとにコピー&ペーストしてきます。
STM32CubeIDE_prjcp1
STM32CubeIDE_prjcp2

Project nameの変更をします。
Project nameの変更

各種設定が入っているiocファイルもRenameします。
iocファイルのRename

Uartと入力してOKを押す。
Uartと入力してOKを押す

次は、デバッグファイルの削除を行います。makefileに前回のプロジェクトの設定が残っているようです。
デバッグファイルの削除

最後に、Clean Projectを押して、
Clean Project

Run Uart Debugをすれば(Configurationsは再設定することになる)、無事ST-LINK経由で書込みができます。

これでプロジェクトのコピーは完了です。

周波数の再設定

周波数の設定を前回やりましたが、よくよく見返すと外付けの共振子に切り替えていなかったので、各種マイコン周辺機能を最大性能で使えるようにしてみます。

Uart.iocのClock Configurationタブを開きます。
Uart.iocのClock Configurationタブ

STM32F446はCPU周波数を最大180MHzまで行けるようなので、PLL(Phase Locked Loop:位相同期ループ)を色々変更してみました。STM32は細かい調整ができて便利です。
最大で使おうとすると、USB部分で赤い設定不可のところが出てきました。
USB部分で赤い設定不可のところ

USBを使う場合は、48MHzにする必要があるため、若干調周波数を落としてみました。若干調周波数を落とす

とりあえず、この設定で進めてみます。

UARTの設定

STM32CubeMXのUSART3→Configuration→Parameter Settingsで、ボーレート等が変更できます。今回はデフォルトのままにします。
Parameter Settings

これで保存を押すと、ソースコードが自動生成されます。
保存を押すと、ソースコードが自動生成される

main.cをみてみます。MX_USART3_UART_Init()関数が生成されており、ボーレート等も入力済みです。上のコメント書式を見ると、Doxygenに対応しているようですね。
MX_USART3_UART_Init()関数

Doxygen

試しにDoxygenで表示してみます。
GUIとグラフィカル表示オプションもついでにインストール。

$ sudo apt-get install doxygen doxygen-gui graphviz

Doxygenウィザードを起動します。

$ doxywizard

各種設定をして、
設定

HTML出力して、ファイルを開くと、こんな感じで表示されました。
main.c は特に何かしてるわけでもないので、中身は説明が書いてあるくらい。
HTML出力

プログラム

HALドキュメントを見ると3つの操作モードのAPIが用意されているようです。

  1. Polling mode IO operation(順次処理モード)
  2. Interrupt mode IO operation(割り込みモード)
  3. DMA mode IO operation(DMAモード)

送信プログラム

簡単そうな、Polling mode IO operationのHAL_UART_Transmit関数を試しに使ってみます。
HAL_UART_Transmit関数

この関数を使う場合、以下のファイルを使うはずなので、どうなってるか見てみました。

  • stm32f4xx_hal_uart.c
  • stm32f4xx_hal_uart.h

そうすると、以下のようにincludeされていました。
main.h

/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal.h"

stm32f4xx_hal.h

/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal_conf.h"

stm32f4xx_hal_conf.h

#define HAL_UART_MODULE_ENABLED  //コメント外れて有効化
#ifdef HAL_UART_MODULE_ENABLED
 #include "stm32f4xx_hal_uart.h"
#endif /* HAL_UART_MODULE_ENABLED */

抽象化されててわかりづらいですが、便利に使えるようにしてあるみたいです。

関数内部の引数ですが、1つ目は既に自動でコード生成されています。
main.c

UART_HandleTypeDef huart3;

main.cに以下を追加して、実行する。

/* USER CODE BEGIN 2 */
  char databuff[] = "Hello World!\r\n";
  HAL_UART_Transmit(&huart3, (uint8_t *)databuff, sizeof(databuff), 100);
/* USER CODE END 2 */

端末でシリアル接続を行ってみる。

$ sudo screen /dev/ttyUSB0 115200

リセットボタンを押すと、1度だけHello Word!が表示される。
Hello Word!

ctrl+a,k,yでscreen終了。

受信プログラム

送信関数と対を成す、HAL_UART_Receive関数が用意されています。
HAL_UART_Receive関数

HAL_StatusTypeDefという構造体で定義された関数のリターン値を使って、PCから受信したかどうかを判断するようです。データシートを参照します。
データシート
HAL_OKでいいようです。

割り込みを使わない受信は、while文の中にいれるので、

  /* USER CODE BEGIN 2 */
  char databuff1[] = "Hello World!\r\n";
  char databuff2[1];
  HAL_UART_Transmit(&huart3, (uint8_t *)databuff1, sizeof(databuff1), 100);
  /* USER CODE END 2 */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	 if(HAL_UART_Receive(&huart3, (uint8_t *)databuff2, sizeof(databuff2), 10) == HAL_OK){
		 HAL_UART_Transmit(&huart3, (uint8_t *)databuff2, sizeof(databuff2), 100);
	 }
  }
  /* USER CODE END 3 */

実行すると、シリアルターミナル画面はキーボード入力を返信するようになります。
シリアルターミナル画面

次は、USB通信を行います。

参考サイト:
Linuxにおけるシリアルポートのトラブルシューティング
Doxygen マニュアル
STM32でシリアル通信してみる ポーリング編

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