Nucleo-F446RE 内蔵の AD/DA を使うためのライブラリ.DA からの出力は,標本化周波数の4倍のレートで行う.出力の補間フィルタには直線位相の FIR フィルタを使用.  このライブラリを登録した際のプログラム: Demo_F446_AD_DA_MultirateLinearPhase. Library for built-in ADC and DAC in Nucleo-F446RE. Sampling rate for DAC is four times of that for ADC. Interpolation filter for output is linear-phase FIR filter.

Dependencies:   Array_Matrix

Dependents:   Demo_F446_AD_DA_MultirateLinearPhase

Committer:
MikamiUitOpen
Date:
Wed Nov 28 12:45:18 2018 +0000
Revision:
1:cd42ecc1e174
Parent:
0:ad30ac2b412b
2

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MikamiUitOpen 0:ad30ac2b412b 1 //----------------------------------------------------------------
MikamiUitOpen 0:ad30ac2b412b 2 // AD Conversion by interrupt using ADC2 or ADC3 on STM32F446
MikamiUitOpen 0:ad30ac2b412b 3 //
MikamiUitOpen 0:ad30ac2b412b 4 // STM32F446 の ADC2 または ADC3 を使って割込みによりアナログ信号を
MikamiUitOpen 0:ad30ac2b412b 5 // 入力するクラス ― マルチ・レート処理用
MikamiUitOpen 0:ad30ac2b412b 6 //
MikamiUitOpen 0:ad30ac2b412b 7 // 2018/04/18, Copyright (c) 2018 MIKAMI, Naoki
MikamiUitOpen 0:ad30ac2b412b 8 //----------------------------------------------------------------
MikamiUitOpen 0:ad30ac2b412b 9
MikamiUitOpen 0:ad30ac2b412b 10 #include "F446_ADC.hpp"
MikamiUitOpen 0:ad30ac2b412b 11
MikamiUitOpen 0:ad30ac2b412b 12 namespace Mikami
MikamiUitOpen 0:ad30ac2b412b 13 {
MikamiUitOpen 0:ad30ac2b412b 14 AdcF446::AdcF446(int frequency, PinName pin)
MikamiUitOpen 0:ad30ac2b412b 15 {
MikamiUitOpen 0:ad30ac2b412b 16 if ( (pin != A0) && (pin != A1) )
MikamiUitOpen 0:ad30ac2b412b 17 {
MikamiUitOpen 0:ad30ac2b412b 18 fprintf(stderr, "Invalid pin name\r\n");
MikamiUitOpen 0:ad30ac2b412b 19 while (true) {}
MikamiUitOpen 0:ad30ac2b412b 20 }
MikamiUitOpen 0:ad30ac2b412b 21
MikamiUitOpen 0:ad30ac2b412b 22 // PA0 または PA1 を ADC 入力として使うための設定
MikamiUitOpen 0:ad30ac2b412b 23 __HAL_RCC_GPIOA_CLK_ENABLE();
MikamiUitOpen 0:ad30ac2b412b 24 GPIO_InitTypeDef gpioInit;
MikamiUitOpen 0:ad30ac2b412b 25 gpioInit.Pin = (pin == A0) ? GPIO_PIN_0 : GPIO_PIN_1;
MikamiUitOpen 0:ad30ac2b412b 26 gpioInit.Mode = GPIO_MODE_ANALOG;
MikamiUitOpen 0:ad30ac2b412b 27 gpioInit.Pull = GPIO_NOPULL;
MikamiUitOpen 0:ad30ac2b412b 28 gpioInit.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
MikamiUitOpen 0:ad30ac2b412b 29 HAL_GPIO_Init(GPIOA, &gpioInit);
MikamiUitOpen 0:ad30ac2b412b 30
MikamiUitOpen 0:ad30ac2b412b 31 if (pin == A0) // ADC2 の設定 (入力ポート:PA0)
MikamiUitOpen 0:ad30ac2b412b 32 {
MikamiUitOpen 0:ad30ac2b412b 33 __HAL_RCC_ADC2_CLK_ENABLE();
MikamiUitOpen 0:ad30ac2b412b 34 adc_ = ADC2;
MikamiUitOpen 0:ad30ac2b412b 35 adc_->SQR3 = 0x0; // CH0 を使う
MikamiUitOpen 0:ad30ac2b412b 36 }
MikamiUitOpen 0:ad30ac2b412b 37 else // ADC3 の設定 (入力ポート:PA1)
MikamiUitOpen 0:ad30ac2b412b 38 {
MikamiUitOpen 0:ad30ac2b412b 39 __HAL_RCC_ADC3_CLK_ENABLE();
MikamiUitOpen 0:ad30ac2b412b 40 adc_ = ADC3;
MikamiUitOpen 0:ad30ac2b412b 41 adc_->SQR3 = 0x1; // CH1 を使う
MikamiUitOpen 0:ad30ac2b412b 42 }
MikamiUitOpen 0:ad30ac2b412b 43 adc_->CR2 = ADC_EXTERNALTRIGCONVEDGE_RISING // 外部トリガの立ち上がりで開始される
MikamiUitOpen 0:ad30ac2b412b 44 | ADC_EXTERNALTRIGCONV_T8_TRGO // 外部トリガ: Timer8 TRGO event
MikamiUitOpen 0:ad30ac2b412b 45 | ADC_CR2_ADON; // ADC を有効にする
MikamiUitOpen 0:ad30ac2b412b 46 adc_->CR1 = ADC_CR1_EOCIE; // ADC の変換終了割り込みを有効にする
MikamiUitOpen 0:ad30ac2b412b 47
MikamiUitOpen 0:ad30ac2b412b 48 // ADC 共通の設定
MikamiUitOpen 0:ad30ac2b412b 49 ADC->CCR = 0x0; // 念のため
MikamiUitOpen 0:ad30ac2b412b 50
MikamiUitOpen 0:ad30ac2b412b 51 // AD 変換器の外部トリガに使うタイマ (TIM8) の設定
MikamiUitOpen 0:ad30ac2b412b 52 // 標本化周波数としてアップサンプリングに対応する値を設定する
MikamiUitOpen 0:ad30ac2b412b 53 SetTim8(frequency);
MikamiUitOpen 0:ad30ac2b412b 54 }
MikamiUitOpen 0:ad30ac2b412b 55
MikamiUitOpen 0:ad30ac2b412b 56 // 割込みベクタを設定し,ADC 割込みを有効にする
MikamiUitOpen 0:ad30ac2b412b 57 void AdcF446::SetIntrVec(void (*Func)())
MikamiUitOpen 0:ad30ac2b412b 58 {
MikamiUitOpen 0:ad30ac2b412b 59 NVIC_SetVector(ADC_IRQn, (uint32_t)Func); // "cmsis_nvic.h" 参照
MikamiUitOpen 0:ad30ac2b412b 60 NVIC_EnableIRQ(ADC_IRQn); // "core_cm4.h" 参照
MikamiUitOpen 0:ad30ac2b412b 61 }
MikamiUitOpen 0:ad30ac2b412b 62
MikamiUitOpen 0:ad30ac2b412b 63 // AD 変換器の外部トリガに使うタイマ (TIM8) の設定
MikamiUitOpen 0:ad30ac2b412b 64 void AdcF446::SetTim8(int frequency)
MikamiUitOpen 0:ad30ac2b412b 65 {
MikamiUitOpen 0:ad30ac2b412b 66 __HAL_RCC_TIM8_CLK_ENABLE(); // クロック供給. "stm32f4xx_hal_rcc.h" 参照
MikamiUitOpen 0:ad30ac2b412b 67 SystemCoreClockUpdate(); // クロックの更新. See "system_stm32f4xx.h" 参照
MikamiUitOpen 0:ad30ac2b412b 68 TIM_TypeDef* const myTim = TIM8;
MikamiUitOpen 0:ad30ac2b412b 69
MikamiUitOpen 0:ad30ac2b412b 70 myTim->CR2 = TIM_CR2_MMS_1; // Update event を TRGO (trigger output) とする
MikamiUitOpen 0:ad30ac2b412b 71
MikamiUitOpen 0:ad30ac2b412b 72 uint32_t psc = 0;
MikamiUitOpen 0:ad30ac2b412b 73 uint16_t mul = 1;
MikamiUitOpen 0:ad30ac2b412b 74 uint32_t arr;
MikamiUitOpen 0:ad30ac2b412b 75 while (true)
MikamiUitOpen 0:ad30ac2b412b 76 {
MikamiUitOpen 0:ad30ac2b412b 77 arr = SystemCoreClock/(mul*frequency);
MikamiUitOpen 0:ad30ac2b412b 78 if (arr <= 65536) break;
MikamiUitOpen 0:ad30ac2b412b 79 psc++;
MikamiUitOpen 0:ad30ac2b412b 80 mul++;
MikamiUitOpen 0:ad30ac2b412b 81 if (psc > 65535)
MikamiUitOpen 0:ad30ac2b412b 82 {
MikamiUitOpen 0:ad30ac2b412b 83 fprintf(stderr, "Sampling frequency: too low.\r\n");
MikamiUitOpen 0:ad30ac2b412b 84 while (true) {}
MikamiUitOpen 0:ad30ac2b412b 85 }
MikamiUitOpen 0:ad30ac2b412b 86 }
MikamiUitOpen 0:ad30ac2b412b 87 myTim->ARR = arr - 1; // Auto-reload レジスタの設定
MikamiUitOpen 0:ad30ac2b412b 88 myTim->PSC = psc; // Prescaler の設定
MikamiUitOpen 0:ad30ac2b412b 89 myTim->CR1 = TIM_CR1_CEN; // TIM8 を有効にする
MikamiUitOpen 0:ad30ac2b412b 90 }
MikamiUitOpen 0:ad30ac2b412b 91 }