CQエレクトロニクス・セミナ「実習・マイコンを動かしながら学ぶディジタル・フィルタ」で使うプログラムを,入力として STM32F746 の内蔵 ADC を使うように変更したもの. http://seminar.cqpub.co.jp/ccm/ES18-0020
Dependencies: mbed Array_Matrix BSP_DISCO_F746NG LCD_DISCO_F746NG TS_DISCO_F746NG
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 }
Generated on Sun Jul 17 2022 01:09:34 by 1.7.2