しゅうの自作マウス研修

USB入/出力 – しゅうの自作マウス研修 part5

しゅうの自作マウス研修

こんにちは、しゅうです。
今回は、BluePillをUSB経由でパソコンのキーボード入力からLED制御してみたり
ターミナル上にBluePillから文字列を出力してもらいます!

ピン設定

前回のプロジェクトファイルをそのまま使うのも問題ないですが、僕は階層を分けて解説していくことにします。
ということで、1からプロジェクトファイルを作ります。始め方はPart4で解説しています。

USB通信

まず初めに、USB通信を有効化します。Pinout & Configurationタブ内の左側にあるCategories欄のConnectivityを開くとUSBを選択することができます。選択したら、表示される設定画面(中央)のDevice (FS)にチェックマークをつけましょう。するとピンPA12とPA11が有効化されます。

Middleware

次に左側のMiddlewareからUSB_DEVICEを選択して、Class For FS IPをCommunication Device Class (Virtual Port Com)を選択しましょう。ピン設定は特に変わりません。ここで設定したデバイスによって、プロジェクトフォルダに含まれるライブラリなどが変わります。

LED制御用のピン設定

次はPC13をGPIO_Outputに設定します。設定の仕方はPart4でご説明したので割愛します。

System Core

次はCategories欄の上の方にあるSystem Coreを2箇所設定をします。
まず1つ目、RCCを選択してHigh Speed Clock (HSE)をCrystal/Ceramic Resonatorに設定しましょう。すると、ピンPD0-OSC_INとPD1-OSC_OUTがそれぞれRCC_OSC_INとRCC_OSC_OUTに変わります。
次にRCCのすぐ下にあるSYSをクリックしましょう。Debug欄をSerial Wireに設定します。するとピンPA14がSYS_JTCK-SWCLKに設定されます。

その他

ここまでで、全体のピン設定は最終的に次のようになります。

ここで、PC13のデフォルト値を変更します。PC13がHighの時にLEDが消灯するので、電源投入時にLEDが消灯したままでいるように設定します。左側のSystem CoreのGPIOを選択しましょう。真ん中に設定画面が出るので、PC13を選択してGPIO output levelをLowからHighにしましょう。

クロックの設定

今回のピン設定でクロックの設定も合わせると良さそうです。実際には、ピン設定を終えてからそのままプログラムを出力し、書き込んで実行することはできます。ただし、将来的には、割り込み処理を実装する際に重要になってきそうなので簡単ですけど直し方を紹介しておきます。
ひとまず直すだけならとても簡単です。Clock Configurationタブを開くと、警告画面が表示されます。自動でクロック設定を解決するかどうかを聞かれていますので、Yesをクリックしましょう。

いろいろな組み合わせから最適解を探してくるそうです。設定が完了したら、僕の環境では以下のようになりました。

プロジェクトの設定

Part4と同じ様に設定をします。Project Managerタブを開いて、任意のプロジェクト名や保存先を設定しましょう。

コードの生成が完了したら、次はプログラムの編集をしていきます。

プログラムの編集

今回は、Core/Src/main.cではなく、USB_DEVICE/App/usbd_cdc_if.cを編集します。USB通信を行うときは、このソースコード内のCDC_Receive_FSCDC_Transmit_FS関数が鍵になります。今回はCDC_Receive_FS関数の中身に数行コードを追加します。
245行目から259行目あたりのコメントに、CDC_Receive_FS関数の役割や引数が何を指しているかが書かれています。以下のコードを、/* USER CODE BEGIN 6 */以降に追加しましょう。ここでは、キーボード入力からLEDの制御を行います。HAL_GPIO_WritePin関数を使います。
1を入力するとLEDが点灯し、0を入力するとLEDが消灯するようにしています。また、if文のなかでCDC_Transmit_FS関数を使って、Blue Pillから文字列を出力してもらいます。data変数に文字列を格納して、それを引数として送っています。この時、改行コードとして\n\rを使わないと良い具合にターミナルに表示されません。(参考記事はこちら

  if(Buf[0] == '1'){
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, 0);
    char data[] = "PC13 LED ON!\n\r";
    CDC_Transmit_FS((uint8_t*)data, strlen(data));
  }else if(Buf[0] == '0'){
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, 1);
    char data[] = "PC13 LED OFF!\n\r";
    CDC_Transmit_FS((uint8_t*)data, strlen(data));  
  }

今回使っている関数は、Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio.cにて定義されています。Part4で使ったHAL_GPIO_TogglePin関数もその中で定義されています。
このSrcフォルダーには他にもADCやI2C用の関数も定義されているので、じっくりと読みがいがありそうですね。

ビルドと書き込み

あとはビルドして書き込みます。詳しくはPart4を参照してください。
今回のように新しくプロジェクトファイルを作成した人は、前回のディレクトリからopenocd.cfgファイルをコピーしてくるのを忘れないようにしましょう。また、書き込みコマンドを実行時は、適切な.elfファイルを指定しましょう。今回の僕の環境では次のようになります。

openocd -f ./openocd.cfg -c "flash_elf build/test_USB.elf"

プログラムの実行

ジャンパピンを戻したらリセットボタンを押しましょう。その後、microUSBケーブルを使ってBlue PillをPCに接続します。ST-Link V2は接続したままでも問題ないです。
この時、USBケーブルを接続したままリセットボタンを押すと、どうやらUSB接続もリセットされちゃうのでケーブルを挿し直す必要があります。
ターミナルに表示するためにscreenコマンドを使います。そのためには、PCがBlue Pillを何というデバイス名で認識しているかを調べる必要があります。
接続したデバイスは/dev/という階層に表示されており、USBデバイスは大抵tty.usb-??というような名前になります。ですが、今回の僕の環境ではそうではなく、cu.usbmodem??というデバイス名で認識されていました。(ちなみにUbuntu18.04に接続したらttyACM0と表示されました)この、ttyとcuの違いについてはまた別の時に調べてお話ししようと思います。
デバイス名がわかったので、次のコマンドを実行しましょう。デバイス名は同じかもしれませんが、それぞれの環境で確認しましょう。

screen /dev/cu.usbmodem6D76267A55551

最初は何も表示されませんが、1か0を入力すると、それに対応した文字列とLED制御が行われます。

終了するには、Ctrl+aを押して、k、yと順番に押しましょう。

まとめ

以上、USB経由で入力と出力を行うことができました。
次回以降はセンサやモータを扱っていこうと思いますが、その前にそろそろマイコンを決めちゃいたいと思います。
次回はマイコン選定などの紹介から始めます!

タイトルとURLをコピーしました