2021-05-29 02:50 PM
I have probably missed something simple.
I use CubeMx to Configure the A2D channels
hadc.Instance = ADC1;
hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
hadc.Init.Resolution = ADC_RESOLUTION_12B;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc.Init.LowPowerAutoWait = DISABLE;
hadc.Init.LowPowerAutoPowerOff = DISABLE;
hadc.Init.ContinuousConvMode = ENABLE;
hadc.Init.DiscontinuousConvMode = DISABLE;
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc.Init.DMAContinuousRequests = DISABLE;
hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
if (HAL_ADC_Init(&hadc) != HAL_OK)
{
Error_Handler();
}
/** Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_8;
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_9;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_VREFINT;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_VBAT;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
I only need to take data periodically so I use this to kick off the conversion very 3 seconds.
if(AdcTmr == 3000)
{
AdcTmr = 0;
HAL_ADC_Start_DMA(&hadc, AdcBuf, NUM_A2D_CHANS);
}
where NUM_A2D_CHANS is the set to 5 for the number of channels to be scanned. The Callback routine is
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
AdcRdy = FALSE;
if(hadc->Instance == ADC1)
{
for(int i = 0; i < NUM_A2D_CHANS; i++)
{
AdcVal[i] = AdcBuf[i];
AdcBuf[i] = 0;
}
AdcRdy = TRUE;
}
}
The contents of the AdcBuf is transferred to the AdcVal buffer and printed out. as above
ADC Data: : 1: 2144: 2: 1665: 3: 0: 4: 0: 5: 0
The first value is the output of a pot and changes as the pot changes.
Channel 2 is also tied to a second pot but the value doesn't change as the pot is varied . I don't know what it represents. The last three values should be from the internal sensors put are obviously incorrect.
I've missed something.
Should I be registering a callback for the DMA instead of using the ADC_ConvCpltCallback???
Suggestions??
2021-05-30 07:33 AM
I got the functionality I wanted using Interrupts.
ADC Data: : 1: 2298: 2: 3339: 3: 1670: 4: 1452: 5: 0
The first two values are tied to pots and change as I set the pot. The next two change with sample but by one or two bit. Not unexpected for an A2D. The last value is VBAT but I there may not be a VBAT connection on the Nucleo-F042k board. I'll have to check the datasheet.
I would really like to get the DMA working to save clock cycles.
Any Suggestions??