サンプルプログラム F405VG_ADC_DAC の説明
F405VG_ADC_DAC_Wave_Screen
  STM32F405VG内蔵のADCとDACを使用して
 A/D変換して入力したデータを
 そのまま、D/A変換出力するプログラムです。


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

  えがおのでんし製の評価用基板 Base-F405VG には、STM32F405VGを実装した
 えがおのでんし製の評価用CPU基板 tri-S CPU が搭載されています。



目次

概要

えがおのでんし製の評価用基板 Base-F405VG の説明

サンプルプログラム F405VG_ADC_DAC のプロジェクト


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

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

 F405VG_ADC_DAC の main() の説明
  1) 初期化の部分
  2) LED点滅 と ADCとDACの処理 の部分

 ADCとDACの処理 Transact_ADC_DAC の説明



概要
  サンプルプログラム F405VG_ADC_DACは
 STM32F405VG内蔵のADCとDACを使用して
 A/D変換して入力したデータを
 そのまま、D/A変換して出力するプログラムです。

  STM32F405VG内蔵のタイマ TIM4 と TIM6 により
 それぞれ100uSec間隔のタイミングを作成します。

  A/D変換には TIM4 を、D/A変換には TIM6 を使用します。

  100uSec間隔でA/D変換を行い、1000個のデータを取り込みます。
  その1000個のデータをそのまま、100uSec間隔でD/A変換して出力します。

  1000個のデータを取り込む周期は 100mSec になります。

  A/D信号は PB0 (ADC12_IN8) から入力します。
  D/A信号は PA4 (DAC_OUT1) に出力しています。

  また、1000個のA/D変換が終了するごとに、Low/Highを切り替える
 Toggle信号を PA7 に出力しています。



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

Base_F405VG_Dim

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



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

 ここからサンプルプログラム W_F405VG_ADC_DAC.zip をダウンロードしてください。

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

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

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



サンプルプログラム F405VG_ADC_DAC の説明
  STM32F405VG内蔵のADCとDACを使用して
 A/D変換して入力したデータを
 そのまま、D/A変換して出力するプログラムです。

  STM32F405VG内蔵のタイマ TIM4 と TIM6 により
 それぞれ100uSec間隔のタイミングを作成します。

  A/D変換には TIM4 を、D/A変換には TIM6 を使用します。

  100uSec間隔でA/D変換を行い、1000個のデータを取り込みます。
  その1000個のデータをそのまま、100uSec間隔でD/A変換して出力します。

  1000個のデータを取り込む周期は 100mSec になります。

  A/D信号は PB0 (ADC12_IN8) から入力します。
  D/A信号は PA4 (DAC_OUT1) に出力しています。

  また、1000個のA/D変換が終了するごとに、Low/Highを切り替える
 Toggle信号を PA7 に出力しています。

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

F405VG_ADC_DAC_Scrn_First

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



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

F405VG_ADC_DAC_Tree

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

F405VG_ADC_DAC
  |
  |- Includes
  |
  |- ADC_DAC_Ope
  |    |- F405VG_ADC_DAC_Config : 動作パラメータの定義
  |    |    |- Dev_Conf.h
  |    |
  |    |- Transact_ADC_DAC : ADCとDACの処理
  |         |- Transact_ADC_DAC.c
  |         |- Transact_ADC_DAC.h
  |
  |- C_Lib
  |    |- User_IF_Lib
  |    |    |- Blink_LED_Status : Status LED点滅処理
  |    |         |- Blink_LED_Status.c
  |    |         |- Blink_LED_Status.h
  |    |
  |    |- Wait_Interval : 時間待ち処理
  |         |- Wait_Interval.c
  |         |- Wait_Interval.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
  |
  |- Periph_Lib
  |    |- Handle_F4 : 周辺インターフェースのハンドラ
  |         |- H_F4_ADC.c : ADC12_IN8 のハンドラ
  |         |- H_F4_ADC.h
  |         |- H_F4_DAC.c : DAC_OUT1 のハンドラ
  |         |- H_F4_DAC.h
  |         |- H_F4_TIM.c : TIM4 と TIM6 のハンドラ
  |         |- H_F4_TIM.h
  |
  |- F405VG_ADC_DAC.launch
  |- STM32F405VGTX_FLASH.ld
  |- STM32F405VGTX_RAM.ld



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

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



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

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

