Skip to content

2. UART(Serial通信)とツールの使い方

目標

  • STM32CubeIDEにおけるプロジェクト作成時の定形作業をできるようになる
  • プロジェクトの作成からWrapperの作成までを定形作業とする
  • HALライブラリの規則を知る
  • UARTを使えるようになる

プロジェクト作成

  1. メニューバーから File/New/STM32 Project を選択する

    データのダウンロードが自動で行われることがある

  2. マイコンの選択を行う
    1. Commercial Part Numberに "F446RE"と入力する
    2. STM32F446RET6を選択する
    3. 次へ進む
  3. Project Nameを入力する

    プロジェクト名は自分で分かれば何でも良いです. 特にこだわりがないならUARTとしておきましょう.

  4. Targeted Languagec++にする

マイコンの設定(CubeMX)

  1. conecctibityからUSART2を選択する
  2. ModeをAsynchronousに設定する
  3. Baud Rate115200に設定する
  4. マイコンのPA2, PA3がUART機能に割り当てられていることを確認する

  5. 写真を参考にチェックを入れる

    このチェックを入れることを前提としてライブラリの作成等をしているので,忘れないようにしましょう. マイコンの設定は<Project Name>.iocのように拡張子がiocのファイルに保存されている.このファイルを開くとマイコンの設定の画面が開く.

プログラミング

wrapper.hppmain.cは同じ内容なので,次回以降の資料では省略する.

Wrapperファイルの作成

本環境ではmain関数がmain.c(C言語)に作成されるため,c++の機能を使用するためにWrapperを作成する必要がある. 1. Core/Incwrapper.hppを作る 2. Core/Srcwrapper.cppを作る

wrapper.hpp

c++とc言語を繋ぐための関数のプロトタイプ宣言をしている.extern "C" {}で囲われた関数は内部的にc言語と同様に定義されるため,C言語のファイルから呼び出すことが可能である.基本的には,必要な機能はどのようなプロジェクトでも同じであるため,ファイルの中身はコピーして使いまわすことが多い.

wrapper.cpp

Arduino環境でソースコードを書くときと同様にコードを書くファイルである.

HALライブラリの解説

命名規則

STMマイコンのプログラムで使用する関数群のことを"HALライブラリ(HAL)"と呼ぶ.関数の命名規則は一貫して以下に従っている.

HAL_<periferal name>_<behavior>(<periferal handler>,...);

''はUARTGPIOなどのマイコンの機能の名前である.
<behaviot>はどのような動作をするかを示している.例えば,通信で受信をするときにはReceiveのようになる. <behaviot>は複数のアンダーバーで区切られていることがある.

HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout)

UARTでデータを送信するための関数である.pDataには送信したい配列の先頭アドレスを渡す.Sizeは送信データの長さ(byte)である. Timeoutで指定した時間(ms)だけ通信が終了しなかった場合に関数を終了する.Timeoutは通信処理が上手くいかないときに処理全体がフリーズすることを防ぐためにある. huartにはペリフェラルのハンドラーのポインターを渡す.コード生成の時点でuart1であればhuart1のように自動で宣言されている.

期待する動作

本プログラムはシリアルモニタに接続した状態で起動することを想定している.
起動時にHello Worldと表示され,その後,count:<number>と表示されがカウントアップされていく.

サンプルコード

wrapper.hpp

#ifndef INC_WRAPPER_HPP_
#define INC_WRAPPER_HPP_

#ifdef __cplusplus
extern "C" {
#endif

void init(void);
void loop(void);

#ifdef __cplusplus
};
#endif

#endif /* INC_WRAPPER_HPP_ */

wrapper.cpp

#include "wrapper.hpp"

#include "usart.h"
#include <string>


void init(){
    uint8_t str[] = "Hello World";
    HAL_UART_Transmit(&huart2, str,11,100);
}

void loop(){
  HAL_Delay(100);
    static uint16_t count = 0;
    std::string str = "count:"+std::to_string(count++)+"\n";
    HAL_UART_Transmit(&huart2, (uint8_t *)str.c_str(),str.length(),100);
}

main.c

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "wrapper.hpp"
/* USER CODE END Includes */
  /* USER CODE BEGIN 2 */
  init();
  /* USER CODE END 2 */

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

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */

Reference

Sample code