サンプルプログラム F4xxxx_CDC の説明
マスコット
  USBのCDCクラス
 (The Communication Device Class)を使用して、
 VCP(仮想COMポート)による、
 非同期シリアル通信を行うプログラムです。

  F4xxxx は、
  F405RG, F405VG, F446RE のいずれかです。

  それぞれの種類に応じて、F4xxxx の部分を読み代えてください。
  プログラムの内容は共通です。

  サンプルプログラムの動作を確認するために
 えがおのでんし製の評価用基板 Base-F4xxxx
 STMicroelectronics社のfreeの開発ツール、
 STM32CubeIDE を使用しています。



目次

概要

えがおのでんし製の評価用基板 Base-F4xxxx の説明
 1. Base-F405RG基板 の説明
 2. Base-F405VG基板 の説明
 3. Base-F446RE基板 の説明

サンプルプログラム F4xxxx_CDC のプロジェクト
 1. サンプルプログラム F405RG_CDC のプロジェクト
 2. サンプルプログラム F405VG_CDC のプロジェクト
 3. サンプルプログラム F446RE_CDC のプロジェクト

 既存のプロジェクトを開く


PCとのUSB接続
 1, Base-F405RG基板のUSB接続
 2, Base-F405VG基板のUSB接続
 3, Base-F446RE基板のUSB接続


サンプルプログラム F4xxxx_CDC の説明
 F4xxxx_CDC の構成

 F4xxxx_CDC の動作パラメータの定義
 ユーザープログラムの実行開始位置

 F4xxxx_CDC のmain()の説明
  1) 初期化の部分
  2) LED点滅 と CDC通信処理 の部分

 CDC通信処理 Communication_CDC の説明

 モジュール Execute_Command_LED について

VCPドライバのインストール
  USBのCDC通信を行うためには、
 STMicroelectronics社が提供するVCP(仮想COMポート)ドライバを
 PCにインストールする必要があります。

コマンド送信について



概要
  サンプルプログラム F4xxxx_CDCは
 USBのCDCクラス(The Communication Device Class)を使用して、
 非同期シリアル通信を行います。

  PCからデータを受信すると、データを判定してLED点滅コマンドなら、
 指定に従って点滅間隔を変更します。

  また、受信したデータをエコーバックします。



えがおのでんし製の評価用基板 Base-F4xxxx の説明
  このサンプルプログラムは、
  えがおのでんし製の評価用基板 Base-F4xxxx を使用して動作を確認しています。


 1. Base-F405RG基板 の説明
Base_F405RG_Dim

  Base-F405RG基板については、
 Base-F405RG基板 の説明 をご覧ください。


 2. Base-F405VG基板 の説明
Base_F405VG_Dim

  Base-F405VG基板については、
 Base-F405VG基板 の説明 をご覧ください。


 3. Base-F446RE基板 の説明
Base_F446RE_Dim

  Base-F446RE基板については、
 Base-F446RE基板 の説明 をご覧ください。



サンプルプログラム F4xxxx_CDC のプロジェクト
 STM32CubeIDE 1.17.0 を使用して作成しました。


1. サンプルプログラム F405RG_CDC のプロジェクト
 ここからサンプルプログラム L_F405RG_CDC.zip をダウンロードしてください。

  プロジェクト L_F405RG_CDC は、
 フォルダ C:\Project_CubeIDE\Launch_F405RG\L_F405RG_CDC のように配置して作成しました。

  フォルダ C:\Project_CubeIDE\Launch_F405RG を作成して、
 そのフォルダに L_F405RG_CDC.zip を貼り付けて解凍し、
 プロジェクト作成時と同一に C:\Project_CubeIDE\Launch_F405RG\L_F405RG_CDC と
 配置した場合は、普通にプロジェクトを開くことができます。


