#include "stm32l1xx.h" volatile uint16_t adcConversions[2]; volatile uint32_t avg_value1, avg_value2; volatile uint8_t samples; // function prototypes void InitGPIO(); void InitDMA(); void InitADC(); // main program int main() { // start system 12 MHz SystemInit(); // initialize peripheral InitGPIO(); InitDMA(); InitADC(); while(1) { } } // DMA interrupt handler void DMA1_Channel1_IRQHandler() { DMA_ClearITPendingBit(DMA1_IT_TC1); // in this handler isn't much time. just do essential things avg_value1 += adcConversions[0]; avg_value2 += adcConversions[1]; samples++; } void InitGPIO() { RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); GPIO_InitTypeDef GPIOInitStruct; // initialize analog input pin (PB13) GPIOInitStruct.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13; GPIOInitStruct.GPIO_Mode = GPIO_Mode_AN; GPIOInitStruct.GPIO_OType = GPIO_OType_PP; GPIOInitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIOInitStruct.GPIO_Speed = GPIO_Speed_400KHz; GPIO_Init(GPIOB, &GPIOInitStruct); } void InitADC() { // turn on clock for ADC1 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); // initialize ADC ADC_InitTypeDef ADCInitStruct; ADCInitStruct.ADC_Resolution = ADC_Resolution_10b; ADCInitStruct.ADC_ScanConvMode = ENABLE; ADCInitStruct.ADC_ContinuousConvMode = DISABLE; ADCInitStruct.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising; ADCInitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T6_TRGO; // use hardware trigger: timer TIM6 ADCInitStruct.ADC_DataAlign = ADC_DataAlign_Right; ADCInitStruct.ADC_NbrOfConversion = 2; ADC_Init(ADC1, &ADCInitStruct); // channel configuration ADC_RegularChannelConfig(ADC1, ADC_Channel_18, 1, ADC_SampleTime_4Cycles); // use channel 18 (PB12) ADC_RegularChannelConfig(ADC1, ADC_Channel_19, 2, ADC_SampleTime_4Cycles); // use channel 19 (PB13) // enable DMA request after last transfer (Single-ADC mode) ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE); // turn on clock for timer TIM6 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); // initialize timer TIM_TimeBaseInitTypeDef TIMInitStruct; TIMInitStruct.TIM_Prescaler = 1; TIMInitStruct.TIM_Period = 100; TIMInitStruct.TIM_ClockDivision = 1; TIM_TimeBaseInit(TIM6, &TIMInitStruct); // trigger mode: update TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update); ADC_DMACmd(ADC1, ENABLE); // enable ADC1 ADC_Cmd(ADC1, ENABLE); // enable timer TIM_Cmd(TIM6, ENABLE); // turn on HSI (required for ADC) RCC_HSICmd(ENABLE); while(!RCC_GetFlagStatus(RCC_FLAG_HSIRDY)); } void InitDMA() { // turn on clock for DMA RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // configure DMA DMA_InitTypeDef DMA_InitStructure; DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&adcConversions; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = 2; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel1, &DMA_InitStructure); // enable interrupt for DMA DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE); // initialize interrupt for DMA NVIC_InitTypeDef INTInitStructDMA; INTInitStructDMA.NVIC_IRQChannel = DMA1_Channel1_IRQn; INTInitStructDMA.NVIC_IRQChannelCmd = ENABLE; INTInitStructDMA.NVIC_IRQChannelPreemptionPriority = 0; INTInitStructDMA.NVIC_IRQChannelSubPriority = 0; NVIC_Init(&INTInitStructDMA); // enable DMA DMA_Cmd(DMA1_Channel1, ENABLE); }