Added one channel mode
Dependents: CW_Decoder_using_FFT_on_F446
Fork of F446_AD_DA by
F446_ADC.cpp@4:03e91e464ce5, 2017-02-05 (annotated)
- Committer:
- kenjiArai
- Date:
- Sun Feb 05 07:59:14 2017 +0000
- Revision:
- 4:03e91e464ce5
- Parent:
- 2:29f9831ce719
added one channel mode (only A0/PA_0 input)
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
MikamiUitOpen | 0:c945b4fe9a48 | 1 | //---------------------------------------------------------- |
MikamiUitOpen | 0:c945b4fe9a48 | 2 | // Simultanuous AD Conversion by polling using |
MikamiUitOpen | 0:c945b4fe9a48 | 3 | // ADC2 and ADC3 on STM32F446 ---- Header |
MikamiUitOpen | 0:c945b4fe9a48 | 4 | // |
MikamiUitOpen | 0:c945b4fe9a48 | 5 | // STM32F446 の ADC2, ADC3 を使って同時に AD 変換を開始し, |
MikamiUitOpen | 0:c945b4fe9a48 | 6 | // ポーリングによりアナログ信号を入力するクラス |
MikamiUitOpen | 0:c945b4fe9a48 | 7 | // A0 (PA_0) : ADC2 CH0 |
MikamiUitOpen | 0:c945b4fe9a48 | 8 | // A1 (PA_1) : ADC3 CH1 |
MikamiUitOpen | 0:c945b4fe9a48 | 9 | // |
MikamiUitOpen | 1:6b9f2af6613d | 10 | // 2016/11/12, Copyright (c) 2016 MIKAMI, Naoki |
MikamiUitOpen | 0:c945b4fe9a48 | 11 | //---------------------------------------------------------- |
kenjiArai | 4:03e91e464ce5 | 12 | /* |
kenjiArai | 4:03e91e464ce5 | 13 | * Modified by Kenji Arai |
kenjiArai | 4:03e91e464ce5 | 14 | * http://www.page.sannet.ne.jp/kenjia/index.html |
kenjiArai | 4:03e91e464ce5 | 15 | * http://mbed.org/users/kenjiArai/ |
kenjiArai | 4:03e91e464ce5 | 16 | * |
kenjiArai | 4:03e91e464ce5 | 17 | * Started: Feburary 1st, 2017 |
kenjiArai | 4:03e91e464ce5 | 18 | * Revised: Feburary 1st, 2017 |
kenjiArai | 4:03e91e464ce5 | 19 | */ |
MikamiUitOpen | 0:c945b4fe9a48 | 20 | |
MikamiUitOpen | 0:c945b4fe9a48 | 21 | #include "F446_ADC.hpp" |
MikamiUitOpen | 0:c945b4fe9a48 | 22 | |
MikamiUitOpen | 0:c945b4fe9a48 | 23 | namespace Mikami |
MikamiUitOpen | 0:c945b4fe9a48 | 24 | { |
MikamiUitOpen | 0:c945b4fe9a48 | 25 | AdcDual::AdcDual(int frequency) |
MikamiUitOpen | 0:c945b4fe9a48 | 26 | { |
MikamiUitOpen | 2:29f9831ce719 | 27 | // PA0, PA1 を ADC 入力として使うための設定 |
MikamiUitOpen | 0:c945b4fe9a48 | 28 | __HAL_RCC_GPIOA_CLK_ENABLE(); |
MikamiUitOpen | 0:c945b4fe9a48 | 29 | GPIO_InitTypeDef gpioInit; |
MikamiUitOpen | 0:c945b4fe9a48 | 30 | gpioInit.Pin = GPIO_PIN_0 | GPIO_PIN_1; |
MikamiUitOpen | 0:c945b4fe9a48 | 31 | gpioInit.Mode = GPIO_MODE_ANALOG; |
MikamiUitOpen | 0:c945b4fe9a48 | 32 | gpioInit.Pull = GPIO_NOPULL; |
MikamiUitOpen | 0:c945b4fe9a48 | 33 | gpioInit.Speed = GPIO_SPEED_FREQ_VERY_HIGH; |
MikamiUitOpen | 0:c945b4fe9a48 | 34 | HAL_GPIO_Init(GPIOA, &gpioInit); |
MikamiUitOpen | 0:c945b4fe9a48 | 35 | |
MikamiUitOpen | 2:29f9831ce719 | 36 | // ADC2 の設定 (入力ポート:PA0) |
MikamiUitOpen | 0:c945b4fe9a48 | 37 | __HAL_RCC_ADC2_CLK_ENABLE(); |
MikamiUitOpen | 0:c945b4fe9a48 | 38 | ADC2->CR1 = 0x0; |
MikamiUitOpen | 0:c945b4fe9a48 | 39 | ADC2->CR2 = ADC_EXTERNALTRIGCONVEDGE_RISING // 外部トリガの立ち上がりで開始される |
MikamiUitOpen | 0:c945b4fe9a48 | 40 | | ADC_EXTERNALTRIGCONV_T8_TRGO // 外部トリガ: Timer8 TRGO event |
MikamiUitOpen | 0:c945b4fe9a48 | 41 | | ADC_CR2_ADON; // ADC を有効にする |
MikamiUitOpen | 0:c945b4fe9a48 | 42 | ADC2->SQR3 = 0x0; // CH0 を使う |
MikamiUitOpen | 0:c945b4fe9a48 | 43 | |
MikamiUitOpen | 2:29f9831ce719 | 44 | // ADC3 の設定 (入力ポート:PA1) |
MikamiUitOpen | 0:c945b4fe9a48 | 45 | __HAL_RCC_ADC3_CLK_ENABLE(); |
MikamiUitOpen | 0:c945b4fe9a48 | 46 | ADC3->CR1 = 0x0; |
MikamiUitOpen | 0:c945b4fe9a48 | 47 | ADC3->CR2 = ADC_EXTERNALTRIGCONVEDGE_RISING // 外部トリガの立ち上がりで開始される |
MikamiUitOpen | 0:c945b4fe9a48 | 48 | | ADC_EXTERNALTRIGCONV_T8_TRGO // 外部トリガ: Timer8 TRGO event |
MikamiUitOpen | 0:c945b4fe9a48 | 49 | | ADC_CR2_ADON; // ADC を有効にする |
MikamiUitOpen | 0:c945b4fe9a48 | 50 | ADC3->SQR3 = 0x1; // CH1 を使う |
MikamiUitOpen | 0:c945b4fe9a48 | 51 | |
MikamiUitOpen | 0:c945b4fe9a48 | 52 | // ADC 共通の設定 |
MikamiUitOpen | 0:c945b4fe9a48 | 53 | ADC->CCR = 0x0; // 念のため |
MikamiUitOpen | 0:c945b4fe9a48 | 54 | |
MikamiUitOpen | 0:c945b4fe9a48 | 55 | // AD 変換器の外部トリガに使うタイマ (TIM8) の設定 |
MikamiUitOpen | 0:c945b4fe9a48 | 56 | SetTim8(frequency); |
MikamiUitOpen | 0:c945b4fe9a48 | 57 | } |
MikamiUitOpen | 0:c945b4fe9a48 | 58 | |
MikamiUitOpen | 0:c945b4fe9a48 | 59 | void AdcDual::Read(float &ad1, float &ad2) |
MikamiUitOpen | 0:c945b4fe9a48 | 60 | { |
MikamiUitOpen | 0:c945b4fe9a48 | 61 | WaitDone(); |
MikamiUitOpen | 0:c945b4fe9a48 | 62 | ad1 = ToFloat(ADC2->DR); |
MikamiUitOpen | 0:c945b4fe9a48 | 63 | ad2 = ToFloat(ADC3->DR); |
MikamiUitOpen | 0:c945b4fe9a48 | 64 | } |
MikamiUitOpen | 0:c945b4fe9a48 | 65 | |
MikamiUitOpen | 0:c945b4fe9a48 | 66 | void AdcDual::Read(uint16_t &ad1, uint16_t &ad2) |
MikamiUitOpen | 0:c945b4fe9a48 | 67 | { |
MikamiUitOpen | 0:c945b4fe9a48 | 68 | WaitDone(); |
MikamiUitOpen | 0:c945b4fe9a48 | 69 | ad1 = ADC2->DR; |
MikamiUitOpen | 0:c945b4fe9a48 | 70 | ad2 = ADC3->DR; |
MikamiUitOpen | 0:c945b4fe9a48 | 71 | } |
MikamiUitOpen | 0:c945b4fe9a48 | 72 | |
MikamiUitOpen | 0:c945b4fe9a48 | 73 | void AdcDual::SetTim8(int frequency) |
MikamiUitOpen | 0:c945b4fe9a48 | 74 | { |
MikamiUitOpen | 0:c945b4fe9a48 | 75 | __HAL_RCC_TIM8_CLK_ENABLE(); // Supply clock. See "stm32f4xx_hal_rcc.h" |
MikamiUitOpen | 0:c945b4fe9a48 | 76 | SystemCoreClockUpdate(); // Update core clock. See "system_stm32f4xx.h" |
MikamiUitOpen | 0:c945b4fe9a48 | 77 | TIM_TypeDef* const myTim = TIM8; |
MikamiUitOpen | 0:c945b4fe9a48 | 78 | |
MikamiUitOpen | 0:c945b4fe9a48 | 79 | myTim->CR2 = TIM_CR2_MMS_1; // Update event: as trigger out |
MikamiUitOpen | 0:c945b4fe9a48 | 80 | |
MikamiUitOpen | 0:c945b4fe9a48 | 81 | uint32_t psc = 0; |
MikamiUitOpen | 0:c945b4fe9a48 | 82 | uint16_t mul = 1; |
MikamiUitOpen | 0:c945b4fe9a48 | 83 | uint32_t arr; |
MikamiUitOpen | 0:c945b4fe9a48 | 84 | while (true) |
MikamiUitOpen | 0:c945b4fe9a48 | 85 | { |
MikamiUitOpen | 0:c945b4fe9a48 | 86 | arr = SystemCoreClock/(mul*frequency); |
MikamiUitOpen | 0:c945b4fe9a48 | 87 | if (arr <= 65536) break; |
MikamiUitOpen | 0:c945b4fe9a48 | 88 | psc++; |
MikamiUitOpen | 0:c945b4fe9a48 | 89 | mul++; |
MikamiUitOpen | 0:c945b4fe9a48 | 90 | if (psc > 65535) |
MikamiUitOpen | 0:c945b4fe9a48 | 91 | { |
MikamiUitOpen | 0:c945b4fe9a48 | 92 | fprintf(stderr, "Sampling frequency: too low.\r\n"); |
MikamiUitOpen | 0:c945b4fe9a48 | 93 | while (true) {} |
MikamiUitOpen | 0:c945b4fe9a48 | 94 | } |
MikamiUitOpen | 0:c945b4fe9a48 | 95 | } |
MikamiUitOpen | 0:c945b4fe9a48 | 96 | myTim->ARR = arr - 1; // Auto-reload |
MikamiUitOpen | 0:c945b4fe9a48 | 97 | myTim->PSC = psc; // Prescaler |
MikamiUitOpen | 0:c945b4fe9a48 | 98 | myTim->CR1 = TIM_CR1_CEN; // Enable TIM8 |
MikamiUitOpen | 0:c945b4fe9a48 | 99 | } |
kenjiArai | 4:03e91e464ce5 | 100 | |
kenjiArai | 4:03e91e464ce5 | 101 | //------------------------------------------------------------------------------ |
kenjiArai | 4:03e91e464ce5 | 102 | |
kenjiArai | 4:03e91e464ce5 | 103 | AdcSingle::AdcSingle(int frequency) |
kenjiArai | 4:03e91e464ce5 | 104 | { |
kenjiArai | 4:03e91e464ce5 | 105 | // ADC input is assigned PA0 |
kenjiArai | 4:03e91e464ce5 | 106 | __HAL_RCC_GPIOA_CLK_ENABLE(); |
kenjiArai | 4:03e91e464ce5 | 107 | GPIO_InitTypeDef gpioInit; |
kenjiArai | 4:03e91e464ce5 | 108 | gpioInit.Pin = GPIO_PIN_0; |
kenjiArai | 4:03e91e464ce5 | 109 | gpioInit.Mode = GPIO_MODE_ANALOG; |
kenjiArai | 4:03e91e464ce5 | 110 | gpioInit.Pull = GPIO_NOPULL; |
kenjiArai | 4:03e91e464ce5 | 111 | gpioInit.Speed = GPIO_SPEED_FREQ_VERY_HIGH; |
kenjiArai | 4:03e91e464ce5 | 112 | HAL_GPIO_Init(GPIOA, &gpioInit); |
kenjiArai | 4:03e91e464ce5 | 113 | |
kenjiArai | 4:03e91e464ce5 | 114 | // ADC2 (port:PA0) |
kenjiArai | 4:03e91e464ce5 | 115 | __HAL_RCC_ADC2_CLK_ENABLE(); |
kenjiArai | 4:03e91e464ce5 | 116 | ADC2->CR1 = 0x0; |
kenjiArai | 4:03e91e464ce5 | 117 | ADC2->CR2 = ADC_EXTERNALTRIGCONVEDGE_RISING // Ext. trigger + rising eggde |
kenjiArai | 4:03e91e464ce5 | 118 | | ADC_EXTERNALTRIGCONV_T8_TRGO // Ext. trigger Timer8 TRGO event |
kenjiArai | 4:03e91e464ce5 | 119 | | ADC_CR2_ADON; // ADC を有効にする |
kenjiArai | 4:03e91e464ce5 | 120 | ADC2->SQR3 = 0x0; // CH0 を使う |
kenjiArai | 4:03e91e464ce5 | 121 | |
kenjiArai | 4:03e91e464ce5 | 122 | // ADC 共通の設定 |
kenjiArai | 4:03e91e464ce5 | 123 | ADC->CCR = 0x0; // 念のため |
kenjiArai | 4:03e91e464ce5 | 124 | |
kenjiArai | 4:03e91e464ce5 | 125 | // AD 変換器の外部トリガに使うタイマ (TIM8) の設定 |
kenjiArai | 4:03e91e464ce5 | 126 | SetTim8(frequency); |
kenjiArai | 4:03e91e464ce5 | 127 | } |
kenjiArai | 4:03e91e464ce5 | 128 | |
kenjiArai | 4:03e91e464ce5 | 129 | void AdcSingle::Read(float &ad) |
kenjiArai | 4:03e91e464ce5 | 130 | { |
kenjiArai | 4:03e91e464ce5 | 131 | WaitDone(); |
kenjiArai | 4:03e91e464ce5 | 132 | ad = ToFloat(ADC2->DR); |
kenjiArai | 4:03e91e464ce5 | 133 | } |
kenjiArai | 4:03e91e464ce5 | 134 | |
kenjiArai | 4:03e91e464ce5 | 135 | void AdcSingle::Read(uint16_t &ad) |
kenjiArai | 4:03e91e464ce5 | 136 | { |
kenjiArai | 4:03e91e464ce5 | 137 | WaitDone(); |
kenjiArai | 4:03e91e464ce5 | 138 | ad = ADC2->DR; |
kenjiArai | 4:03e91e464ce5 | 139 | } |
kenjiArai | 4:03e91e464ce5 | 140 | |
kenjiArai | 4:03e91e464ce5 | 141 | void AdcSingle::SetTim8(int frequency) |
kenjiArai | 4:03e91e464ce5 | 142 | { |
kenjiArai | 4:03e91e464ce5 | 143 | __HAL_RCC_TIM8_CLK_ENABLE(); // Supply clock. See "stm32f4xx_hal_rcc.h" |
kenjiArai | 4:03e91e464ce5 | 144 | SystemCoreClockUpdate(); // Update core clock. See "system_stm32f4xx.h" |
kenjiArai | 4:03e91e464ce5 | 145 | TIM_TypeDef* const myTim = TIM8; |
kenjiArai | 4:03e91e464ce5 | 146 | |
kenjiArai | 4:03e91e464ce5 | 147 | myTim->CR2 = TIM_CR2_MMS_1; // Update event: as trigger out |
kenjiArai | 4:03e91e464ce5 | 148 | |
kenjiArai | 4:03e91e464ce5 | 149 | uint32_t psc = 0; |
kenjiArai | 4:03e91e464ce5 | 150 | uint16_t mul = 1; |
kenjiArai | 4:03e91e464ce5 | 151 | uint32_t arr; |
kenjiArai | 4:03e91e464ce5 | 152 | while (true) |
kenjiArai | 4:03e91e464ce5 | 153 | { |
kenjiArai | 4:03e91e464ce5 | 154 | arr = SystemCoreClock/(mul*frequency); |
kenjiArai | 4:03e91e464ce5 | 155 | if (arr <= 65536) break; |
kenjiArai | 4:03e91e464ce5 | 156 | psc++; |
kenjiArai | 4:03e91e464ce5 | 157 | mul++; |
kenjiArai | 4:03e91e464ce5 | 158 | if (psc > 65535) |
kenjiArai | 4:03e91e464ce5 | 159 | { |
kenjiArai | 4:03e91e464ce5 | 160 | fprintf(stderr, "Sampling frequency: too low.\r\n"); |
kenjiArai | 4:03e91e464ce5 | 161 | while (true) {} |
kenjiArai | 4:03e91e464ce5 | 162 | } |
kenjiArai | 4:03e91e464ce5 | 163 | } |
kenjiArai | 4:03e91e464ce5 | 164 | myTim->ARR = arr - 1; // Auto-reload |
kenjiArai | 4:03e91e464ce5 | 165 | myTim->PSC = psc; // Prescaler |
kenjiArai | 4:03e91e464ce5 | 166 | myTim->CR1 = TIM_CR1_CEN; // Enable TIM8 |
kenjiArai | 4:03e91e464ce5 | 167 | } |
MikamiUitOpen | 1:6b9f2af6613d | 168 | } |
kenjiArai | 4:03e91e464ce5 | 169 |