2. サンプルプログラム F405VG_CDC のプロジェクト
 ここからサンプルプログラム L_F405VG_CDC.zip をダウンロードしてください。

  プロジェクト L_F405VG_CDC は、
 フォルダ C:\Project_CubeIDE\Launch_F405VG\L_F405VG_CDC のように配置して作成しました。

  フォルダ C:\Project_CubeIDE\Launch_F405VG を作成して、
 そのフォルダに L_F405VG_CDC.zip を貼り付けて解凍し、
 プロジェクト作成時と同一に C:\Project_CubeIDE\Launch_F405VG\L_F405VG_CDC と
 配置した場合は、普通にプロジェクトを開くことができます。


3. サンプルプログラム F446RE_CDC のプロジェクト
 ここからサンプルプログラム L_F446RE_CDC.zip をダウンロードしてください。

  プロジェクト L_F446RE_CDC は、
 フォルダ C:\Project_CubeIDE\Launch_F446RE\L_F446RE_CDC のように配置して作成しました。

  フォルダ C:\Project_CubeIDE\Launch_F446RE を作成して、
 そのフォルダに L_F446RE_CDC.zip を貼り付けて解凍し、
 プロジェクト作成時と同一に C:\Project_CubeIDE\Launch_F446RE\L_F446RE_CDC と
 配置した場合は、普通にプロジェクトを開くことができます。



既存のプロジェクトを開く
  サンプルプログラムのプロジェクトを任意のフォルダに配置した場合に、
 STM32CubeIDEにより、そのプロジェクトを開く方法については
既存のプロジェクトを開く方法 をご覧ください。



PCとのUSB接続

 1. Base-F405RG基板のUSB接続
  Base-F405RG基板の USB-1 を使用します。

  PCとUSB-1とを、USBケーブル(A - Mini B)で接続します。


 2. Base-F405VG基板のUSB接続
  Base-F405VG に搭載されているtri-S基板のUSBコネクタ P3 を使用します。

  PCとtri-S基板のP3とを、USBケーブル(A - Mini B)で接続します。

 3. Base-F446RE基板のUSB接続
  Base-F446RE基板の USB-1 を使用します。

  PCとUSB-1とを、USBケーブル(A - Mini B)で接続します。



サンプルプログラム F4xxxx_CDC の説明
  STM32F4xxxxのCDC通信を行うプログラムです。
  PCが送信したコマンドを受信して、コマンドに応じてLEDの点滅間隔を変化させます。

 プロジェクトを最初に開いた画面は以下のようになります。

F405RG_CDC_Scrn_First

 以下、サンプルプログラム F4xxxx_CDC について説明していきます。



サンプルプログラムの構成
  STM32CubeIDEの画面左側、Project Explorerの
 F4xxxx_CDCを展開した画面は以下のようになります。

F405RG_CDC_Tree

  サンプルプログラム F4xxxx_CDC の構成を以下に示します。

