Question
STM32F4 Dual ADC Reg Sim Mode with DMA
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