STM32CubeIDEを使ってみよう How To STM32CubeIDE 日本語版 (5)  UARTを使ってみよう


STM32CubeIDEを使ってみよう How To STM32CubeIDE 日本語版 (4) スイッチを使ってみようの続きです。

今回は、UARTを使ってみます
UARTとはなんぞや?ということですが、シリアル通信です。
シリアル通信って??
https://thinkit.co.jp/story/2015/04/15/5791
丸投げさせていただきます。
USBも実は、このシリアル通信だったりします。(ユニバーサルシリアルバス)
マイコンなどの通信は、基本このシリアル通信が重要になってきます。

新規プロジェクトを作ります。

私は、Nucleo-UARTというプロジェクトにしました。
プロジェクトを作るといつものピンマップが見えます。

よくよく見るとUARTといのがありますね。

左のツールバーのConnectivityにUART2がチェックされていますね。

開けてみましょう。
ここには、設定情報が入っています。
転送速度など

UARTに割り込みを設定したいのでNVICの設定をします。
NVIC Settingsの「USART2 global interrupt」にはすでにチェックが入っていると思います。

「NVIC Mode and Configuration」の「Configuration」「NVIC}を設定します。
「USART2 global interrupt」の「SubPriority」を1にします。

まずは、指定した文字を自動的に送ってくるコードを書いてみましょう。

char msg[] ="Hello STM32\r\n";
charとは文字列を表します。
\r\nは改行コードです。
msgという文字列にHello STM32を入れる

HAL_UART_Transmit(huart, pData, Size, Timeout)を入力しまs。

HAL_UART_Transmit(&huart2,(uint8_t *)msg,sizeof(msg),3000);
HAL_UART_TransmitはUARTでデータを送るというプログラムです。
カッコの中には、
huart:&huart2
pData:(uint8_t *)msg
Size:sizeof(msg)
(strlenはエラーになります)
Timeout:3000
としました。
&huart2はUART2ですね。
(uint8_t *)8ビットの符号なし整数型です。
後ろにmsgを入れないとエラーになります。
Sizeについては、strlenとしましたが、エラーになるのでsizeofにしています。

これをwhileの中に入れます。
while(1)はループでここに書かれているプログラムを繰り返します。
ここでDelayを入れることで、周期的にプログラムを繰り返しします(入れないと、滅茶苦茶早く動くのお勧めしません)

  /* USER CODE BEGIN 2 */
  char msg[] ="Hello STM32\r\n";
 // HAL_UART_Transmit(&huart2,(uint8_t *)msg,strlen(msg),3000);
  /* USER CODE END 2 */

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

    /* USER CODE BEGIN 3 */
      HAL_UART_Transmit(&huart2,(uint8_t *)msg,sizeof(msg),3000);
      HAL_Delay(1000);
  }
  /* USER CODE END 3 */

プログラムを動かしてみましょう。
動いても何も表示されないですよね?
これを見るには、TeraTermなどのターミナルエミュレーターを使わないといけません。
https://forest.watch.impress.co.jp/library/software/utf8teraterm/

TeraTermを起動し、接続されているシリアルポートを指定して接続します。

スピードは115200です。
これは「転送速度」で指定した内容になります。

きちんと接続できると、こちらのようになります。

次にボタンとLEDとUARTをつなげてみましょう。

STM32CubeIDEを使ってみよう How To STM32CubeIDE 日本語版 (4) スイッチを使ってみようのコードをもとにして
スイッチを押すと、LEDが点灯したり、消灯したりします。
さらに、シリアル通信でボタンが押されたことを通知します。

まずは、msg2を作成しここに送りたいメッセージを入れます。
char msg2[] ="PushButton\r\n";

次に、メッセージを送信するプログラムをif{}の中に書きましょう。

 /* USER CODE BEGIN 2 */
  char msg[] ="Hello STM32\r\n";
  char msg2[] ="PushButton\r\n";
  HAL_UART_Transmit(&huart2,(uint8_t *)msg,sizeof(msg),3000);

  /* USER CODE END 2 */

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

    /* USER CODE BEGIN 3 */
      if(HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin)==0){
          HAL_UART_Transmit(&huart2,(uint8_t *)msg2,sizeof(msg2),3000);
          HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
      }
      HAL_Delay(150);
      LED_State = HAL_GPIO_ReadPin(LD2_GPIO_Port, LD2_Pin);
      B1_State = HAL_GPIO_ReadPin(B1_GPIO_Port,B1_Pin);
  }
  /* USER CODE END 3 */

なぜか、Delayが入っていますね。
これは、先ほどのチャタリング対策です。
試しにこれを入れないプログラムを動かしてみましょう。
一度押しただけなのに、PushButtonが何個も送られていると思います。
チャタリングは、人間が一度押しただけなのを、マイコンは、何回も押したと認識するためによるものであり、
一定時間待つことで回避することが可能です。
ただし、この一定時間は常に待つことになり最低の手法なのでお勧めしません。

UARTを触ってみましたが、これよりも詳しい内容については
STM32でUARTをやってみる6(float型printfをUART経由で出力)などをご覧になってはいかがでしょうか?
http://gsmcustomeffects.hatenablog.com/entry/2017/03/22/124549