cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 Dual ADC Reg Sim Mode with DMA

alexanderjonas
Associate II
Posted on March 21, 2016 at 18:02

Hello, I want to read ADC1 CH0 and ADC2 CH1 in dual regular simultaneous mode and buffer it in DMA. I want to send the ADC values via UART to my PC and read them from the COM Port.

When I start the program now, I only receive the msg 0x0A, which I send after the m_ADCValue. But after some transmissions it stops and nothing is sent anymore. Another problem is, that I do not really I understand how to get the values that I write in the m_ADCBuffer. Do I have to use the HAL_ADC_ConvCpltCallback and HAL_ADCEx_MultiModeGetValue? What is about the DMA2_Stream0_IRQHandler(), do I need to implement that?

void ADC_init(void){
// 1. Init Timer for Interrupt trigger 
TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_MasterConfigTypeDef sMasterConfig;
// TIM3 clock enable
__TIM3_CLK_ENABLE();
//Init TIM3 Base
m_hTIM3.Instance = TIM3; 
m_hTIM3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
m_hTIM3.Init.Prescaler = 18000; 
m_hTIM3.Init.CounterMode = TIM_COUNTERMODE_UP;
m_hTIM3.Init.Period = MYADCSAMPLETIME; 
m_hTIM3.Init.RepetitionCounter = 0;
if(HAL_TIM_Base_Init(&m_hTIM3) != HAL_OK){
ErrorLED();
}
//Config Timer3 TRGO
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if(HAL_TIM_ConfigClockSource(&m_hTIM3, &sClockSourceConfig) != HAL_OK){
ErrorLED();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if(HAL_TIMEx_MasterConfigSynchronization(&m_hTIM3, &sMasterConfig) != HAL_OK){
ErrorLED();
}
//Start timer
if(HAL_TIM_Base_Start(&m_hTIM3) != HAL_OK){
ErrorLED();
}
// 2. Enable ADC1, ADC2, DMA2 Clock 
// Enable ADC Clk before DMA2 Clk
__ADC1_CLK_ENABLE();
__ADC2_CLK_ENABLE();
__DMA2_CLK_ENABLE();
// 3. Init DMA
m_hDMA2s0c0.Instance = DMA2_Stream0;
m_hDMA2s0c0.Init.Channel = DMA_CHANNEL_0;
m_hDMA2s0c0.Init.Direction = DMA_PERIPH_TO_MEMORY;
m_hDMA2s0c0.Init.PeriphInc = DMA_PINC_DISABLE; 
m_hDMA2s0c0.Init.MemInc = DMA_MINC_ENABLE; 
m_hDMA2s0c0.Init.PeriphDataAlignment = MA_PDATAALIGN_WORD; 
m_hDMA2s0c0.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
m_hDMA2s0c0.Init.Mode = DMA_CIRCULAR; 
m_hDMA2s0c0.Init.Priority = DMA_PRIORITY_HIGH;
m_hDMA2s0c0.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
m_hDMA2s0c0.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;
m_hDMA2s0c0.Init.MemBurst = DMA_MBURST_SINGLE;
m_hDMA2s0c0.Init.PeriphBurst = DMA_PBURST_SINGLE;
if(HAL_DMA_Init(&m_hDMA2s0c0) != HAL_OK){
ErrorLED();
}
// DMA mit ADC verlinken
__HAL_LINKDMA(&m_hADC1, DMA_Handle, m_hDMA2s0c0);
HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
// 4. Init ADC1 
m_hADC1.Instance = ADC1;
m_hADC1.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV2; 
m_hADC1.Init.Resolution = ADC_RESOLUTION_8B;
m_hADC1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
m_hADC1.Init.ScanConvMode = DISABLE; 
m_hADC1.Init.EOCSelection = DISABLE; 
m_hADC1.Init.ContinuousConvMode = ENABLE;
m_hADC1.Init.DiscontinuousConvMode = DISABLE;
m_hADC1.Init.DMAContinuousRequests = ENABLE; 
m_hADC1.Init.NbrOfConversion = 1; 
m_hADC1.Init.NbrOfDiscConversion = 0; 
m_hADC1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING; 
m_hADC1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T3_TRGO; 
if(HAL_ADC_Init(&m_hADC1) != HAL_OK){
ErrorLED();
}
// 5. Init ADC2 
m_hADC2.Instance = ADC2;
m_hADC2.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV2; 
m_hADC2.Init.Resolution = ADC_RESOLUTION_8B;
m_hADC2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
m_hADC2.Init.ScanConvMode = DISABLE; 
m_hADC2.Init.EOCSelection = DISABLE; 
m_hADC2.Init.ContinuousConvMode = ENABLE;
m_hADC2.Init.DiscontinuousConvMode = DISABLE;
m_hADC2.Init.DMAContinuousRequests = ENABLE; 
m_hADC2.Init.NbrOfConversion =1; 
m_hADC2.Init.NbrOfDiscConversion = 0;
m_hADC2.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T3_TRGO; 
m_hADC2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
if(HAL_ADC_Init(&m_hADC2) != HAL_OK){
ErrorLED();
}
HAL_NVIC_SetPriority(ADC_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(ADC_IRQn);
// 6. Config ADC Channel
ADC_ChannelConfTypeDef sConfig;
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = 1; 
sConfig.SamplingTime = ADC_SAMPLETIME_56CYCLES; 
sConfig.Offset = 0;
HAL_ADC_ConfigChannel(&m_hADC1, &sConfig);
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = 1; 
sConfig.SamplingTime = ADC_SAMPLETIME_56CYCLES; 
sConfig.Offset = 0;
HAL_ADC_ConfigChannel(&m_hADC2, &sConfig);
// 7. ADC Mode
ADC_MultiModeTypeDef multimode;
multimode.Mode = ADC_DUALMODE_REGSIMULT;
multimode.DMAAccessMode = ADC_DMAACCESSMODE_1; 
multimode.TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_6CYCLES;
if(HAL_ADCEx_MultiModeConfigChannel(&m_hADC1, &multimode) != HAL_OK){
ErrorLED();
}
if(HAL_ADCEx_MultiModeConfigChannel(&m_hADC2, &multimode) != HAL_OK){
ErrorLED();
}
}
/*
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* m_hADC1){
m_ADCValue[1] = HAL_ADCEx_MultiModeGetValue(&m_hADC1);
}
*/
/*
void DMA2_Stream0_IRQHandler(){
HAL_DMA_IRQHandler(m_hADC1.DMA_Handle); //?????? mit & ???????
}
*/
/*
void ADC1_DMA_IRQHandler(void)
{
HAL_DMA_IRQHandler(m_hADC1.DMA_Handle);
}
*/
/*
void ADC_IRQHandler(){
HAL_ADC_IRQHandler(&m_hADC1);
}
*/
int main(){
HAL_Init();
SystemCoreClockConfigure_180MHz_internal();
GPIO_PowerLub_init();
UART_Init(mBaudrate);
ADC_init();
uint8_t msg[1] = {0x0A};
HAL_ADC_Start(&m_hADC2);
HAL_ADCEx_MultiModeStart_DMA(&m_hADC1, (uint32_t *)m_ADCBuffer, 2)
while(1){
HAL_UART_Transmit(&huart2, (uint32_t *)m_ADCValue, 2, 0xAAFF);
HAL_UART_Transmit(&huart2, (uint32_t *)msg, 1, 0xAAFF);
}
}

#adc_dual #adc #dma #stm32-adc
1 REPLY 1
alexanderjonas
Associate II
Posted on March 23, 2016 at 21:24

Ok, I updated my code and got some things running.

My only problem now is, that my ADCBuffer is always 00. Even when I initialize it with m_ADCBuffer[2] = {0xCC, 0xCC} I only got 0s. So, maybe my ADC isnt running or what is happening. Any Suggestions? My updated code:

#include ''stm32f4xx.h''
#include ''stm32f4xx_hal.h''
#include ''stm32f4xx_hal_adc.h''
#include ''stm32f4xx_it.h''
#include ''stm32f4xx_hal_dma.h''
#include ''SPI_init.h''
#include ''UART_init.h''
#include ''GPIO_init.h''
#include ''timer.h''
#include ''defines.h''
ADC_HandleTypeDef hadc1;
ADC_HandleTypeDef hadc2;
DMA_HandleTypeDef hdma_adc1;
__IO uint32_t m_ADCBuffer[2] = {0xCC, 0xCC};
__IO uint32_t m_ADCval[2];
volatile uint8_t DMA_TC_Detect;
void ADC_DMA_Init(void);
void HAL_MspInit(void);
void DMA2_Stream0_IRQHandler(void);
int main(){
HAL_Init();
SystemCoreClockConfigure_180MHz_internal();
HAL_MspInit();
GPIO_PowerLub_init();
UART_Init(mBaudrate);
ADC_DMA_Init();
uint16_t msg_start[1] = {0xAA};
uint16_t msg_stop[1] = {0xBB};
m_ADCval[0] = 0;
HAL_ADC_Start(&hadc2);
HAL_ADCEx_MultiModeStart_DMA(&hadc1, (uint32_t *)m_ADCBuffer, 2);
while(1){
if(DMA_TC_Detect == 1){
HAL_UART_Transmit(&huart2, (uint32_t *)msg_start, 1, 0xAAFF);
//copy Values
for(int i=0; i<
2
; i++){
m_ADCval[0] = (m_ADCBuffer[0] >> 8) & 0xFF;
m_ADCval[1] = m_ADCBuffer[1];
}
DMA_TC_Detect = 0;
HAL_ADC_Start(&hadc2);
HAL_ADCEx_MultiModeStart_DMA(&hadc1, (uint32_t *)m_ADCBuffer, 2);
HAL_Delay(100);
HAL_UART_Transmit(&huart2, (uint32_t *)m_ADCval, 4, 0xAAFF);
HAL_UART_Transmit(&huart2, (uint32_t *)msg_stop, 1, 0xAAFF);
}
}
}
void ADC_DMA_Init(void){
__ADC1_CLK_ENABLE();
__ADC2_CLK_ENABLE();
__DMA2_CLK_ENABLE();
hdma_adc1.Instance = DMA2_Stream0;
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_WORD;
hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_adc1.Init.Mode = DMA_CIRCULAR;
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);
__HAL_LINKDMA(&hadc1,DMA_Handle,hdma_adc1);
/* DMA interrupt init */
HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
ADC_MultiModeTypeDef multimode;
ADC_ChannelConfTypeDef sConfig;
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV2;
hadc1.Init.Resolution = ADC_RESOLUTION8b;
hadc1.Init.ScanConvMode = DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
hadc1.Init.DMAContinuousRequests = ENABLE;
hadc1.Init.EOCSelection = EOC_SINGLE_CONV;
HAL_ADC_Init(&hadc1);
hadc2.Instance = ADC2;
hadc2.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV2;
hadc2.Init.Resolution = ADC_RESOLUTION8b;
hadc2.Init.ScanConvMode = DISABLE;
hadc2.Init.ContinuousConvMode = DISABLE;
hadc2.Init.DiscontinuousConvMode = DISABLE;
hadc2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc2.Init.NbrOfConversion = 1;
hadc2.Init.DMAContinuousRequests = ENABLE;
hadc2.Init.EOCSelection = EOC_SINGLE_CONV;
HAL_ADC_Init(&hadc2);
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_56CYCLES;
HAL_ADC_ConfigChannel(&hadc1, &sConfig);
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_56CYCLES;
HAL_ADC_ConfigChannel(&hadc2, &sConfig);
multimode.Mode = ADC_DUALMODE_REGSIMULT;
multimode.DMAAccessMode = ADC_DMAACCESSMODE_1;
multimode.TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_6CYCLES;
HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode);
}
void DMA2_Stream0_IRQHandler(void){
if(__HAL_DMA_GET_FLAG(&hdma_adc1, __HAL_DMA_GET_TC_FLAG_INDEX(&hdma_adc1)) != RESET){
__HAL_DMA_CLEAR_FLAG(&hdma_adc1, __HAL_DMA_GET_TC_FLAG_INDEX(&hdma_adc1));
DMA_TC_Detect = 1;
if(__HAL_DMA_GET_FLAG(&hdma_adc1, __HAL_DMA_GET_HT_FLAG_INDEX(&hdma_adc1)) != RESET){
__HAL_DMA_CLEAR_FLAG(&hdma_adc1, __HAL_DMA_GET_HT_FLAG_INDEX(&hdma_adc1));
}
else{
DMA_TC_Detect = 1;
}
}
HAL_DMA_IRQHandler(hadc1.DMA_Handle);
}
void HAL_MspInit(void)
{
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}