2017-04-14 06:45 AM
2017-04-15 06:23 AM
If you want to read multi-channel-adc, DMA Mode maybe the better way to do it, for example
PC1 ------> ADC1_IN11,
PC4 ------> ADC1_IN14,
PA2 ------> ADC1_IN2,
PC5 ------> ADC1_IN15
:1. ADC Initial : for channel with 4 different rank
/* ADC1 init function */static void MX_ADC1_Init(void){ADC_ChannelConfTypeDef sConfig;
/**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/hadc1.Instance = ADC1;hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;hadc1.Init.Resolution = ADC_RESOLUTION_12B;hadc1.Init.ScanConvMode = ENABLE;hadc1.Init.ContinuousConvMode = ENABLE;hadc1.Init.DiscontinuousConvMode = DISABLE;hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;hadc1.Init.NbrOfConversion = 4;hadc1.Init.DMAContinuousRequests = ENABLE;hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV;if (HAL_ADC_Init(&hadc1) != HAL_OK){Error_Handler();}/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/sConfig.Channel = ADC_CHANNEL_11;sConfig.Rank = 1;sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK){Error_Handler();}/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/sConfig.Channel = ADC_CHANNEL_2;sConfig.Rank = 2;if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK){Error_Handler();}/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/sConfig.Channel = ADC_CHANNEL_14;sConfig.Rank = 3;if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK){Error_Handler();}/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/sConfig.Channel = ADC_CHANNEL_15;sConfig.Rank = 4;if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK){Error_Handler();}}
2. DMA Initial : DMA NVIC
/**
* Enable DMA controller clock*/static void MX_DMA_Init(void) {/* DMA controller clock enable */__HAL_RCC_DMA1_CLK_ENABLE();__HAL_RCC_DMA2_CLK_ENABLE();/* DMA interrupt init */
/* DMA2_Stream0_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);}
3. MSP initial : adc' GPIO
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc){GPIO_InitTypeDef GPIO_InitStruct;
if(hadc->Instance==ADC1){/* USER CODE BEGIN ADC1_MspInit 0 *//* USER CODE END ADC1_MspInit 0 */
/* Peripheral clock enable */__HAL_RCC_ADC1_CLK_ENABLE();/**ADC1 GPIO Configuration
PC1 ------> ADC1_IN11PC4 ------> ADC1_IN14PA2 ------> ADC1_IN2PC5 ------> ADC1_IN15 */GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5;GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);/* Peripheral DMA init*/
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_HALFWORD;hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;hdma_adc1.Init.Mode = DMA_NORMAL;hdma_adc1.Init.Priority = DMA_PRIORITY_LOW;hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_DISABLE;if (HAL_DMA_Init(&hdma_adc1) != HAL_OK){Error_Handler();}__HAL_LINKDMA(hadc,DMA_Handle,hdma_adc1);
/* USER CODE BEGIN ADC1_MspInit 1 */
/* USER CODE END ADC1_MspInit 1 */
}}
4. Read Multi-ADC-Channel to memnory
static uint16_t adc_buffer[4];
//
hadc1.Init.NbrOfConversion == 4
if(HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&adc_buffer, hadc1.Init.NbrOfConversion) != HAL_OK);
HAL_Delay(500);
HAL_ADC_Stop_DMA(&hadc1);
and add what you want in completed callback function:
/**
* @brief Conversion complete callback in non blocking mode* @param AdcHandle : AdcHandle handle* @note This example shows a simple way to report end of conversion, and* you can add your own implementation.* @retval None*/void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* AdcHandle){// TODO__NOP();}2017-04-15 08:25 AM
Not a HAL guy, but pretty sure you'd need to increment the Rank number
2017-04-17 05:50 AM
,
,
The rank number appears as a fixed number in the HAL of the ADC:
♯ define ADC_RANK_CHANNEL_NUMBER , , , , , , , , , , , , , , , , (0x00001000U) , /*!<, Enable the rank of the selected channels. Number of ranks in the sequence is defined by number of channels enabled, rank of each channel is defined by channel number (channel 0 fixed on rank 0, channel 1 fixed on rank1, ...) */
It is not clear to me how does it work or how could I change it.
2017-04-26 04:37 AM
I think the MCU I'm using is more limited than yours. This is what I can configure in CubeMX:
I haven't find any way to configure different ranks for each ADC channel. What I have finally done is to enable the ADC interrupts and work in interrupt mode:
It seems to work fine but I would like to know if there is any way to us the DMA as well.