F4xxxx_CDC
  |
  |- Includes
  |
  |- CDC_Ope
  |    |- Communication_CDC : CDC通信処理
  |    |    |- Communication_CDC.c
  |    |    |- Communication_CDC.h
  |    |
  |    |- Execute_Command_LED : 受信したLEDコマンドの実行
  |    |    |- Execute_Command_LED.c
  |    |    |- Execute_Command_LED.h
  |    |
  |    |- F4xxxx_Config : 動作パラメータの定義
  |         |- Dev_Conf.h
  |
  |- Core
  |    |- Inc
  |    |    |- main.h
  |    |    |- stm32f4xx_hal_conf.h
  |    |    |- stm32f4xx_it.h : 割り込み処理モジュールのヘッダ
  |    |
  |    |- Src
  |    |    |- main.c
  |    |    |- stm32f4xx_hal_msp.c
  |    |    |- stm32f4xx_it.c : 割り込み処理モジュール
  |    |    |- syscalls.c
  |    |    |- system.c
  |    |    |- system_stm32f4xx.c
  |    |
  |    |- Startup
  |
  |- Drivers
  |
  |- Middlewares
  |    |- ST
  |        |
  |        |- STM32_USB_Device_Library
  |              |- Class
  |              |    |- CDC
  |              |        |- Inc
  |              |        |   |- usbd_cdc.h
  |              |        |
  |              |        |- Src
  |              |            |- usbd_cdc.c
  |              |
  |              |
  |              |- Core
  |                  |- Inc
  |                  |   |- usbd_core.h
  |                  |   |- usbd_ctrreq.h
  |                  |   |- usbd_def.h
  |                  |   |- usbd_ioreq.h
  |                  |
  |                  |- Src
  |                      |- usbd_core.c
  |                      |- usbd_ctrreq.c
  |                      |- usbd_ioreq.c
  |
  |- Shared_Lib : 共有ライブラリ
  |    |- Handle_UI_Lib
  |    |    |- Blink_LED_ST : ST LED点滅処理
  |    |         |- Blink_LED_ST.c
  |    |         |- Blink_LED_ST.h
  |    |
  |    |- Time_Interval : 時間待ち処理
  |         |- Time_Interval.c
  |         |- Time_Interval.h
  |
  |- USB_DEVICE
  |    |- App
  |    |   |- usb_device.c
  |    |   |- usb_device.h
  |    |   |- usbd_cdc_if.c : USB送受信の処理を記述
  |    |   |- usbd_cdc_if.h
  |    |   |- usbd_desc.c
  |    |   |- usbd_desc.h
  |    |
  |    |- Target
  |        |- usbd_conf.c
  |        |- usbd_conf.h
  |
  |- F4xxxx_CDC.launch
  |- STM32F4xxxxTX_FLASH.ld
  |- STM32F4xxxxTX_RAM.ld



 F4xxxx_CDC の動作パラメータの定義
  サンプルプログラム F4xxxx_CDC の 動作パラメータの定義を
  CDC_Ope/F4xxxx_Config/Dev_Conf.h に記述しています。

  使用する CPU の定義、ヘッダ名の定義、GPIO のポートとピンの定義、
 などを記述しています。



 ユーザープログラムの実行開始位置
  プログラムは、int main(void) から実行開始します。

  int main(void) は、フォルダ Core/Src/main.c にあります。

F405RG_CDC_main

  STM32CubeIDEでビルドされたプログラムは、自動的にCPUの初期化を
 行った後、int main(void) を呼び出します。

  ユーザーコード(記述したプログラム)は、
 int main(void) の先頭から実行されます。



 F4xxxx_CDC の main() の説明
  サンプルプログラム F4xxxx_CDC の main() の記述は、
 以下のとおりです。


