Nucleo-F446RE 内蔵の AD/DA を使うためのライブラリ.DA からの出力は,標本化周波数の4倍のレートで行う.  このライブラリを登録した際のプログラム: Demo_F446_AD_DA_Multirate. Library for built-in ADC and DAC in Nucleo-F446RE. Sampling rate for DAC is four times of that for ADC.

Dependencies:   Array_Matrix

Dependents:   F446_UpSampling_GraphicEqualizer F446_UpSampling_ReverbSystem F446_UpSampling_FrqShifter_Weaver Demo_F446_AD_DA_Multirate ... more

Revision:
0:2447a7d225b1
Child:
3:285cebe5823c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/F446_ADC.cpp	Wed May 16 01:40:50 2018 +0000
@@ -0,0 +1,91 @@
+//----------------------------------------------------------------
+//  AD Conversion by interrupt using ADC2 or ADC3 on STM32F446
+//
+//  STM32F446 の ADC2 または ADC3 を使って割込みによりアナログ信号を
+//  入力するクラス ― マルチ・レート処理用
+//
+//  2018/04/18, Copyright (c) 2018 MIKAMI, Naoki
+//----------------------------------------------------------------
+
+#include "F446_ADC.hpp"
+
+namespace Mikami
+{
+    AdcF446::AdcF446(int frequency, PinName pin)
+    {
+        if ( (pin != A0) && (pin != A1) )
+        {
+        	fprintf(stderr, "Invalid pin name\r\n");
+        	while (true) {}
+        }
+       
+        // PA0 または PA1 を ADC 入力として使うための設定
+        __HAL_RCC_GPIOA_CLK_ENABLE();
+        GPIO_InitTypeDef gpioInit;
+        gpioInit.Pin = (pin == A0) ? GPIO_PIN_0 : GPIO_PIN_1;
+        gpioInit.Mode = GPIO_MODE_ANALOG;
+        gpioInit.Pull = GPIO_NOPULL;
+        gpioInit.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+        HAL_GPIO_Init(GPIOA, &gpioInit);
+
+        if (pin == A0)	// ADC2 の設定 (入力ポート:PA0)
+        {
+	        __HAL_RCC_ADC2_CLK_ENABLE();
+	        adc_ = ADC2;
+	        adc_->SQR3 = 0x0;		// CH0 を使う
+		}
+		else			// ADC3 の設定 (入力ポート:PA1)
+		{
+    	    __HAL_RCC_ADC3_CLK_ENABLE();
+    	    adc_ = ADC3;
+	        adc_->SQR3 = 0x1;       // CH1 を使う
+        }
+       	adc_->CR2 = ADC_EXTERNALTRIGCONVEDGE_RISING // 外部トリガの立ち上がりで開始される
+           	      | ADC_EXTERNALTRIGCONV_T8_TRGO    // 外部トリガ: Timer8 TRGO event
+               	  | ADC_CR2_ADON;                   // ADC を有効にする
+        adc_->CR1 = ADC_CR1_EOCIE;					// ADC の変換終了割り込みを有効にする
+
+        // ADC 共通の設定
+        ADC->CCR = 0x0;     // 念のため
+
+        // AD 変換器の外部トリガに使うタイマ (TIM8) の設定
+        // 標本化周波数としてアップサンプリングに対応する値を設定する
+        SetTim8(frequency);
+    }
+
+	// 割込みベクタを設定し,ADC 割込みを有効にする
+    void AdcF446::SetIntrVec(void (*Func)())
+    {
+        NVIC_SetVector(ADC_IRQn, (uint32_t)Func);   // "cmsis_nvic.h" 参照
+        NVIC_EnableIRQ(ADC_IRQn);                   // "core_cm4.h" 参照
+    }
+
+
+    void AdcF446::SetTim8(int frequency)
+    {
+        __HAL_RCC_TIM8_CLK_ENABLE();    // クロック供給. "stm32f4xx_hal_rcc.h" 参照
+        SystemCoreClockUpdate();        // クロックの更新. See "system_stm32f4xx.h" 参照
+        TIM_TypeDef* const myTim = TIM8;
+
+        myTim->CR2 = TIM_CR2_MMS_1; // Update event を TRGO (trigger output) とする
+
+    	uint32_t psc = 0;
+        uint16_t mul = 1;
+        uint32_t arr;
+        while (true)
+        {
+            arr = SystemCoreClock/(mul*frequency);
+            if (arr <= 65536) break;
+            psc++;
+            mul++;
+            if (psc > 65535)
+            {
+                fprintf(stderr, "Sampling frequency: too low.\r\n");
+                while (true) {}
+            }
+        }
+        myTim->ARR = arr - 1;       // Auto-reload レジスタの設定
+        myTim->PSC = psc;           // Prescaler の設定
+        myTim->CR1 = TIM_CR1_CEN;   // TIM8 を有効にする
+    }
+}