CQ出版社セミナ "実習・Armマイコン内蔵ペリフェラルを活用するためのC++プログラミング" で使う外付け回路のテスト
Dependencies: mbed UIT_SetOutputPortType UIT_AQM1602 UIT_ADT7410
Diff: F446_ADDA/F446_AdcBase.cpp
- 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; +} +