/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */

  //------------------------------------------------------------
  // main関数内では、以下の処理番号の変数、
  // STC_uint8_JobNum_LED と
  // STC_uint8_JobNum_CDC は

  // while(1){
  // }

  // の永久ループ内で使用しているので、
  // static宣言をする必要はない。

  // しかし、main関数以外の全ての関数内では
  // 処理番号をstatic宣言をする必要があるので、
  // 合わせるために、ここでも static宣言をしている。
  //------------------------------------------------------------
  static uint8_t STC_uint8_JobNum_LED;  // LED点滅処理番号
  static uint8_t STC_uint8_JobNum_CDC;  // CDC通信処理番号


  //------------------------------------------------------------
  // 呼び出す関数を case 0: から実行させるために
  // 処理番号に 0 をセットします。
  //------------------------------------------------------------
  STC_uint8_JobNum_LED = 0;  // LED点滅処理番号初期化
  STC_uint8_JobNum_CDC = 0;  // CDC通信処理番号初期化

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USB_DEVICE_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

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

    /* USER CODE BEGIN 3 */
    //--------------------------------------------------------
    // ST LED点滅
    //--------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ

    // struct sParam_Blink_LED_ST *pstructParam_Blink_LED_ST :
    //              ST LED点滅用パラメータの構造体のポインタ


    // 戻り値:
    //   -1 : 処理中
    //    0 : OK終了
    //    1 : NG
    //--------------------------------------------------------
    Blink_LED_ST(&STC_uint8_JobNum_LED,
                 &GLB_structParam_Blink_LED_ST);


    //----------------------------------------------------------
    // CDC通信処理
    //----------------------------------------------------------
    // 処理内容 :

    // 1. CDCの初期化がされていない場合、初期化します。
    // 2. 受信が発生するのを待ち、受信データを取得します。
    // 3. 受信データを判定して、内容に従い処理を行います。
    // 4. 受信データによる処理の結果、
    //      送信データがセットされた場合、送信処理を行います。
    //----------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ

    // struct sParam_Communication_CDC
    //                  *pstructParam_Communication_CDC :
    //          Communication_CDC用パラメータの構造体のポインタ


    // 戻り値:
    //   -1 : 処理中
    //    0 : OK終了
    //    1 : NG終了
    //----------------------------------------------------------
    Communication_CDC(&STC_uint8_JobNum_CDC,
                      &GLB_structParam_Communication_CDC);
  }
  /* USER CODE END 3 */
}


 1) 初期化の部分

  a) CPUのPeripheral初期化
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
   により、CPUのPeripheralなどの基本的な初期化を行います。
  PeripheralとはCPUの周辺インターフェースなどのことを言います。

   プロジェクト構築時に自動的に組み込まれる、
  HAL Drivers(フォルダ Drivers/STM32F4xx_HAL_Drivers) 内に記述されています。


  b) CPU動作クロックの設定
  /* Configure the system clock */
  SystemClock_Config();

   CPUの動作クロックとPeripheralの動作クロックを設定します。

   SystemClock_Config(); の設定内容は、

int main(void)
{
         .
         .
         .
}
 の、すぐ下に記述されています。


 2) LED点滅 と CDC通信処理 の部分
   永久ループ部分の記述を以下に示します。


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

    /* USER CODE BEGIN 3 */
    //--------------------------------------------------------
    // ST LED点滅
    //--------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ

    // struct sParam_Blink_LED_ST *pstructParam_Blink_LED_ST :
    //              ST LED点滅用パラメータの構造体のポインタ


    // 戻り値:
    //   -1 : 処理中
    //    0 : OK終了
    //    1 : NG
    //--------------------------------------------------------
    Blink_LED_ST(&STC_uint8_JobNum_LED,
                 &GLB_structParam_Blink_LED_ST);


    //----------------------------------------------------------
    // CDC通信処理
    //----------------------------------------------------------
    // 処理内容 :

    // 1. CDCの初期化がされていない場合、初期化します。
    // 2. 受信が発生するのを待ち、受信データを取得します。
    // 3. 受信データを判定して、内容に従い処理を行います。
    // 4. 受信データによる処理の結果、
    //      送信データがセットされた場合、送信処理を行います。
    //----------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ

    // struct sParam_Communication_CDC
    //                  *pstructParam_Communication_CDC :
    //          Communication_CDC用パラメータの構造体のポインタ


    // 戻り値:
    //   -1 : 処理中
    //    0 : OK終了
    //    1 : NG終了
    //----------------------------------------------------------
    Communication_CDC(&STC_uint8_JobNum_CDC,
                      &GLB_structParam_Communication_CDC);
  }
  /* USER CODE END 3 */

  ST LED点滅処理 Blink_LED_ST と
  CDC通信処理 Communication_CDC を
 呼び出しています。

  Communication_CDC では、コマンドを受信して、コマンドの内容に応じて
 LEDの点滅時間変更を行います。

  Blink_LED_ST と Communication_CDC は並列に実行されます。



 CDC通信処理 Communication_CDC の説明
  データを受信して、LED点滅コマンドの場合、
 コマンドの内容に応じて、LEDの点滅間隔を変更します。
  受信したデータはエコーバックされます。

  LED点滅コマンドは以下の通りです。
