AD変換(DMA使用)

Dependents:   ADC_DMA ADC

Revision:
0:c5f50c994173
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/adc.cpp	Tue Jul 17 04:49:30 2018 +0000
@@ -0,0 +1,85 @@
+#include "adc.h"
+
+AnalogIn adc(A0);    // init GPIO stuff
+
+/* HAL objects */
+static ADC_HandleTypeDef hadc1;
+static DMA_HandleTypeDef hdma_adc1;
+
+void adc::init()
+{
+    ADC_init();
+    DMA_init();
+    
+    memset(ADCVal, 0, sizeof(ADCVal));
+}
+
+void adc::read(uint16_t *data, uint32_t length)
+{
+    ADC_ChannelConfTypeDef sConfig;
+    
+    sConfig.Channel      = ADC_CHANNEL_0;   // チャンネル0(ADC1_IN0:PA0)を使用
+    sConfig.Rank         = 1;
+    sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
+    sConfig.Offset       = 0;
+    
+    HAL_ADC_ConfigChannel(&hadc1, &sConfig);
+
+    HAL_ADC_Start_DMA(&hadc1, (uint32_t *)data, length / 2);
+    while (hdma_adc1.Instance->CR & DMA_SxCR_EN);   // spin
+    HAL_ADC_Stop(&hadc1);
+}
+
+void adc::ADC_init()
+{
+    /* Peripheral clock enable */
+    __ADC1_CLK_ENABLE();
+    
+    /* Config ADC */
+    hadc1.Instance                   = (ADC_TypeDef *)ADC1;
+    hadc1.Init.ClockPrescaler        = ADC_CLOCKPRESCALER_PCLK_DIV4;   // ADCクロックプリスケーラ4
+    hadc1.Init.Resolution            = ADC_RESOLUTION12b;              // 分解能12bit
+    hadc1.Init.ScanConvMode          = DISABLE;                        // ENABLE:スキャンモード DISABLE:分割スキャンモード
+    hadc1.Init.ContinuousConvMode    = ENABLE;                         // ENABLE:連続変換モード DISABLE:シングルモード
+    hadc1.Init.DiscontinuousConvMode = DISABLE;                        // 連続変換モード無効時、このパラメータは無効
+    hadc1.Init.NbrOfDiscConversion   = 0;
+    hadc1.Init.ExternalTrigConvEdge  = ADC_EXTERNALTRIGCONVEDGE_NONE;  // 変換開始の外部トリガなし
+    hadc1.Init.ExternalTrigConv      = ADC_EXTERNALTRIGCONV_T1_CC1;
+    hadc1.Init.DataAlign             = ADC_DATAALIGN_RIGHT;            // 変換データを右詰め(RIGHT)か左詰め(LEFT)のどちらかを選択
+    hadc1.Init.NbrOfConversion       = 1;                              // AD変換する合計チャンネル数
+    hadc1.Init.DMAContinuousRequests = ENABLE;                         // DMAコンテニューリクエスト
+    hadc1.Init.EOCSelection          = DISABLE;
+  
+    /* 設定を反映 */
+    HAL_ADC_Init(&hadc1); 
+}
+
+void adc::DMA_init()
+{
+    /* Peripheral clock enable */
+    __DMA2_CLK_ENABLE();
+    
+    /* Config DMA */
+    hdma_adc1.Instance                 = DMA2_Stream0;
+    hdma_adc1.State                    = HAL_DMA_STATE_READY;
+    HAL_DMA_DeInit(&hdma_adc1);
+    
+    hdma_adc1.Init.Channel             = DMA_CHANNEL_0;
+    hdma_adc1.Init.Direction           = DMA_PERIPH_TO_MEMORY;
+    hdma_adc1.Init.PeriphInc           = DMA_PINC_DISABLE;
+    hdma_adc1.Init.MemInc              = DMA_MINC_ENABLE;
+    hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
+    hdma_adc1.Init.MemDataAlignment    = DMA_MDATAALIGN_HALFWORD;
+    hdma_adc1.Init.Mode                = DMA_NORMAL;
+    hdma_adc1.Init.Priority            = DMA_PRIORITY_HIGH;
+    hdma_adc1.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
+    hdma_adc1.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_HALFFULL;
+    hdma_adc1.Init.MemBurst            = DMA_MBURST_SINGLE;   
+    hdma_adc1.Init.PeriphBurst         = DMA_PBURST_SINGLE;
+    
+    /* 設定を反映 */
+    HAL_DMA_Init(&hdma_adc1);
+    
+    /* 設定されたDMAハンドルをADC_DMAハンドルに関連付ける */
+    __HAL_LINKDMA(&hadc1, DMA_Handle, hdma_adc1);
+}
\ No newline at end of file