STM32 USBのVCPで通信してみる

  • 2021.03.12
  • HAL
STM32 USBのVCPで通信してみる

今回はUSBのVPCを使ってパソコンと通信してみました。

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

( IDE & MX バージョンアップしました )

PC:Windows10 OS
IDE: STM32CubeIDE Version1.6.0
Configurator: STM32CubeMX Version6.2.0
Board: STM32Nucleo-F401RE

VCPとは

VCPとは Virtual COM Port (仮想COMポート)の略です。

マイコンボード等のUSBコネクタからUSBケーブルでパソコンとつなぎ、パソコンはCOMポートを選択して仮想的にRS232C等のシリアル通信を行う場合のCOMポートだと私は理解しています。

下図はマイコンペリフェラルのUARTを使い、USB-シリアル変換して VCP通信するブロック図です。

今回はマイコンペリフェラルにUSB-DEVICEを使うことで、USB-シリアル変換を省略してVCP通信を行います。
ブロック図は以下の通りです。
ハードウェア的なコストが下がるので魅力的ですね。

USBのコネクタ

上記NucleoボードにはUSBコネクタがないので、以下のものを準備してNucleoボードと接続しました。

USBコネクタ

接続を確認する

USBコネクタとNucleoボードは以下のとおりに接続します。

プロジェクトを作成する

IDEを起動し、File- New – STM32 Project を選択し、Target Selection ウィンドウが出たら Board Selector タブを選択し Boards List から NUCLEO-F401RE を選択し Next ボタンを押します。

Project 名に F401UsbVcp と入力し、Finishボタンを押します。
Initialize all peripherals with their default Mode ? と聞いてくるので Yesを押します。
This kind of project is associated with the STM32CubeMx perspective. Do you want to open this perspective now ? と聞いてくるので Yesを押します。

USBの設定を行う

Pinout & Configuration – Categories – Connectivity から USB OTG FS を選択し Mode で Device_Only を選択します。
GPIO Settings では PA11, PA12 が選択されていることを確認しておきます。

次に Categories – Middleware から USB DEVICE を選択し Mode – Class for FS IP で Communication Device Class (Virtual Port Com) を選択します。

VPC になっていますね 笑

クロックの設定

USBは48MHzのそこそこ精度の良いクロックを必要とするようです。

Clock Configuration でクロックを下図のとおりに設定します。
この設定を行わないと警告が出ます。

よく見えないので、2つに分割してみます。

左半分

右半分

この後ビルドしてエラーがないことを確認しておきます。

コーディングする

Project EXplorer – F401UsbVcp の下に USB_DEVICE フォルダが追加されています。

App の下の usbd_cdc_if.c をダブルクリックして開きます。

262行目あたりに CDC_Receive_RS()という関数があるので以下のようにコード( if()の近辺 )を追加します。

static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{
  /* USER CODE BEGIN 6 */
  USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
  USBD_CDC_ReceivePacket(&hUsbDeviceFS);

  uint8_t sendBuf[64];

  if (*Len && *Len < 64)
  {
    for (int i = 0; i < *Len; i++)
    {
      sendBuf[i] = Buf[i];
    }
    CDC_Transmit_FS(sendBuf, *Len);
  }

  return (USBD_OK);
  /* USER CODE END 6 */
}

ビルドしてエラーがないことを確認し

Run - Debug - Resume でプログラムを動作させておきます。

環境をつくる

増設したUSBコネクタにUSBケーブルを挿し、パソコンとつなぎます。

パソコン側はいつものように Tera Term を起動します。

新しい接続 ウィンドウでシリアルを選択すると STLink Virtual COM Port以外にもうひとつUSBシリアルデバイスが見つかるので、そちらを選択します。

設定 - 端末 でローカルエコーにチェックを入れます。

通信パラメーターの設定は不要です。

相手のマイコン側がUARTではないので、なんとなくうなずけますね。

何かキーを押して、ボードからそのままその値が返ってくれば成功です。

コードの概要説明

説明というほどのものではありませんけれど、

たどっていくと CDC_Receive_FS() は割り込みサービスルーチンから呼ばれていることがわかります。

ですから、この中の処理は簡潔にかかなければなりません。

*Lenに値が入っていれば、*Bufからデータを取り出せばよいことになります。

CDC_Transmit_FS() で受信した電文をそのまま返しています。

いかがでしたか?

あのUSB通信が、ほとんど設定だけで動いてしまったので楽チンできました。

HALカテゴリの最新記事