2024-03-02 03:09 AM - edited 2024-03-02 03:54 AM
Hello All, I am working on a raw STM32C031C6T6 directly soldered on a breakout board and trying to make a multi channel interrupt based ADC working but the problem i am facing is all the adc's are giving me the same values even after setting the separate channel for individuals and when i decided to use dma it stuck when continue dma request is enable and when its not dma just reads a single cycle.
below i have provided you the screenshot of my configuration and clock settings i have used as well as i am attaching my code which i have made for this.
any kind of help will be really appreciable.
__IO uint16_t counter=0,secCounter=0;
uint32_t uADCVal[4];
__IO uint8_t ADCflag=0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
if (htim->Instance == TIM3) {
counter++;
if (counter >= 500) {
counter=0;
secCounter++;
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
}
}
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(hadc);
/* NOTE : This function should not be modified. When the callback is needed,
function HAL_ADC_ConvCpltCallback must be implemented in the user file.
*/
ADCflag=1;
}
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* Configure the peripherals common clocks */
PeriphCommonClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_TIM3_Init();
MX_ADC1_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim3);
HAL_ADC_Start_IT(&hadc1);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if (ADCflag) {
for (int var = 0; var < 4; var++) {
uADCVal[var] = HAL_ADC_GetValue(&hadc1);
}
ADCflag=0;
//HAL_ADC_Start_IT(&hadc1);
}
}
/* USER CODE END 3 */
}
2024-03-02 04:29 AM
Have you scan mode enabled ? Better as photo is attach ioc file or show code adc init...
And 1,5 cycle ...
2024-03-02 08:16 PM
Do you know that the ADC has multiple channels and these have to be configured as "RANK"s?
How many RANKs are configured in your system? I would guess: the CubeMX tool does not configure multiple channels, just the main ADC setup.
On my STM32U5A5 project, I "need" this:
/** Configure Regular Channel */
sConfig.Channel = ADC_CHANNEL_VREFINT;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_68CYCLES; //ADC_SAMPLETIME_1CYCLE_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
sConfig.OffsetSignedSaturation = DISABLE;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
//Error_Handler();
}
sConfig.Channel = ADC_CHANNEL_VBAT;
sConfig.Rank = ADC_REGULAR_RANK_2;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
//Error_Handler();
}
sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
sConfig.Rank = ADC_REGULAR_RANK_3;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
//Error_Handler();
}
HAL_ADCEx_Calibration_Start(&hadc, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED);
2024-03-03 04:50 AM
for (int var = 0; var < 4; var++) { uADCVal[var] = HAL_ADC_GetValue(&hadc1); }
This is not how the ADC works. It does not store the values for all channels in a buffer which you can read out later.
Use DMA to convert multiple channels.
2024-03-04 12:20 AM - edited 2024-03-04 12:30 AM
2024-03-04 12:22 AM
static void MX_ADC1_Init(void)
{
/* USER CODE BEGIN ADC1_Init 0 */
/* USER CODE END ADC1_Init 0 */
ADC_ChannelConfTypeDef sConfig = {0};
/* USER CODE BEGIN ADC1_Init 1 */
/* USER CODE END ADC1_Init 1 */
/** 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.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV;
hadc1.Init.LowPowerAutoWait = DISABLE;
hadc1.Init.LowPowerAutoPowerOff = DISABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.NbrOfConversion = 3;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.DMAContinuousRequests = DISABLE;
hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc1.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_1CYCLE_5;
hadc1.Init.SamplingTimeCommon2 = ADC_SAMPLETIME_1CYCLE_5;
hadc1.Init.OversamplingMode = DISABLE;
hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_2;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = ADC_REGULAR_RANK_2;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_2;
sConfig.Rank = ADC_REGULAR_RANK_3;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ADC1_Init 2 */
/* USER CODE END ADC1_Init 2 */
}
here is my adc init as well as i have attached my ioc file with this.
2024-03-04 12:27 AM
Above on Mr MM..1's post i have attached my ioc file and if you could check them once for any error would be really appreciable.
And if you could provide me any sample code using Multichannel ADC interrupt mode can help me a lot to understand better.
2024-03-04 05:48 AM
Using DMA would be the supported solution. You can use interrupts if your code is fast enough. The reference manual provides instructions on how to set this up. You probably won't find examples of it as it's prone to overrun errors.
2024-03-04 09:42 AM - edited 2024-03-04 09:45 AM
SamplingTime common 1 set to value around 100 cycles and use common 1 on channels...