CQ出版社セミナ "実習・Armマイコン内蔵ペリフェラルを活用するためのC++プログラミング" で使う外付け回路のテスト

Dependencies:   mbed UIT_SetOutputPortType UIT_AQM1602 UIT_ADT7410

Revision:
0:8c850cf6285d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/F446_ADDA/F446_AdcBase.cpp	Tue Mar 03 03:30:50 2020 +0000
@@ -0,0 +1,92 @@
+//-------------------------------------------------------------
+//  F446 内蔵 ADC2 のための抽象基底クラス
+//
+//  2020/01/28, Copyright (c) 2020 MIKAMI, Naoki
+//-------------------------------------------------------------
+
+#include "F446_AdcBase.hpp"
+#include "PeripheralPins.h" // PinMap_ADC を使う場合に必要
+#pragma diag_suppress 870   // マルチバイト文字使用の警告抑制のため
+// PeripheralPins.c は以下よりたどって行けば取得可能
+// https://gitlab.exmachina.fr/fw-libs/mbed-os/tree/5.8.1
+
+namespace Mikami
+{
+    // コンストラクタ
+    AdcF446_Base::AdcF446_Base(float fSampling, PinName pin)
+    {
+        SetGPIO(pin);                   // GPIO の設定
+
+        __HAL_RCC_ADC2_CLK_ENABLE();    // ADC2 にクロックを供給する
+        // __HAL_RCC_ADC2_CLK_ENABLE() の定義:stm32f4xx_hal_rcc_ex.h
+
+        // 1 チャンネルのみ使用の設定
+        myAdc_->SQR1 &= ~ADC_SQR1_L;
+        // pin に対応するチャンネルを使うための設定
+        myAdc_->SQR3 = STM_PIN_CHANNEL(pinmap_function(pin, PinMap_ADC));
+        // pinmap_function() のヘッダファイル: mbed\hal\pinmap.h
+        // STM_PIN_CHANNEL() の定義:PinNamesTypes.h
+
+        // ADC の CR1 の設定
+        myAdc_->CR1 = 0x0;  // 12bit, 非Scan モード,AD 変換終了割込みを禁止
+        // ADC の CR2 の設定
+        myAdc_->CR2 = ADC_EXTERNALTRIGCONVEDGE_RISING   // 外部トリガの立ち上がりで開始される
+                    | ADC_EXTERNALTRIGCONV_T8_TRGO      // 外部トリガ: Timer8 TRGO event
+                    | ADC_CR2_ADON;                     // ADC を有効にする
+
+        // AD 変換器の外部トリガに使うタイマ (TIM8) の設定
+        SetTim8(fSampling);
+    }
+
+    // AD 変換器の外部トリガに使うタイマ (TIM8) の設定
+    //      fSampling 標本化周波数 [kHz]
+    void AdcF446_Base::SetTim8(float fSampling)
+    {
+        __HAL_RCC_TIM8_CLK_ENABLE();    // クロック供給. "stm32f4xx_hal_rcc.h" 参照
+        TIM_TypeDef* const TIM = TIM8;
+
+        TIM->CR2 = TIM_TRGO_UPDATE;     // Update event を TRGO (trigger output) とする
+
+        float arrF = (SystemCoreClock/fSampling)/1000.0f;
+        if (arrF >65535)
+        {
+            fprintf(stderr, "%8.2f kHz : 標本化周波数が低すぎます.\r\n", fSampling);
+            while (true) {}
+        }
+        TIM->ARR = floor(arrF + 0.5f) - 1;  // Auto-reload レジスタの設定
+        TIM->PSC = 0;                   // Prescaler の設定
+        TIM->CR1 = TIM_CR1_CEN;         // TIM8 を有効にする
+    }
+
+    // AD 変換器に関係のある GPIO の設定
+    void AdcF446_Base::SetGPIO(PinName pin)
+    {
+        // 各シンボルは stm32f4xx_hal_gpio.h で定義されている
+        // MODIFY_REG() マクロは stm32f4xx.h で定義されている
+        uint32_t nShift = STM_PIN(pin) << 1;
+        uint32_t moder = GPIO_MODE_ANALOG << nShift;
+        uint32_t mask = 0x03 << nShift;
+        switch (STM_PORT(pin))
+        {
+            case 0:
+                if (__HAL_RCC_GPIOA_IS_CLK_DISABLED())
+                    __HAL_RCC_GPIOA_CLK_ENABLE();       // GPIOA にクロックを供給
+                MODIFY_REG(GPIOA->MODER, mask, moder);  // GPIOA のピンを設定
+                break;
+            case 1:
+                if (__HAL_RCC_GPIOB_IS_CLK_DISABLED())
+                    __HAL_RCC_GPIOB_CLK_ENABLE();       // GPIOB にクロックを供給
+                MODIFY_REG(GPIOB->MODER, mask, moder);  // GPIOB のピンを設定
+                break;
+            case 2:
+                if (__HAL_RCC_GPIOC_IS_CLK_DISABLED())
+                    __HAL_RCC_GPIOC_CLK_ENABLE();       // GPIOC にクロックを供給
+                MODIFY_REG(GPIOC->MODER, mask, moder);  // GPIOC のピンを設定
+                break;
+        }
+    }
+
+    // static メンバの実体
+    ADC_TypeDef* const AdcF446_Base::myAdc_ = ADC2;
+}
+