LED1 B0\r\n : 1000mSec 点灯 / 2000mSec 消灯
LED1 B1\r\n : 100mSec 点灯 / 100mSec 消灯
LED1 B2\r\n : 200mSec 点灯 / 200mSec 消灯
LED1 B3\r\n : 300mSec 点灯 / 300mSec 消灯
LED1 B4\r\n : 400mSec 点灯 / 400mSec 消灯
LED1 B5\r\n : 500mSec 点灯 / 500mSec 消灯
  \r : CR : 0x0D
  \n : LF : 0x0A
 です。

  Communication_CDC は
 CDC_Ope/Communication_CDC/Communication_CDC.c 内にあります。

  以下に、Communication_CDC のコードを示します。


//----------------------------------------------------------
// CDC通信処理
//----------------------------------------------------------
// 処理内容 :

//  1. CDCの初期化がされていない場合、初期化します。
//  2. 受信が発生するのを待ち、受信データを取得します。
//  3. 受信データを判定して、内容に従い処理を行います。
//  4. 受信データによる処理の結果、
//     送信データがセットされた場合、送信処理を行います。
//----------------------------------------------------------
// 引数:
// uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ

// struct sParam_Communication_CDC
//                  *pstructParam_Communication_CDC :
//          Communication_CDC用パラメータの構造体のポインタ


