Library for build-in ADC and DAC in STM32F446 mounted on Nucleo F446RE. For single channel. Nucleo F446RE に搭載されている STM32F446 の内蔵 ADC, DAC 用のライブラリ.1チャンネルで使う場合.

Dependents:   Demo_F446_AD_DA_Single F446ZE-mbed-devfiles

Committer:
MikamiUitOpen
Date:
Tue Feb 21 00:40:10 2017 +0000
Revision:
0:2a5690e56a16
1

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MikamiUitOpen 0:2a5690e56a16 1 //------------------------------------------------------------
MikamiUitOpen 0:2a5690e56a16 2 // AD Conversion by polling using ADC2 or ADC3 on STM32F446
MikamiUitOpen 0:2a5690e56a16 3 //
MikamiUitOpen 0:2a5690e56a16 4 // STM32F446 の ADC2, ADC3 を使ってポーリングによりアナログ信号を
MikamiUitOpen 0:2a5690e56a16 5 // 入力するクラス
MikamiUitOpen 0:2a5690e56a16 6 // A0 (PA_0) : ADC2 CH0
MikamiUitOpen 0:2a5690e56a16 7 // A1 (PA_1) : ADC3 CH1
MikamiUitOpen 0:2a5690e56a16 8 //
MikamiUitOpen 0:2a5690e56a16 9 // 2017/02/16, Copyright (c) 2017 MIKAMI, Naoki
MikamiUitOpen 0:2a5690e56a16 10 //------------------------------------------------------------
MikamiUitOpen 0:2a5690e56a16 11
MikamiUitOpen 0:2a5690e56a16 12 #include "F446_ADC_Single.hpp"
MikamiUitOpen 0:2a5690e56a16 13
MikamiUitOpen 0:2a5690e56a16 14 namespace Mikami
MikamiUitOpen 0:2a5690e56a16 15 {
MikamiUitOpen 0:2a5690e56a16 16 AdcSingle::AdcSingle(PinName pin, int frequency)
MikamiUitOpen 0:2a5690e56a16 17 {
MikamiUitOpen 0:2a5690e56a16 18 if ( (pin != A0) && (pin != A1) )
MikamiUitOpen 0:2a5690e56a16 19 {
MikamiUitOpen 0:2a5690e56a16 20 fprintf(stderr, "Invalid pin name\r\n");
MikamiUitOpen 0:2a5690e56a16 21 return;
MikamiUitOpen 0:2a5690e56a16 22 }
MikamiUitOpen 0:2a5690e56a16 23
MikamiUitOpen 0:2a5690e56a16 24 // PA0 または PA1 を ADC 入力として使うための設定
MikamiUitOpen 0:2a5690e56a16 25 __HAL_RCC_GPIOA_CLK_ENABLE();
MikamiUitOpen 0:2a5690e56a16 26 GPIO_InitTypeDef gpioInit;
MikamiUitOpen 0:2a5690e56a16 27 gpioInit.Pin = (pin == A0) ? GPIO_PIN_0 : GPIO_PIN_1;
MikamiUitOpen 0:2a5690e56a16 28 gpioInit.Mode = GPIO_MODE_ANALOG;
MikamiUitOpen 0:2a5690e56a16 29 gpioInit.Pull = GPIO_NOPULL;
MikamiUitOpen 0:2a5690e56a16 30 gpioInit.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
MikamiUitOpen 0:2a5690e56a16 31 HAL_GPIO_Init(GPIOA, &gpioInit);
MikamiUitOpen 0:2a5690e56a16 32
MikamiUitOpen 0:2a5690e56a16 33 if (pin == A0) // ADC2 の設定 (入力ポート:PA0)
MikamiUitOpen 0:2a5690e56a16 34 {
MikamiUitOpen 0:2a5690e56a16 35 __HAL_RCC_ADC2_CLK_ENABLE();
MikamiUitOpen 0:2a5690e56a16 36 adc_ = ADC2;
MikamiUitOpen 0:2a5690e56a16 37 adc_->SQR3 = 0x0; // CH0 を使う
MikamiUitOpen 0:2a5690e56a16 38 fpWait = &AdcSingle::WaitDone2;
MikamiUitOpen 0:2a5690e56a16 39 }
MikamiUitOpen 0:2a5690e56a16 40 else // ADC3 の設定 (入力ポート:PA1)
MikamiUitOpen 0:2a5690e56a16 41 {
MikamiUitOpen 0:2a5690e56a16 42 __HAL_RCC_ADC3_CLK_ENABLE();
MikamiUitOpen 0:2a5690e56a16 43 adc_ = ADC3;
MikamiUitOpen 0:2a5690e56a16 44 adc_->SQR3 = 0x1; // CH1 を使う
MikamiUitOpen 0:2a5690e56a16 45 fpWait = &AdcSingle::WaitDone3;
MikamiUitOpen 0:2a5690e56a16 46 }
MikamiUitOpen 0:2a5690e56a16 47 adc_->CR1 = 0x0;
MikamiUitOpen 0:2a5690e56a16 48 adc_->CR2 = ADC_EXTERNALTRIGCONVEDGE_RISING // 外部トリガの立ち上がりで開始される
MikamiUitOpen 0:2a5690e56a16 49 | ADC_EXTERNALTRIGCONV_T8_TRGO // 外部トリガ: Timer8 TRGO event
MikamiUitOpen 0:2a5690e56a16 50 | ADC_CR2_ADON; // ADC を有効にする
MikamiUitOpen 0:2a5690e56a16 51
MikamiUitOpen 0:2a5690e56a16 52 // ADC 共通の設定
MikamiUitOpen 0:2a5690e56a16 53 ADC->CCR = 0x0; // 念のため
MikamiUitOpen 0:2a5690e56a16 54
MikamiUitOpen 0:2a5690e56a16 55 // AD 変換器の外部トリガに使うタイマ (TIM8) の設定
MikamiUitOpen 0:2a5690e56a16 56 SetTim8(frequency);
MikamiUitOpen 0:2a5690e56a16 57 }
MikamiUitOpen 0:2a5690e56a16 58
MikamiUitOpen 0:2a5690e56a16 59 float AdcSingle::Read()
MikamiUitOpen 0:2a5690e56a16 60 {
MikamiUitOpen 0:2a5690e56a16 61 (this->*fpWait)();
MikamiUitOpen 0:2a5690e56a16 62 return ToFloat(adc_->DR);
MikamiUitOpen 0:2a5690e56a16 63 }
MikamiUitOpen 0:2a5690e56a16 64
MikamiUitOpen 0:2a5690e56a16 65 uint16_t AdcSingle::ReadUint()
MikamiUitOpen 0:2a5690e56a16 66 {
MikamiUitOpen 0:2a5690e56a16 67 (this->*fpWait)();
MikamiUitOpen 0:2a5690e56a16 68 return adc_->DR;
MikamiUitOpen 0:2a5690e56a16 69 }
MikamiUitOpen 0:2a5690e56a16 70
MikamiUitOpen 0:2a5690e56a16 71 void AdcSingle::SetTim8(int frequency)
MikamiUitOpen 0:2a5690e56a16 72 {
MikamiUitOpen 0:2a5690e56a16 73 __HAL_RCC_TIM8_CLK_ENABLE(); // Supply clock. See "stm32f4xx_hal_rcc.h"
MikamiUitOpen 0:2a5690e56a16 74 SystemCoreClockUpdate(); // Update core clock. See "system_stm32f4xx.h"
MikamiUitOpen 0:2a5690e56a16 75 TIM_TypeDef* const myTim = TIM8;
MikamiUitOpen 0:2a5690e56a16 76
MikamiUitOpen 0:2a5690e56a16 77 myTim->CR2 = TIM_CR2_MMS_1; // Update event: as trigger out
MikamiUitOpen 0:2a5690e56a16 78
MikamiUitOpen 0:2a5690e56a16 79 uint32_t psc = 0;
MikamiUitOpen 0:2a5690e56a16 80 uint16_t mul = 1;
MikamiUitOpen 0:2a5690e56a16 81 uint32_t arr;
MikamiUitOpen 0:2a5690e56a16 82 while (true)
MikamiUitOpen 0:2a5690e56a16 83 {
MikamiUitOpen 0:2a5690e56a16 84 arr = SystemCoreClock/(mul*frequency);
MikamiUitOpen 0:2a5690e56a16 85 if (arr <= 65536) break;
MikamiUitOpen 0:2a5690e56a16 86 psc++;
MikamiUitOpen 0:2a5690e56a16 87 mul++;
MikamiUitOpen 0:2a5690e56a16 88 if (psc > 65535)
MikamiUitOpen 0:2a5690e56a16 89 {
MikamiUitOpen 0:2a5690e56a16 90 fprintf(stderr, "Sampling frequency: too low.\r\n");
MikamiUitOpen 0:2a5690e56a16 91 while (true) {}
MikamiUitOpen 0:2a5690e56a16 92 }
MikamiUitOpen 0:2a5690e56a16 93 }
MikamiUitOpen 0:2a5690e56a16 94 myTim->ARR = arr - 1; // Auto-reload
MikamiUitOpen 0:2a5690e56a16 95 myTim->PSC = psc; // Prescaler
MikamiUitOpen 0:2a5690e56a16 96 myTim->CR1 = TIM_CR1_CEN; // Enable TIM8
MikamiUitOpen 0:2a5690e56a16 97 }
MikamiUitOpen 0:2a5690e56a16 98 }