STM32 ゼロから始めるローパワーマイコン USBシリアル通信してみる 後編

STM32 ゼロから始めるローパワーマイコン USBシリアル通信してみる 後編

皆さま こんにちは。

今回はUSBシリアル変換モジュールを使った通信の後編です。

投稿時の開発環境を記しておきます。

PC:Windows10 OS
IDE: STM32CubeIDE Version1.3.0
Configurator: STM32CubeMX Version5.6.0
マイコン: STM32L010F4P6
Board: 自作のボード

IDEで新規にプロジェクトを作成する

IDEを起動し File – New – STM32 Project を選択します。

( 一番最初の起動時には、ファームウェアのダウンロードで時間がかかることがあります。)

Target Selection のウィンドウが出ます。

Part Number Search のコンボボックス(下図の赤枠部分)に STM32L010F4 と入力します。

そうすると MPUs/MCUs List に STM32L010F4 (下図の2重線部分)が出てくるので、クリックして Nextボタンを押します。

Project Name を入力するウィンドが出るので、ここでは STM32L-UART と入力し、Optionのところはさわらずに Finishボタンを押します。

This kind of project is associated with the STM32CubeMx perspective. Do you want to open this perspective now ? と聞いてくるので Yesを押します。

これは平たく言うと STM32CubeMX を IDE に関連づけして開きますか? という内容です。
初期化コード生成ツールを STM32CubeIDE に統合して使えるようなイメージになります。

コンフィグレーションする

コンフィグレーションは設定などの意味で、STM32CubeIDEはGUIを使ってI/Oの初期化処理を指示することができるようになっています。

I/Oピンを設定する

Pin & Configuration でマイコンの端子をクリックしてリストから機能を選択します。

以下の通りに設定します。

PA2と3は通信用に以下の機能を割り当てます。

PA2 : USART2_TX
PA3 : USART2_RX

もう少し設定が必要なので、端子が黄色になっています。

USARTを設定する

Pinout & Configuration – Categories – Connectivity – USART2 を選択し、Mode から Asynchronous を選択します。

そうするとPA2,3の端子が黄色から緑色にかわり設定が有効になったことを教えてくれます。

後でパソコン側の設定が必要になりますので、以下のパラメーターについて確認しておきます。

初期値を、そのまま使いましょう。

Baud Rate : 115200 Bits/s
Word Length : 8 Bits
Parity : None
Stop Bits : 1

ビルドする

それでは、ここで一度ビルドしてエラーがないことを確認しておきましょう。

Project – Build All を選択します。

Do you want generate Code ? (コードをつくりますか?)

と聞いてくるので Yes を選択します。

下の Console ウィンドウでエラーがないことを確認します。

09:46:37 Build Finished. 0 errors, 0 warnings. (took 3s.837ms)

パソコン側の設定

パソコン側は Tera Term というソフトを使いますので、ネットで検索、ダウンロードしておきます。

Tera Term を起動し、新しい接続のウィンドウが出たら、ラジオボタンで「シリアル」を選択し、ポートから選択します。

もしポートのリストに複数のポートが出てきたら、USBシリアルのUSBケーブルを抜き差ししたリストを比べて、増えたポートを選択します。

設定 – シリアルポート からパラメータを設定します。
内容はマイコン側で設定したものに合わせておく必要があります。

もうひとつ 設定 – 端末 画面でローカルエコーにチェックを入れておきます。

これでキーを押すと、その文字を送り画面に表示します。

コーディングする

それでは通信部分のプログラムを実装してみましょう。

Project EXplorer – Core – Src – main.c をダブルクリックして開きます。

まずmain()の先頭に変数の定義を行います。


int main(void)
{
  /* USER CODE BEGIN 1 */
  uint8_t buffer[256];
  HAL_StatusTypeDef s;
  /* USER CODE END 1 */

次に while()ループの部分を以下のように記述してください。


  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
    s = HAL_UART_Receive(&huart2, buffer, 1, 3000);
    if (s == HAL_TIMEOUT)
    {
      HAL_UART_Transmit(&huart2, "UART Timeout.\r\n", 15, 10);
    }
    else if (s == HAL_OK)
    {
      HAL_UART_Transmit(&huart2, buffer, 1, 10);
    }
  }
  /* USER CODE END 3 */

コーディングが終わったらビルドしてエラーがないことを確認してください。

プログラムの概要

パソコン側で何かキーを押します。

s = HAL_UART_Receive(&huart2, buffer, 1, 3000); で受信を開始します。

HAL_UART系 関数の詳細は HALのマニュアルを参照してください。

STM32L0系のHALマニュアルは こちら からダウンロードできます。

HAL_UART_Receive()

第1引数:UARTの構造体へのポインタを指定します。
huart2 は MX_USART2_UART_Init() で使っている構造体の変数です。

第2引数:uint8_t型のバッファへのポインタを指定します。
第3引数:受信データのサイズを指定します。練習なので1バイトにしています。
第4引数:タイムアウト値を指定します。単位はmsecです。
戻り値:HAL_StatusTypeDef型の値が返ってきます。

1バイトのデータを受信するか、タイムアウトすると関数から戻ってきます。
ここではタイムアウト値を3秒にしています。

タイムアウトした場合は “UART Timeout.\r\n” を送り返します。
何か受信した場合には、受信した値をそのまま HAL_UART_Transmit() で送信します。

HAL_UART_Transmit()

第1引数:UARTの構造体へのポインタを指定します。
第2引数:uint8_t型のバッファへのポインタを指定します。
第3引数:送信データのサイズを指定します。
第4引数:タイムアウト値を指定します。単位はmsecです。
戻り値:HAL_StatusTypeDef型が返ります。

通信時間の見積

ここで通信時間がどのくらいかかるのか見積もってみます。
UARTによる通信方式は調歩同期式と言われていてフォーマットは以下の図のようになっています。
先頭のS : スタートビット
D0-7 : データビット(7ビットの場合はD0-6までになります)
P : パリティビット
ST : ストップビット

データ長を8ビットに設定しているのでパリティを含めると1バイトのデータは11ビットになりますが、今回はパリティなしなので10ビットです。

タイムアウトの場合に送るデータは15バイトです。
通信速度の単位は bps で、ビットパーセカンドの略です。これは1秒間に送るビット数を表しています。
ですから1ビットあたりの時間は逆数をとればよいので 1/115200 [sec]となります。

15バイトのデータを送る通信時間は(1/115200)×10×15=約1.3[msec] になります。

送信する際の HAL_UART_Transmit() のタイムアウト値 10 は 1.3msec に比べて充分大きいので、そこそこ妥当な値でしょう。
通信時間よりタイムアウト値が小さいと全てのデータを送れないことになるので HAL_UART_Transmit() を使う場合には通信時間を見積もっておくと良いでしょう。

プログラムを動かしてみる

それでは Run – Resume してプログラムを動かしてみましょう。

パソコンから何かキーを押して送信し、その文字がパソコンに返ってくれば成功です。

いかがでしたか?
うまく通信できたでしょうか?

お疲れさまでした。

LowPowerカテゴリの最新記事