// 戻り値:
//   -1 : 処理中
//    0 : OK終了
//    1 : NG終了
//----------------------------------------------------------
int16_t Communication_CDC(uint8_t *puint8_JobNum,
                     struct sParam_Communication_CDC
                            *pstructParam_Communication_CDC)
{
  static uint8_t STC_uint8_JobNum_CDC;

  int16_t int16_ReceiveLength;

  int16_t int16_Return;


  switch(*puint8_JobNum)
  {
  case 0:
    //--------------------------------------
    // 初期化フラグの判定
    //--------------------------------------
    if(pstructParam_Communication_CDC->int16_vCDC_Initialize <= 0){
      //----------------------------------------------------
      // 初期化済みでない場合、
      // CDC通信パラメータ初期化 と CDC初期化を行います。
      //----------------------------------------------------
      //--------------------------------------------------------
      // CDC通信パラメータ初期化 と CDCの初期化
      //--------------------------------------------------------
      // 引数:
      // struct sParam_Communication_CDC
      //                  *pstructParam_Communication_CDC :
      //          Communication_CDC用パラメータの構造体のポインタ


      // 戻り値:
      //    なし
      //--------------------------------------------------------
      Initialize_Communication_CDC(pstructParam_Communication_CDC);

      pstructParam_Communication_CDC->int16_vCDC_Initialize = 1;
                                    // CDC初期化フラグON
    }

    pstructParam_Communication_CDC->uint16_vCDC_SendLength = 0;
                                    // 送信データ長クリア


    STC_uint8_JobNum_CDC = 0;  // CDC通信処理番号初期化


    (*puint8_JobNum)++;  // 次の処理番号に移行する。
    int16_Return = -1;   // 処理継続
    break;

  case 1:
    //------------------------------------------------------
    // CDCによるVCP受信処理
    //------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ

    // struct sParam_Communication_CDC
    //                  *pstructParam_Communication_CDC :
    //          Communication_CDC用パラメータの構造体のポインタ


    // 戻り値:
    //   -1 : 受信なし
    //    0 : 受信なし
    //    1以上 : 受信byte数 : 受信終了
    //------------------------------------------------------
    int16_ReceiveLength = Receive_CDC(&STC_uint8_JobNum_CDC,
                            pstructParam_Communication_CDC);
    if(int16_ReceiveLength <= 0){
      // 受信なしの場合
      int16_Return = -1;  // 処理継続
      break;  // 処理番号維持 : 現在の処理番号をループ
    }
    //--------------------------------------------------
    // 受信を行うまで、この下に行きません。
    //--------------------------------------------------


    //----------------------------------------------------------
    // 受信コマンドを実行する。 : LED点滅
    //----------------------------------------------------------
    // 引数 :
    // uint16_t uint16_ReceiveLength : 受信データ数
    // uint8_t *puint8_aReceiveData :
    //          受信データが格納されているBufferのポインタ
    // uint8_t *puint8_SendData :
    //          応答送信データを格納するBufferのポインタ

    // struct sParam_Blink_LED_ST *pstructParam_Blink_LED_ST :
    //              ST LED点滅用パラメータの構造体のポインタ


    // 戻り値 : 応答送信データ数
    //----------------------------------------------------------
    pstructParam_Communication_CDC->uint16_vCDC_SendLength
        = Execute_Command_LED((uint16_t)int16_ReceiveLength,
                              GLB_uint8_aCDC_ReceiveData,
                              GLB_uint8_aCDC_SendData,
                              &GLB_structParam_Blink_LED_ST);
    if(pstructParam_Communication_CDC->
                        uint16_vCDC_SendLength == 0){
      //--------------------------------------------
      // 送信データなしの場合
      //--------------------------------------------
      *puint8_JobNum = 0;  // 処理番号初期化
      int16_Return = 0;    // OK終了
      break;
    }


    //----------------------------------------------
    // 送信データがある場合
    //----------------------------------------------
    (*puint8_JobNum)++;  // 次の処理番号に移行する。
    int16_Return = -1;   // 処理継続
    break;

  case 2:
    //----------------------------------------------------------
    // CDC送信セマフォチェック :
    // 他のモジュールでCDC送信を実行していないかをチェックします。
    //----------------------------------------------------------
    if(pstructParam_Communication_CDC->
                        int16_vSemaphore_CDC_Send != 0){
      // 使用中
      int16_Return = -1;  // 処理中
      break;  // 処理番号維持 : 処理継続 : 現在の処理番号をループ
    }
    //------------------------------------------------------
    // 他のモジュールが GLB_int16_vSemaphore_CDC_Send を
    // 開放するまで、この下に行きません。
    //------------------------------------------------------


    pstructParam_Communication_CDC->
        int16_vSemaphore_CDC_Send = 1;  // CDC送信セマフォ取得


    (*puint8_JobNum)++;  // 次の処理番号に移行する。
    int16_Return = -1;   // 処理中
    break;

  case 3:
    //----------------------------------------------------------
    // CDCによるVCP送信処理
    //----------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ

    // uint16_t uint16_SendLength : 送信データ数
    // uint8_t *puint8_SendData :
    //              送信データが格納されているBufferのポインタ

    // 戻り値:
    //   -1 : 送信中
    //    0 : 送信終了 : OK
    //    1 : エラー
    //----------------------------------------------------------
    int16_Return = Send_CDC(&STC_uint8_JobNum_CDC,
        pstructParam_Communication_CDC->uint16_vCDC_SendLength,
                            GLB_uint8_aCDC_SendData);
    if(int16_Return == -1){
      // 送信中
      break;  // 処理番号維持 : 処理継続 : 現在の処理番号をループ
    }
    //----------------------------------------------
    // 送信が終了するまで、この下に行きません。
    //----------------------------------------------


    pstructParam_Communication_CDC->uint16_vCDC_SendLength = 0;
                                        // 送信データ長クリア

    pstructParam_Communication_CDC->int16_vSemaphore_CDC_Send = 0;
                                        // CDC送信セマフォ解放


    *puint8_JobNum = 0;  // 処理番号初期化
    // int16_Return : 処理結果
    // 処理終了
    break;

  default:
    *puint8_JobNum = 0;  // 処理番号初期化
    int16_Return = 1;    // NG
    break;
  }

  return(int16_Return);
}

 1) case 0:
  a) 初期化フラグ pstructParam_Communication_CDC->int16_vCDC_Initialize を判定して
   0 の場合、CDC の初期化を行います。

  b) 処理番号 *puint8_JobNum をインクリメントして、次に実行する処理を case 1: にします。

 2) case 1:
  a) CDC の受信処理を行います。

   受信がない場合、break します。
    *puint8_JobNumが 1 のまま抜けるので、次にモジュールが呼び出されると
    再び case 1: が実行されます。
    受信があるまで、case 1: を繰り返し実行します。
    受信があった場合、以下の処理を実行します。

  b) 受信データは GLB_uint8_aCDC_ReceiveData にセットされています。

  c) 受信コマンド実行モジュール Execute_Command_LED に
   GLB_uint8_aCDC_ReceiveData を渡して実行します。

   受信コマンド実行結果に伴う送信データは
  GLB_uint8_aCDC_SendData にセットされます。

  d) Execute_Command_LED を実行した結果、送信データなしの場合は
   処理番号を 0 にセットして、case 0: の処理に移行します。

  e) Execute_Command_CDC を実行した結果、送信データありの場合、
   処理番号をインクリメントします。
    処理は、case 2: に移行します。

 3) case 2:
  a) CDC送信セマフォチェックを行います。
   他のモジュールがCDC送信を実行していないかチェックます。

    実行している場合は、case 2: をループします。
    実行していなければセマフォを取得します。

  b) セマフォを取得したら、処理番号をインクリメントします。
    処理は、case 3: に移行します。

 4) case 3:
   CDCによるVCP送信処理 Send_CDC を実行して、
  GLB_uint8_CDC_SendData のデータを送信します。

  a) 送信が終了するまで、case 3: をループします。

  b) 送信が終了すると、処理番号を 0 に初期化して終了します。

  Communication_CDC は再び、処理番号 0 : case 0: から実行されます。



 モジュール Execute_Command_LED について
  受信したLEDコマンドに応じて、LED点滅間隔を設定します。

  モジュール Execute_Command_LED は、
 CDC_Ope/Execute_Command_LED/Execute_Command_LED.c 内に記述されています。

  以下に、モジュールExecute_Command_LEDのコードを示します。


