Added one channel mode

Dependents:   CW_Decoder_using_FFT_on_F446

Fork of F446_AD_DA by 不韋 呂

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?

UserRevisionLine numberNew 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