2016-12-15 03:08 PM
2016-12-15 04:00 PM
How about using ADC Injected Channels? They have a Data Register per channel ==> no DMA needed ==> Simpler?
2016-12-15 04:04 PM
Ok now I diabled DMA and wrote the following :
HAL_ADC_Start(&hadc1); HAL_ADC_PollForConversion(&hadc1,1000); value[0]= HAL_ADC_GetValue(&hadc1);value[1]= HAL_ADC_GetValue(&hadc1);
HAL_ADC_Stop(&hadc1);sConfig.Channel = ADC_CHANNEL_2;
sConfig.Rank = 2; sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES; if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { Error_Handler(); }sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = 1; if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { Error_Handler(); }and it reads two channels. However, it reads OK for few seconds and then the the values swap for a second and then come back, so value[0] becomes value[1] and vice versa and only happes for a second then its fine. Further why it reads
ADC_CHANNEL_2 in value[0], I though the one with the lower rank number will be read first, is that correct?
2016-12-15 05:07 PM
Hi Seb,
thank you for your reply, i am still in my early stages learning and not sure how the injected channels mode work. any example code for the multi channels using an injected channel mode I can start with? many thanks
2016-12-15 08:01 PM
2016-12-15 09:53 PM
Hi Seb,
thanks for that. I'll go through it and see. How about my code above with polling, it is working for me to read multi channels but not sure about processing time, is it going to be very slow?
Thank you
Esam
2016-12-15 09:55 PM
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1,1000); value[0]= HAL_ADC_GetValue(&hadc1);HAL_ADC_PollForConversion(&hadc1,1000);
value[1]= HAL_ADC_GetValue(&hadc1); HAL_ADC_Stop(&hadc1);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_DIV2; 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 = 2; hadc1.Init.DMAContinuousRequests = ENABLE; hadc1.Init.EOCSelection = ADC_EOC_SINGLE_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_2; sConfig.Rank = 2; sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES; if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { Error_Handler(); }sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = 1; if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { Error_Handler(); }}2016-12-16 01:10 AM
Your version looks like a 'one shot mode', controlled by SW.
It really depends on how often you need ADC data and if you'd like to react (interrupt) when reaching a certain value (analog watchdog).
The continuous mode on injected channel will automatically convert both channel in a cyclic fashion, and the SW can do something else.
The best example to illustrate this is to use DMA and a trigger from TIMER CC : You would then create a low frequency oscilloscope.
Do this also with a DAC and you'll get a waveform generator to feed the ADC. ADC sample at 1MHz range. A more challenge solution would be to inject an analog signal (ADC), run it through a digital filter (Kalman or pass band) and push it to the DAC or Matlab/Simulink....
2016-12-18 04:29 PM
Hi again,
I am trying to use DMA now as its more straightforward but still not working for me. Ain[0 below is only reading some weired voltage .17 instead of 1.3V and Ain[1] reads nothing stays 0. can you please have a look and let me know what might have gone wrong:
#include 'stm32f7xx_hal.h'#include 'global.h'#define NO_OF_CHANNELS 2#define NO_OF_ADCs 1//Note that Interrupts for all peripherals are located in the xxx_msp file and xxx_it
void MX_ADC1_Init(void);void MX_DMA_Init(void);void readAins(void);void MX_DMA_Init(void)
{ /* DMA controller clock 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);}
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_DIV2; hadc1.Init.Resolution = ADC_RESOLUTION_12B; hadc1.Init.ScanConvMode = ENABLE; hadc1.Init.ContinuousConvMode = DISABLE; 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 = 2; hadc1.Init.DMAContinuousRequests = ENABLE; hadc1.Init.EOCSelection = DISABLE; HAL_ADC_Init(&hadc1);// 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_2; sConfig.Rank = 2; sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES; HAL_ADC_ConfigChannel(&hadc1, &sConfig);if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{ Error_Handler(); }sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = 1; HAL_ADC_ConfigChannel(&hadc1, &sConfig); if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { Error_Handler(); } // All Channels has to be preconfgured here as above}void readAins(void){
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&value2, 2); Ain[0]=value2[0]; Ain[1]=value2[1];}msp file:
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 PA0/WKUP ------> ADC1_IN0 PA1 ------> ADC1_IN1 */ GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);/* USER CODE BEGIN ADC1_MspInit 1 */
/* USER CODE END ADC1_MspInit 1 */
/* 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_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);// if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)// {// Error_Handler();// } __HAL_LINKDMA(hadc,DMA_Handle,hdma_adc1);}
}
void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1)
{ /* USER CODE BEGIN ADC1_MspDeInit 0 *//* USER CODE END ADC1_MspDeInit 0 */
/* Peripheral clock disable */ __HAL_RCC_ADC1_CLK_DISABLE(); /**ADC1 GPIO Configuration PA0/WKUP ------> ADC1_IN0 PA1 ------> ADC1_IN1 */ HAL_GPIO_DeInit(GPIOA, GPIO_PIN_0|GPIO_PIN_1);/* Peripheral DMA DeInit*/
HAL_DMA_DeInit(hadc->DMA_Handle); // __HAL_LINKDMA(hadc,DMA_Handle,hdma_adc1); } /* USER CODE BEGIN ADC1_MspDeInit 1 *//* USER CODE END ADC1_MspDeInit 1 */
}
2017-01-22 12:10 AM
Hi, did you get it working ?