//----------------------------------------------------------
// 受信コマンドを実行する。 : LED点滅
//----------------------------------------------------------
// 引数;
// uint16_t uint16_ReceiveLength : 受信データ数
// uint8_t *puint8_aReceiveData :
//              受信データが格納されているBufferのポインタ
// uint8_t *puint8_aSendData :
//              応答送信データを格納するBufferのポインタ

// struct sParam_Blink_LED_ST *pstructParam_Blink_LED_ST :
//              ST LED点滅用パラメータの構造体のポインタ


// 戻り値; 応答送信データ数
//----------------------------------------------------------
uint16_t Execute_Command_LED(uint16_t uint16_ReceiveLength,
                             uint8_t *puint8_aReceiveData,
                             uint8_t *puint8_aSendData,
            struct sParam_Blink_LED_ST *pstructParam_Blink_LED_ST)
{
  uint16_t uint16_I;
  uint16_t uint16_SendLength = 0;


  //------------------------------------------------------------
  // Command処理
  //------------------------------------------------------------

  //------------------------------------------------------------
  // LED1(緑) 点滅間隔切り替え
  //------------------------------------------------------------
  if(memcmp(puint8_aReceiveData, "LED1 B0\r\n", 9) == 0){
    // LED1(緑) : 点灯1000mSec / 消灯2000mSec
    pstructParam_Blink_LED_ST->uint16_Time_LED_ST_ON = (uint16_t)1000;
    pstructParam_Blink_LED_ST->uint16_Time_LED_ST_OFF = (uint16_t)2000;

    pstructParam_Blink_LED_ST->int16_Restart_LED_ST = 1;
                                    // Status LED再起動フラグON
  }
  else if(memcmp(puint8_aReceiveData, "LED1 B1\r\n", 9) == 0){
    // LED1(緑) : 点灯100mSec / 消灯100mSec
    pstructParam_Blink_LED_ST->uint16_Time_LED_ST_ON = (uint16_t)100;
    pstructParam_Blink_LED_ST->uint16_Time_LED_ST_OFF = (uint16_t)100;

    pstructParam_Blink_LED_ST->int16_Restart_LED_ST = 1;
                                    // Status LED再起動フラグON
  }
  else if(memcmp(puint8_aReceiveData, "LED1 B2\r\n", 9) == 0){
    // LED1(緑) : 点灯200mSec / 消灯200mSec
    pstructParam_Blink_LED_ST->uint16_Time_LED_ST_ON = (uint16_t)200;
    pstructParam_Blink_LED_ST->uint16_Time_LED_ST_OFF = (uint16_t)200;

    pstructParam_Blink_LED_ST->int16_Restart_LED_ST = 1;
                                    // Status LED再起動フラグON
  }
  else if(memcmp(puint8_aReceiveData, "LED1 B3\r\n", 9) == 0){
    // LED1(緑) : 点灯300mSec / 消灯300mSec
    pstructParam_Blink_LED_ST->uint16_Time_LED_ST_ON = (uint16_t)300;
    pstructParam_Blink_LED_ST->uint16_Time_LED_ST_OFF = (uint16_t)300;

    pstructParam_Blink_LED_ST->int16_Restart_LED_ST = 1;
                                    // Status LED再起動フラグON
  }
  else if(memcmp(puint8_aReceiveData, "LED1 B4\r\n", 9) == 0){
    // LED1(緑) : 点灯400mSec / 消灯400mSec
    pstructParam_Blink_LED_ST->uint16_Time_LED_ST_ON = (uint16_t)400;
    pstructParam_Blink_LED_ST->uint16_Time_LED_ST_OFF = (uint16_t)400;

    pstructParam_Blink_LED_ST->int16_Restart_LED_ST = 1;
                                    // Status LED再起動フラグON
  }
  else if(memcmp(puint8_aReceiveData, "LED1 B5\r\n", 9) == 0){
    // LED1(緑) : 点灯500mSec / 消灯500mSec
    pstructParam_Blink_LED_ST->uint16_Time_LED_ST_ON = (uint16_t)500;
    pstructParam_Blink_LED_ST->uint16_Time_LED_ST_OFF = (uint16_t)500;

    pstructParam_Blink_LED_ST->int16_Restart_LED_ST = 1;
                                    // Status LED再起動フラグON
  }


