μC Board: STM32F429ZI-Discovery
IDE: μVision V5.13.0.0
Enable ADC Peripheral, in Triple Mode, using DMA.
CDR | ADC | Priority | Channel | Pin |
1 | ADC1 | 1 | CH13 | PC3 |
2 | ADC2 | 1 | CH00 | PA0 |
3 | ADC3 | 1 | CH15 | PF5 |
4 | ADC1 | 2 | CH08 | PB0 |
5 | ADC2 | 2 | CH10 | PC0 |
6 | ADC3 | 2 | CH09 | PF3 |
7 | ADC1 | 3 | CH06 | PA6 |
8 | ADC2 | 3 | CH14 | PC4 |
9 | ADC3 | 3 | CH03 | PA3 |
TIM2 Enable
[pastacode lang=”c” manual=”%23define%20ADC_PER%204499%0A%0ARCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2%2C%20ENABLE)%3B%0A%0ATIM_BaseStruct_ST.TIM_Prescaler%20%3D%200%3B%0ATIM_BaseStruct_ST.TIM_CounterMode%20%3D%20TIM_CounterMode_Up%3B%0A%20%2F%2F%20899%20%3D%3E%20100kHz%2C%202249%20%3D%3E%2040kHz%2C%204499%20%3D%3E%2020kHz%2C%208999%20%3D%3E%2010kHz%0ATIM_BaseStruct_ST.TIM_Period%20%3D%20ADC_PER%3B%20%0ATIM_BaseStruct_ST.TIM_ClockDivision%20%3D%20TIM_CKD_DIV1%3B%0A%0ATIM_TimeBaseInit(TIM2%2C%20%26TIM_BaseStruct_ST)%3B%0ATIM_SelectOutputTrigger(TIM2%2C%20TIM_TRGOSource_Update)%3B” message=”” highlight=”” provider=”manual”/]
ADC Clock Enable
[pastacode lang=”c” manual=”%23include%20%22stm32f4xx_adc.h%22%0ARCC_APB2PeriphClockCmd%20(RCC_APB2Periph_ADC1%2C%20ENABLE)%3B%0ARCC_APB2PeriphClockCmd%20(RCC_APB2Periph_ADC2%2C%20ENABLE)%3B%0ARCC_APB2PeriphClockCmd%20(RCC_APB2Periph_ADC3%2C%20ENABLE)%3B” message=”” highlight=”” provider=”manual”/]
ADC set to Triple Mode, DMA Enable, No Prescaler
[pastacode lang=”c” manual=”ADC_CommonInitTypeDef%20ADC_CommonInitStructure%3B%0A%0AADC_CommonInitStructure.ADC_Mode%20%20%20%20%20%20%20%20%20%20%3D%20ADC_TripleMode_RegSimult%3B%0AADC_CommonInitStructure.ADC_Prescaler%20%20%20%20%20%3D%20ADC_Prescaler_Div2%3B%0AADC_CommonInitStructure.ADC_DMAAccessMode%20%3D%20ADC_DMAAccessMode_1%3B%0AADC_CommonInit%20(%26ADC_CommonInitStructure)%3B” message=”” highlight=”” provider=”manual”/]
3 conversions for each ADC, hence 9 in total.
Highest resolution of 12 bits, right data alignment and event trigger by TIM2 interrupts.
[pastacode lang=”c” manual=”ADC_InitTypeDef%20ADC_InitStructure%3B%0A%0AADC_InitStructure.ADC_ScanConvMode%20%20%20%20%20%20%20%3D%20ENABLE%3B%0AADC_InitStructure.ADC_NbrOfConversion%20%20%20%20%3D%203%3B%0AADC_InitStructure.ADC_Resolution%20%20%20%20%20%20%20%20%20%3D%20ADC_Resolution_12b%3B%0AADC_InitStructure.ADC_DataAlign%20%20%20%20%20%20%20%20%20%20%3D%20ADC_DataAlign_Right%3B%0AADC_InitStructure.ADC_ContinuousConvMode%20%3D%20DISABLE%3B%0A%0ATIM_SelectOutputTrigger%20(TIM2%2C%20TIM_TRGOSource_Update)%3B%0AADC_InitStructure.ADC_ExternalTrigConv%20%20%20%20%20%3D%20ADC_ExternalTrigConv_T2_TRGO%3B%0AADC_InitStructure.ADC_ExternalTrigConvEdge%20%3D%20ADC_ExternalTrigConvEdge_Rising%3B%0A%0AADC_Init(ADC1%2C%20%26ADC_InitStructure)%3B%0AADC_Init(ADC2%2C%20%26ADC_InitStructure)%3B%0AADC_Init(ADC3%2C%20%26ADC_InitStructure)%3B” message=”” highlight=”” provider=”manual”/]
Set each channel to the right pin, with 15 cycles for sampling the signal
[pastacode lang=”c” manual=”ADC_RegularChannelConfig%20(ADC1%2C%20ADC_Channel_13%2C%201%2C%20ADC_SampleTime_15Cycles)%3B%0AADC_RegularChannelConfig%20(ADC1%2C%20ADC_Channel_8%2C%20%202%2C%20ADC_SampleTime_15Cycles)%3B%0AADC_RegularChannelConfig%20(ADC1%2C%20ADC_Channel_6%2C%20%203%2C%20ADC_SampleTime_15Cycles)%3B%0A%0AADC_RegularChannelConfig%20(ADC2%2C%20ADC_Channel_0%2C%20%201%2C%20ADC_SampleTime_15Cycles)%3B%0AADC_RegularChannelConfig%20(ADC2%2C%20ADC_Channel_10%2C%202%2C%20ADC_SampleTime_15Cycles)%3B%0AADC_RegularChannelConfig%20(ADC2%2C%20ADC_Channel_14%2C%203%2C%20ADC_SampleTime_15Cycles)%3B%0A%0AADC_RegularChannelConfig%20(ADC3%2C%20ADC_Channel_15%2C%201%2C%20ADC_SampleTime_15Cycles)%3B%0AADC_RegularChannelConfig%20(ADC3%2C%20ADC_Channel_9%2C%20%202%2C%20ADC_SampleTime_15Cycles)%3B%0AADC_RegularChannelConfig%20(ADC3%2C%20ADC_Channel_3%2C%20%203%2C%20ADC_SampleTime_15Cycles)%3B” message=”” highlight=”” provider=”manual”/]
DMA Clock Enable.
Setup DMA data transport, base address, matrix size, half word data transfer and circular mode.
Enable Stream4 of DMA2.
[pastacode lang=”c” manual=”%23include%20%22stm32f4xx_dma.h%22%0ARCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2%2C%20ENABLE)%3B%0A%0ADMA_InitTypeDef%20DMA_InitStructure%3B%0A%0ADMA_InitStructure.DMA_DIR%20%20%20%20%20%3D%20DMA_DIR_PeripheralToMemory%3B%0ADMA_InitStructure.DMA_Channel%20%3D%20DMA_Channel_0%3B%0A%0ADMA_InitStructure.DMA_PeripheralBaseAddr%20%3D%20(uint32_t)%26ADC-%3ECDR%3B%0ADMA_InitStructure.DMA_PeripheralInc%20%20%20%20%20%20%3D%20DMA_PeripheralInc_Disable%3B%0ADMA_InitStructure.DMA_Memory0BaseAddr%20%20%20%20%3D%20(uint32_t)(%26adc%5B0%5D)%3B%0ADMA_InitStructure.DMA_MemoryInc%20%20%20%20%20%20%20%20%20%20%3D%20DMA_MemoryInc_Enable%3B%0A%0ADMA_InitStructure.DMA_BufferSize%20%3D%209%3B%0A%0ADMA_InitStructure.DMA_PeripheralDataSize%20%3D%20DMA_PeripheralDataSize_HalfWord%3B%0ADMA_InitStructure.DMA_MemoryDataSize%20%20%20%20%20%3D%20DMA_MemoryDataSize_HalfWord%3B%0A%0ADMA_InitStructure.DMA_Mode%20%3D%20DMA_Mode_Circular%3B%0A%0ADMA_Init(DMA2_Stream4%2C%20%26DMA_InitStructure)” message=”” highlight=”” provider=”manual”/]
Setup and enable interrupt event of DMA
[pastacode lang=”c” manual=”NVIC_InitTypeDef%20ADCNVICConfig%3B%0AADCNVICConfig.NVIC_IRQChannel%20%3D%20DMA2_Stream4_IRQn%3B%0AADCNVICConfig.NVIC_IRQChannelPreemptionPriority%20%3D%200%3B%0AADCNVICConfig.NVIC_IRQChannelSubPriority%20%3D%201%3B%0AADCNVICConfig.NVIC_IRQChannelCmd%20%3D%20ENABLE%3B%0ANVIC_Init(%26ADCNVICConfig)%3B%0A%0AADC_DMACmd(ADC1%2C%20ENABLE)%3B%0AADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE)%3B%0ADMA_ITConfig(DMA2_Stream4%2C%20DMA_IT_TC%2C%20ENABLE)%3B%0A%0ADMA_Cmd(DMA2_Stream4%2C%20ENABLE)%3B%20″ message=”” highlight=”” provider=”manual”/]
Setup ADC1 as Master and ADC2 and ADC3 as Slaves, enable DMA and all ADCs.
[pastacode lang=”c” manual=”ADC_DMACmd(ADC1%2C%20ENABLE)%3B%0AADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE)%3B%0A%0AADC_Cmd(ADC1%2C%20ENABLE)%3B%0AADC_Cmd(ADC2%2C%20ENABLE)%3B%0AADC_Cmd(ADC3%2C%20ENABLE)%3B” message=”” highlight=”” provider=”manual”/]
The full code can be found in GitHUB