AD変換(DMA使用)

Dependents:   ADC_DMA ADC

adc.cpp

Committer:
k0050288
Date:
2018-07-17
Revision:
0:c5f50c994173

File content as of revision 0:c5f50c994173:

#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);
}