F405VG_ADC_DAC_main

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

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



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



int main(void)
{
  /* USER CODE BEGIN 1 */

  uint8_t uint8_JobNum_LED = 0;  // LED点滅処理番号
  uint8_t uint8_JobNum_ADC_DAC = 0;  // ADC_DAC処理番号

  /* 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();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

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

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

    // uint16_t uint16_Time_ON  : 点灯時間
    // uint16_t uint16_Time_OFF : 消灯時間

    // 戻り値:
    //   -1 : 処理中
    //    0 : OK終了
    //    1 : NG
    //------------------------------------------------------
    Blink_LED_Status(&uint8_JobNum_LED,
                     GLB_uint16_Time_LED_Status_ON,
                     GLB_uint16_Time_LED_Status_OFF);


    //------------------------------------------------------
    // ADCとDACの処理
    //------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ

    // 戻り値:
    //   -1 : 処理中
    //    0 : OK終了
    //    1 : NG
    //------------------------------------------------------
    Transact_ADC_DAC(&uint8_JobNum_ADC_DAC);
  }
  /* 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点滅 と ADCとDACの処理 の部分
   永久ループ部分の記述を以下に示します。


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

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

    // uint16_t uint16_Time_ON  : 点灯時間
    // uint16_t uint16_Time_OFF : 消灯時間

    // 戻り値:
    //   -1 : 処理中
    //    0 : OK終了
    //    1 : NG
    //------------------------------------------------------
    Blink_LED_Status(&uint8_JobNum_LED,
                     GLB_uint16_Time_LED_Status_ON,
                     GLB_uint16_Time_LED_Status_OFF);


    //------------------------------------------------------
    // ADCとDACの処理
    //------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ

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

  Status LED点滅処理 Blink_LED_Status と
  ADCとDACの処理 Transact_ADC_DAC を
 呼び出しています。

  Transact_ADC_DAC では、
  100uSec間隔でA/D変換を行い、1000個のデータを取り込み、
  その1000個のデータをそのまま、100uSec間隔でD/A変換して出力しています。

  Blink_LED_Status と Transact_ADC_DAC は並列に実行されます。



 ADCとDACの処理 Transact_ADC_DAC の説明
  100uSec間隔でA/D変換したデータ 1000個 を取り込んだ後、
 そのデータを100uSec間隔でD/A変換して 1000個 出力するのを繰り返します。

  STM32F405VG内蔵のタイマ TIM4 と TIM6 により
 それぞれ100uSec間隔のタイミングを作成します。

  A/D変換には TIM4 を、D/A変換には TIM6 を使用します。

  100uSec間隔でA/D変換を行い、1000個のデータを取り込みます。
  その1000個のデータをそのまま、100uSec間隔でD/A変換して出力します。

  1000個のデータを取り込む周期は 100mSec になります。

  A/D信号は PB0 (ADC12_IN8) から入力します。
  D/A信号は PA4 (DAC_OUT1) に出力しています。

  また、1000個のA/D変換が終了するごとに、Low/Highを切り替える
 Toggle信号を PA7 に出力しています。

  Transact_ADC_DAC は
 ADC_DAC_Ope/Transact_ADC_DAC/Transact_ADC_DAC.c 内にあります。

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


//------------------------------------------------------
// ADCとDACの処理
//------------------------------------------------------
// 引数:
// uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ

// 戻り値:
//   -1 : 処理中
//    0 : OK終了
//    1 : NG
//------------------------------------------------------
int16_t Transact_ADC_DAC(uint8_t *puint8_JobNum)
{
  int16_t int16_Return;


  switch(*puint8_JobNum)
  {
  case 0:
    //------------------------------------------------
    // Toggle_SのGPIO初期化
    //------------------------------------------------
    Init_Toggle_S();


    //--------------------------------
    // TIM6初期化
    //--------------------------------
    Init_TIM6();


    //---------------------------
    // DAC初期化
    //---------------------------
    Init_DAC();


    //--------------------------------
    // TIM4初期化
    //--------------------------------
    Init_TIM4();


    //---------------------------
    // ADC初期化
    //---------------------------
    Init_ADC();


    // Start ADC1 conversion process and enable DMA
    if(HAL_ADC_Start_DMA(&hadc1,
            (uint32_t *)GLB_uint16_Buf_ADC, def_Size_Buf_ADC) != HAL_OK)
    {
      /* Start Error */
      Error_Handler();
    }

    // Enable ADC1
    if(HAL_ADC_Start(&hadc1) != HAL_OK)
    {
      /* Start Error */
      Error_Handler();
    }


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

  case 1:
    if(GLB_int16_Flag_ADC_End == 0){
      // ADC変換が終了していない。
      int16_Return = -1;  // 処理継続
      break;  // 処理番号維持 : case 1: をループ
    }

    GLB_int16_Flag_ADC_End = 0;  // ADC変換終了フラグ OFF


    //------------------------------
    // DAC_OUT1
    //------------------------------
    // Enable DAC selected channel and associated DMA
    if (HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1,
            (uint32_t *)GLB_uint16_Buf_ADC_CH8, def_Size_Buf_ADC,
            DAC_ALIGN_12B_R) != HAL_OK)
    {
      // Start DMA Error
    }


    //------------------------------------------------
    // Toggle_S信号の Low/High を交互に切り替える。
    //------------------------------------------------
    Toggle_S();


    GLB_int16_Flag_Get_ADC = 1;  // ADCデータ取得フラグ ON


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

  case 2:
    //--------------------------------------------------
    // ここに、ADCデータに対する処理を記述してください。
    //--------------------------------------------------

    //------------------------------------------------
    // AD変換データ取得時、A と B を示すフラグ をチェック
    //------------------------------------------------
    // GLB_int16_Flag_A_or_B
    //   0 : A のデータ取得
    //   1 : B のデータ取得
    //------------------------------------------------
    if(GLB_int16_Flag_A_or_B == 0){
      GLB_int16_Flag_A_or_B = 1;

      // A のデータの処理
    }
    else{
      GLB_int16_Flag_A_or_B = 0;

      // B のデータの処理
    }


    GLB_int16_Flag_Get_ADC = 0;  // ADCデータ取得フラグ OFF


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

  case 3:


    *puint8_JobNum = 1;   // 処理番号 1 に移行する : case 1:
    int16_Return = -1;  // 処理継続
    break;

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

  return(int16_Return);
}

 1) case 0:
  a) A/D変換データを 1000個取り込むごとにLow/High出力を
   切り替える Togle信号のGPIOの初期化を行います。

  b) TIM6 と DAC_OUT1 の初期化を行います。

  c) TIM4 と ADC12_IN8 の初期化を行います。

  d) DMAによる1000個のA/D変換を開始します。
   1000個のA/D変換は繰り返し行われます。

    1000個のA/D変換が終了すると割り込みが発生します。
    その割り込みでは、A/D変換終了フラグ GLB_int16_Flag_ADC_End を
   1にセットします。

  e) 処理番号をインクリメントします。
    処理は、case 1: に移行します。

 2) case 1:
  a) A/D変換終了フラグ GLB_int16_Flag_ADC_End が
   1 になるのを待ちます。

    0 の場合は、case 1: をループします。

  b) A/D変換終了フラグ GLB_int16_Flag_ADC_End が
   1 になったら、GLB_int16_Flag_ADC_End を
   0 に戻します。

  c) DMAによる1000個のD/A変換を開始します。

  d) Toggle信号の Low/High を切り替えます。

  e) 処理番号をインクリメントします。
    処理は、case 2: に移行します。

 3) case 2:
  a) A/D変換入力データに対する処理を行う場合は、
   ここに処理を記述します。

  b) 処理番号をインクリメントします。
    処理は、case 3: に移行します。

 4) case 3:
  a) もし、A/D変換データに対する処理を行ったデータを
   DAC_OUT2 に出力するなら、ここに処理を記述します。

    DAC_OUT2 を使用する場合、case 0: の部分に
   DAC_OUT2 の初期化を記述する必要があります。

  b) 処理番号を 1 にセットして、case 1: に移行します。

  Transact_ADC_DAC は、case 1: から case 3: を繰り返し実行します。



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




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

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

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