2025-02-16 12:49 PM
Hello everyone,
I am currently starting my master thesis and i have to design a control loop for an inverter with the STM32 U545 RE-Q. I have started programming in STM32 a week ago so everything is complicated and overwhelming ...
I am aware that there are multiple examples that i can download from every family of NUCLEOS but non of them have worked for me. I have tried the U575 example called ADC, where data from the ADC is written on the DMA, i have configured the IDE as in the example, created the Node, the Queue, etc... And i have literally copied the lines of code provided in the main.c file but it is not working.
In fact, i can not compile as there are the following errors:
../Core/Src/main.c:112:3: warning: implicit declaration of function 'MX_ADCQueue_Config' [-Wimplicit-function-declaration]
112 | MX_ADCQueue_Config();
../Core/Src/main.c:114:56: error: 'ADCQueue' undeclared (first use in this function)
114 | if (HAL_DMAEx_List_LinkQ(&handle_GPDMA1_Channel10, &ADCQueue) != HAL_OK)
I would like to configure 5 channels with the ADC4 and 5 channels with the ADC1 to monitor diverse voltage signals. Then I would like to trigger the ADC reading with
a timer with discontinuous reading as i want to have full control of the ADCs.
What advice would you give me? Has anyone ever ecountered this? How did you solve it?
If you have some examples please provide me those ...
Any help is welcomed
Marc
I attach you the main.c code:
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 Power */
SystemPower_Config();
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_GPDMA1_Init();
MX_ADC4_Init();
MX_ICACHE_Init();
/* USER CODE BEGIN 2 */
MX_ADCQueue_Config();
__HAL_LINKDMA(&hadc4, DMA_Handle, handle_GPDMA1_Channel10);
if (HAL_DMAEx_List_LinkQ(&handle_GPDMA1_Channel10, &ADCQueue) != HAL_OK)
{
Error_Handler();
}
if (HAL_ADC_Start_DMA(&hadc4,
(uint32_t *)aADCxConvertedData,
(ADC_CONVERTED_DATA_BUFFER_SIZE)
) != HAL_OK)
{
Error_Handler();
}
/* USER CODE END 2 */
/* Initialize led */
BSP_LED_Init(LED_GREEN);
/* Initialize USER push-button, will be used to trigger an interrupt each time it's pressed.*/
BSP_PB_Init(BUTTON_USER, BUTTON_MODE_EXTI);
/* Initialize COM1 port (115200, 8 bits (7-bit data + 1 stop bit), no parity */
BspCOMInit.BaudRate = 115200;
BspCOMInit.WordLength = COM_WORDLENGTH_8B;
BspCOMInit.StopBits = COM_STOPBITS_1;
BspCOMInit.Parity = COM_PARITY_NONE;
BspCOMInit.HwFlowCtl = COM_HWCONTROL_NONE;
if (BSP_COM_Init(COM1, &BspCOMInit) != BSP_ERROR_NONE)
{
Error_Handler();
}
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_0;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
RCC_OscInitStruct.PLL.PLLMBOOST = RCC_PLLMBOOST_DIV4;
RCC_OscInitStruct.PLL.PLLM = 3;
RCC_OscInitStruct.PLL.PLLN = 10;
RCC_OscInitStruct.PLL.PLLP = 2;
RCC_OscInitStruct.PLL.PLLQ = 2;
RCC_OscInitStruct.PLL.PLLR = 1;
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLLVCIRANGE_1;
RCC_OscInitStruct.PLL.PLLFRACN = 0;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
|RCC_CLOCKTYPE_PCLK3;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB3CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief Power Configuration
* @retval None
*/
static void SystemPower_Config(void)
{
/*
* Switch to SMPS regulator instead of LDO
*/
if (HAL_PWREx_ConfigSupply(PWR_SMPS_SUPPLY) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN PWR */
/* USER CODE END PWR */
}
/**
* @brief ADC4 Initialization Function
* @param None
* @retval None
*/
static void MX_ADC4_Init(void)
{
/* USER CODE BEGIN ADC4_Init 0 */
/* USER CODE END ADC4_Init 0 */
ADC_ChannelConfTypeDef sConfig = {0};
/* USER CODE BEGIN ADC4_Init 1 */
/* USER CODE END ADC4_Init 1 */
/** Common config
*/
hadc4.Instance = ADC4;
hadc4.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4;
hadc4.Init.Resolution = ADC_RESOLUTION_12B;
hadc4.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc4.Init.ScanConvMode = ADC4_SCAN_DISABLE;
hadc4.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc4.Init.LowPowerAutoPowerOff = ADC_LOW_POWER_NONE;
hadc4.Init.LowPowerAutoWait = DISABLE;
hadc4.Init.ContinuousConvMode = ENABLE;
hadc4.Init.NbrOfConversion = 1;
hadc4.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc4.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc4.Init.DMAContinuousRequests = DISABLE;
hadc4.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_LOW;
hadc4.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc4.Init.SamplingTimeCommon1 = ADC4_SAMPLETIME_19CYCLES_5;
hadc4.Init.SamplingTimeCommon2 = ADC4_SAMPLETIME_19CYCLES_5;
hadc4.Init.OversamplingMode = DISABLE;
if (HAL_ADC_Init(&hadc4) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_4;
sConfig.Rank = ADC4_REGULAR_RANK_1;
sConfig.SamplingTime = ADC4_SAMPLINGTIME_COMMON_1;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&hadc4, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ADC4_Init 2 */
/* USER CODE END ADC4_Init 2 */
}
/**
* @brief GPDMA1 Initialization Function
* @param None
* @retval None
*/
static void MX_GPDMA1_Init(void)
{
/* USER CODE BEGIN GPDMA1_Init 0 */
/* USER CODE END GPDMA1_Init 0 */
/* Peripheral clock enable */
__HAL_RCC_GPDMA1_CLK_ENABLE();
/* USER CODE BEGIN GPDMA1_Init 1 */
/* USER CODE END GPDMA1_Init 1 */
handle_GPDMA1_Channel10.Instance = GPDMA1_Channel10;
handle_GPDMA1_Channel10.InitLinkedList.Priority = DMA_LOW_PRIORITY_LOW_WEIGHT;
handle_GPDMA1_Channel10.InitLinkedList.LinkStepMode = DMA_LSM_FULL_EXECUTION;
handle_GPDMA1_Channel10.InitLinkedList.LinkAllocatedPort = DMA_LINK_ALLOCATED_PORT1;
handle_GPDMA1_Channel10.InitLinkedList.TransferEventMode = DMA_TCEM_LAST_LL_ITEM_TRANSFER;
handle_GPDMA1_Channel10.InitLinkedList.LinkedListMode = DMA_LINKEDLIST_CIRCULAR;
if (HAL_DMAEx_List_Init(&handle_GPDMA1_Channel10) != HAL_OK)
{
Error_Handler();
}
if (HAL_DMA_ConfigChannelAttributes(&handle_GPDMA1_Channel10, DMA_CHANNEL_NPRIV) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN GPDMA1_Init 2 */
/* USER CODE END GPDMA1_Init 2 */
}
/**
* @brief ICACHE Initialization Function
* @param None
* @retval None
*/
static void MX_ICACHE_Init(void)
{
/* USER CODE BEGIN ICACHE_Init 0 */
/* USER CODE END ICACHE_Init 0 */
/* USER CODE BEGIN ICACHE_Init 1 */
/* USER CODE END ICACHE_Init 1 */
/** Enable instruction cache in 1-way (direct mapped cache)
*/
if (HAL_ICACHE_ConfigAssociativityMode(ICACHE_1WAY) != HAL_OK)
{
Error_Handler();
}
if (HAL_ICACHE_Enable() != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ICACHE_Init 2 */
/* USER CODE END ICACHE_Init 2 */
}
/**
* @brief GPIO Initialization Function
* @param None
* @retval None
*/
static void MX_GPIO_Init(void)
{
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
Solved! Go to Solution.
2025-02-16 01:04 PM
Starting with the example in full, before moving to something else. You need all the files to be correct/consistent, not just main.c.
The Example Selector in STM32CubeIDE can be used to load this example.
In this case you haven't modified your main.h file to include those definitions.
/* USER CODE BEGIN Includes */
#include "linked_list.h"
/* USER CODE END Includes */
/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */
/* USER CODE END ET */
/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */
extern DMA_QListTypeDef ADCQueue;
/* USER CODE END EC */
2025-02-16 01:04 PM
Starting with the example in full, before moving to something else. You need all the files to be correct/consistent, not just main.c.
The Example Selector in STM32CubeIDE can be used to load this example.
In this case you haven't modified your main.h file to include those definitions.
/* USER CODE BEGIN Includes */
#include "linked_list.h"
/* USER CODE END Includes */
/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */
/* USER CODE END ET */
/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */
extern DMA_QListTypeDef ADCQueue;
/* USER CODE END EC */
2025-02-16 01:52 PM
Just "follow" the compiler warnings:
1. "warning: implicit declaration of function 'MX_ADCQueue_Config'":
You call a function which is not declared. Potentially, forgotten to include a H-file or to declare this function (as available somewhere else later, e.g. via "Linker"), but a need an external declaration for the function. Here it means: you call a function which is not declared (as a "prototype"), so that compiler could check if you provide enough and correct parameters.
2. "'ADCQueue' undeclared":
Similar: you use a data object which is not declared: the compiler has no clue what it is, what the type of the data is...
You can "use" unknown functions, but you can not use unknown data objects (therefore this error).
As TDK has mentioned:
maybe, both are there, e.g. the function coming from another C-code file (e.g. HAL driver), and the data variable defined (instantiated) in another file. But your code file does not declare both. Something missing, like an #include or an "extern" declaration.
What you could do to find the root cause:
If you do not find it - something is missing (often a H-file to include, to declare in your file that something is "external").
On data objects: the compiler will not continue if it does not know what "it is". On a function called - the compiler warns you, that it cannot "check" if you call the function properly.
Even you can fix it via declarations of the function (as external) and the data object (as external) - the linker will complain at the end, when it cannot find one of those in any file.
Here, the compiler cannot check it what it is.
In this case, you need to add some other files to your project.
Just do what the compiler would do:
2025-02-17 12:31 AM
Good morning,
Thank you for the fast reply.
I uninstalled and reinstalled the STM32CubeIDE and followed your steps and now at least the project can be built.
Can I do something else apart from building it? Of course it is not going to work as i have different nucleo but if i try to "copy/follow" the same procedures in a new project with my nucleo should work right?
Thank you
2025-02-17 12:51 AM
Good morning,
Thank you for the fast reply.
Since I am new i have some questions ...
If i take some project which is alredy done can i apply the same strategy on my nucleo? Which documents do i have to look at if i want to have the same functionality?
Thank you