  // エコーバック
  for(uint16_I = 0; uint16_I < uint16_ReceiveLength; uint16_I++){
    puint8_aSendData[uint16_I] = puint8_aReceiveData[uint16_I];
  }

  uint16_SendLength = uint16_ReceiveLength;

  return(uint16_SendLength);
}


VCPドライバのインストール
  USBのCDC通信を行うためには、
 STMicroelectronics社が提供するVCP(仮想COMポート)ドライバを
 PCにインストールする必要があります。

  開発ツールの STM32CubeIDE をインストールするときに、
 VCPドライバもインストールされます。

  もし、個別にVCPドライバをインストールする必要がある場合は、
 以下の要領でドライバを入手してインストールします。

 1) STMicroelectronics社のサイトにアクセスして、
  STM32 Virtual COM Port Driver の STSW-STM32102 をダウロードします。

   現在のバージョンは、1.5.0 です。
   en.stsw-stm32102_v1.5.0.zip がダウンロードされます。

 2) en.stsw-stm32102_v1.5.0.zip を解凍します。
  解凍されたファイルの中の VCP_V1.5.0_Setup_W7_x64_64bits.exe を実行して、
  VCPドライバをインストールします。



 コマンド送信について
  PCからBase-F4xxxx基板にコマンド送信を行うために、Tera Termを使用しました。

  Tera Termのファイル送信により、コマンドを送信します。

  例えば、Textファイルに LED1 B1<改行> を記述し、
 Tera Termの端末の設定で、改行コードの送信に CR+LF を指定して、
 ファイル送信します。



A+-2C (ええ加減にC) のページに戻る




 メールアドレス: apm2c.sumi@gmail.com

 なんでも、気軽に ご相談ください。
 担当:おの

マスコット
  えがおのでんし 案内