サンプルプログラム F405VG_DAC の説明
F405VG_DAC_Wave_Screen
  STM32F405VG内蔵のDACを使用して
 正弦波を出力するプログラムです。


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

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



目次

概要

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

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


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

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

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

 DAC処理 Transact_DAC の説明



概要
  サンプルプログラム F405VG_DACは
 STM32F405VG内蔵のDACを使用して
 正弦波を出力するプログラムです。

  STM32F405VG内蔵のタイマ TIM6 により
 100uSec間隔のタイミングを作成し、
 正弦波データ配列 1000個を100uSec間隔でD/A変換して出力します。

  正弦波の周期は 100mSec になります。

  D/A信号は PA4 (DAC_OUT1) に出力しています。

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



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

Base_F405VG_Dim

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



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

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

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

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

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



サンプルプログラム F405VG_DAC の説明
  STM32F405VG内蔵のDACを使用して正弦波出力を行うプログラムです。
  正弦波データ配列 1000個を100uSec間隔でD/A変換して出力します。

  正弦波の周期は 100mSec になります。

  D/A信号は PA4 (DAC_OUT1) に出力しています。

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

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

F405VG_DAC_Scrn_First

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



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

F405VG_DAC_Tree

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

F405VG_DAC
  |
  |- Includes
  |
  |- 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
  |
  |- DAC_Ope
  |    |- Data_Creation_Sine : 正弦波データ配列作成
  |    |    |- Data_Creation_Sine.c
  |    |    |- Data_Creation_Sine.h
  |    |
  |    |- F405VG_DAC_Config : 動作パラメータの定義
  |    |    |- Dev_Conf.h
  |    |
  |    |- Transact_DAC : DAC処理
  |         |- Transact_DAC.c
  |         |- Transact_DAC.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_DAC.c : DAC_OUT1 のハンドラ
  |         |- H_F4_DAC.h
  |         |- H_F4_TIM6.c : TIM6 のハンドラ
  |         |- H_F4_TIM6.h
  |
  |- F405VG_DAC.launch
  |- STM32F405VGTX_FLASH.ld
  |- STM32F405VGTX_RAM.ld



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

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



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

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

F405VG_DAC_main

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

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



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



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

  uint8_t uint8_JobNum_LED = 0;  // LED点滅処理番号
  uint8_t uint8_JobNum_DAC = 0;  // 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);


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

    // 戻り値:
    //   -1 : 処理中
    //    0 : OK終了
    //    1 : NG
    //------------------------------------------------------
    Transact_DAC(&uint8_JobNum_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点滅 と 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);


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

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

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

  Transact_DAC では、正弦波データ配列を作成した後、
 100uSec間隔で正弦波データをD/A変換して出力しています。

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



 DAC処理 Transact_DAC の説明
  正弦波データ 1000個 の配列を作成した後、
 正弦波データを100uSec間隔でD/A変換して 1000個 出力するのを繰り返します。

  正弦波の周期は 100mSec になります。

  D/A信号は PA4 (DAC_OUT1) に出力しています。

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

  Transact_DAC は
 DAC_Ope/Transact_DAC/Transact_DAC.c 内にあります。

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


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

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


  switch(*puint8_JobNum)
  {
  case 0:
    //--------------------------------
    // 正弦波データ作成
    //--------------------------------
    // 引数:
    // uint16_t *puint16_Sine : 正弦波データを格納するバッファのポインタ

    // 戻り値:
    //  なし
    //--------------------------------
    Data_Creation_Sine(GLB_uint16_Buf_DAC);


    //------------------------------------------------
    // Toggle_SのGPIO初期化
    //------------------------------------------------
    Init_Toggle_S();


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


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


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

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


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

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

    GLB_int16_Flag_DAC_End = 0;  // DAC変換終了フラグ OFF


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


    *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) 正弦波データ配列の作成を行います。
   1周期 1000個のデータを作成します。
   0 - 4095 の範囲の値です。

  b) 正弦波データ 1000個 のD/A変換出力を行うごとにLow/High出力を
   切り替えるToggle信号の初期化を行います。

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

 2) case 1:
  a) DMAによる1000個のD/A変換を開始します。
   1000個のD/A変換が終了すると割り込みが発生します。
   その割り込みでは、D/A変換終了フラグ GLB_int16_Flag_DAC_End を
  1にセットします。

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

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

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

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

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

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

  Transact_DAC は、case 1: と case 2: を繰り返します。



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




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

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

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