AD変換(DMA使用)
Revision 0:c5f50c994173, committed 2018-07-17
- 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