ししかわです。
社員研修の一環でマイクロマウスを自作します。
記事一覧 – 元Web屋のマイクロマウス製作記 | RT MicroMouse
前回、STM32に光センサを繋いで動かしてみましたが、
センサ値などのデバッグログをPCに出力できないので不便です。
今回はBluePillのUSB端子とPCを接続して、デバッグログをPCに出力できるようにしました。
環境
- STM32 F103 Blue Pill Board
- Ubuntu: 18.04.3 LTS
詳しくは環境構築の記事を参照ください。
STM32とPCをUSBで接続する
STM32とPCで通信する方法は幾つかありますが、
Blue Pill BoardにはmicroUSBの端子が付いているので、今回はUSB経由での接続を試してみます。
以降ではSTM32にUSBデバイスとして振る舞うための設定を加え、仮想COMポートを介したシリアル通信ができるようにします。
CubeMXの設定
- 左メニューの「Connectivity->USB」を選択します
- 「USB Mode and Configuration->Device(FS)」にチェックを入れます
- 左メニューの「Middleware->USB_DEVICE」を選択します
- 「USB_DEVICE Mode and Configuration->Class For FS IP」を「Communication Device Class(Virtual Port Com)」に変更します
- 左メニューの「System Core->RCC」を選択します
- 「RCC Mode and Configuration->High Speed Clock(HSE)」を「Crystal/Ceramic Resonator」に変更します
これで設定できました。「GENERATE CODE」をクリックして雛形を生成します。
生成した雛形には、新たにUSB通信用のミドルウェア(外部プログラム)が含まれているのが確認できます。
通信処理を使う
STM32からPCへ送信するにはCDC_Transmit_FS
関数を使います。
次にコード例を示します。
// main.c /* USER CODE BEGIN 2 */ char cdcBuffer[40]; uint16_t count = 0; /* USER CODE END 2 */ /* USER CODE BEGIN WHILE */ while (1) { sprintf(cdcBuffer, "Count: %d\n\", count++); CDC_Transmit_FS((uint8_t*)cdcBuffer, strlen(cdcBuffer)); HAL_Delay(1000); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ }
次の点に注意しましょう。
- 送信する文字列末尾に改行コード”\n\r”を入れないとターミナルに出力されません
- CDC_Transmit_FSは通信中に他の処理をブロックしません。言い換えると、関数の呼び出し直後はまだ通信が完了していません。
CDC_Transmit_FSを続けて呼ぶと送信は行われず、戻り値に1(= USBD_BUSY)が返ります。
これを防ぐにはコールバックを管理するか、単に送信成功する(USBD_OKが返る)まで処理を繰り返します。
while (1) { sprintf(cdcBuffer, "Count: %d\n\r", count++); while(CDC_Transmit_FS((uint8_t*)cdcBuffer, strlen(cdcBuffer)) == USBD_OK) {} HAL_Delay(1000); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ }
動作確認
- Blue Pillにプログラムを書き込みます
- Blue PillのBootピンを0にしてRESETボタンを押し、プログラムを起動します
- Blue PillとPCをUSBで接続します
- dmesgコマンドを打ってカーネルのログを確認し、Blue Pillのデバイスファイル名を確認します。
次の場合、/dev/ttyACM0
となります。
- dmesgコマンドを打ってカーネルのログを確認し、Blue Pillのデバイスファイル名を確認します。
$ dmesg | tail -n 7 [121717.645332] usb 1-5: new full-speed USB device number 11 using xhci_hcd [121717.794612] usb 1-5: New USB device found, idVendor=0483, idProduct=5740, bcdDevice= 2.00 [121717.794614] usb 1-5: New USB device strings: Mfr=1, Product=2, SerialNumber=3 [121717.794616] usb 1-5: Product: STM32 Virtual ComPort [121717.794617] usb 1-5: Manufacturer: STMicroelectronics [121717.794618] usb 1-5: SerialNumber: 8D83385E5748 [121717.795946] cdc_acm 1-5:1.0: ttyACM0: USB ACM device
- PCからscreenコマンドを打ってボードに接続します
$ screen /dev/ttyACM0 Count: 22 Count: 23 Count: 24 Count: 25 ...
これでログを出力できるようになりました。
なお、プログラムを再度起動するときにCOMポートの接続もリセットされるので、
USBは挿し直す必要があります。
ログやデバッグ、テストの環境などは開発の初期にしっかり作っておくと、
後の開発がずっと楽になります。