AD変換(DMA使用)

Dependents:   ADC_DMA ADC

Files at this revision

API Documentation at this revision

Comitter:
k0050288
Date:
Tue Jul 17 04:49:30 2018 +0000
Commit message:
AD??(DMA??)

Changed in this revision

adc.cpp Show annotated file Show diff for this revision Revisions of this file
adc.h Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r c5f50c994173 adc.cpp
--- /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
diff -r 000000000000 -r c5f50c994173 adc.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/adc.h	Tue Jul 17 04:49:30 2018 +0000
@@ -0,0 +1,21 @@
+#ifndef _ADC_H
+#define _ADC_H
+
+#include <stdint.h>
+#include "mbed.h"
+
+#define ADC_TIMES  4000
+
+class adc{
+private:
+    void ADC_init();
+    void DMA_init();
+
+public:
+    void init();
+    void read(uint16_t *data, uint32_t length);
+    
+    uint16_t ADCVal[ADC_TIMES];        // ADC result
+};
+
+#endif