CQエレクトロニクス・セミナ「実習・マイコンを動かしながら学ぶディジタル・フィルタ」で使うプログラムを,入力として STM32F746 の内蔵 ADC を使うように変更したもの. http://seminar.cqpub.co.jp/ccm/ES18-0020

Dependencies:   mbed Array_Matrix BSP_DISCO_F746NG LCD_DISCO_F746NG TS_DISCO_F746NG

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers F746_ADC.cpp Source File

F746_ADC.cpp

00001 //----------------------------------------------------------
00002 //  Simultanuous AD Conversion by polling using
00003 //  ADC1 and ADC3 on STM32F746
00004 //
00005 //  STM32F746 の ADC1, ADC3 を使って同時に AD 変換を開始し,
00006 //  ポーリングによりアナログ信号を入力するクラス
00007 //
00008 //      PA_0  (DISCO-F746 の A0) :  ADC1 CH0
00009 //      PF_10 (DISCO-F746 の A1) :  ADC3 CH8
00010 //
00011 //  2017/08/16, Copyright (c) 2017 MIKAMI, Naoki
00012 //----------------------------------------------------------
00013 
00014 #include "F746_ADC.hpp"
00015 
00016 namespace Mikami
00017 {
00018     AdcDual::AdcDual(int frequency)
00019     {
00020         GPIO_InitTypeDef gpioInit;
00021         // 以下の三つのメンバの値は共通
00022         gpioInit.Mode = GPIO_MODE_ANALOG;
00023         gpioInit.Pull = GPIO_NOPULL;
00024         gpioInit.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
00025 
00026         // PA0 を ADC 入力として使うための設定
00027         __HAL_RCC_GPIOA_CLK_ENABLE();
00028         HAL_GPIO_DeInit(GPIOA, 0);
00029         gpioInit.Pin = GPIO_PIN_0;
00030         HAL_GPIO_Init(GPIOA, &gpioInit);
00031 
00032         // PF10 を ADC 入力として使うための設定
00033         __HAL_RCC_GPIOF_CLK_ENABLE();
00034         HAL_GPIO_DeInit(GPIOF, 10);
00035         gpioInit.Pin = GPIO_PIN_10;
00036         HAL_GPIO_Init(GPIOF, &gpioInit);
00037 
00038         // ADC1 の設定 (PA0)
00039         __HAL_RCC_ADC1_CLK_ENABLE();
00040         ADC1->CR1 = 0x0;
00041         ADC1->CR2 = ADC_EXTERNALTRIGCONVEDGE_RISING // 外部トリガの立ち上がりで開始される
00042                   | ADC_EXTERNALTRIGCONV_T6_TRGO    // 外部トリガ: Timer6 TRGO event
00043                   | ADC_CR2_ADON;                   // ADC を有効にする
00044         ADC1->SQR3 = 0x0;                           // CH0 を使う
00045 
00046         // ADC3 の設定 (PF10)
00047         __HAL_RCC_ADC3_CLK_ENABLE();
00048         ADC3->CR1 = 0x0;
00049         ADC3->CR2 = ADC_EXTERNALTRIGCONVEDGE_RISING // 外部トリガの立ち上がりで開始される
00050                   | ADC_EXTERNALTRIGCONV_T6_TRGO    // 外部トリガ: Timer6 TRGO event
00051                   | ADC_CR2_ADON;                   // ADC を有効にする
00052         ADC3->SQR3 = 0x8;                           // CH8 を使う
00053         
00054         // ADC 共通の設定
00055         ADC->CCR = 0x0;     // 念のため
00056 
00057         // AD 変換器の外部トリガに使うタイマ (TIM6) の設定
00058         SetTim6(frequency);
00059 
00060         // これを入れなければ動かない(理由は不明)
00061         __DAC_CLK_ENABLE();
00062         // 下記と同じ処理の別表現
00063         // RCC->APB1ENR |= RCC_APB1ENR_DACEN;
00064     }
00065 
00066     void AdcDual::Read(float &ad1, float &ad2)
00067     {
00068         WaitDone();
00069         ad1 = ToFloat(ADC1->DR);
00070         ad2 = ToFloat(ADC3->DR);
00071     }
00072 
00073     void AdcDual::Read(uint16_t &ad1, uint16_t &ad2)
00074     {
00075         WaitDone();
00076         ad1 = ADC1->DR;
00077         ad2 = ADC3->DR;
00078     }
00079 
00080     void AdcDual::SetTim6(int frequency)
00081     {
00082         __HAL_RCC_TIM6_CLK_ENABLE();    // Supply clock. See "stm32f7xx_hal_rcc_ex.h"
00083         SystemCoreClockUpdate();        // Update core clock. See "system_stm32f7xx.h"
00084        
00085         TIM_TypeDef* const myTim = TIM6;
00086 
00087         myTim->CR2 = TIM_CR2_MMS_1; // Update event: as trigger out
00088         
00089         uint32_t psc = 0;
00090         uint32_t arr;
00091         while (true)
00092         {
00093             // TIM6 の入力のクロックは RCC_DCKCFGR1 の TIMPRE ビットにより
00094             // 108/216 MHz のいずれかに設定される
00095             // (RM0385 Rev.2, Reference manual では RCC_DKCFGR1 となっている)
00096             if ((RCC->DCKCFGR1 & RCC_DCKCFGR1_TIMPRE) == RCC_DCKCFGR1_TIMPRE)
00097                 arr = SystemCoreClock/((psc + 1)*frequency);
00098             else
00099                 arr = (SystemCoreClock/2)/((psc + 1)*frequency);
00100             if (arr <= 65536) break;
00101             psc++;
00102         }
00103         myTim->ARR = arr - 1;       // Auto-reload
00104         myTim->PSC = psc;           // Prescaler
00105         myTim->CR1 = TIM_CR1_CEN;   // Enable TIM6
00106     }
00107 }