-
Starting with STM32 (NUCLEO-L412KB)
Posted by
Picuino
on 29 Apr, 2024 18:40
-
-
-
you could start with arduino v2.xx and install all stm32 librairies / boards ... download and install "stm32programmer" , not the same as stm32 cube
when you have all ready, com port and port type selected .... you can use arduino examples on stm32 without problems
i use nucleo L432KC and nucleo144-F412ZG boards like this ...
you use the integrated st-link of the nucleo boards for the programming interface
-
#2 Reply
Posted by
dietert1
on 29 Apr, 2024 18:52
-
For a family like STM32L4xx they have a repository with HAL drivers and that repository includes lots of sample projects. For me the repository got installed when using CubeMX to create a new project. I mean in CubeMX you can select the board you have to create a new project for that board. Then the proper repository will be downloaded and installed on the local computer. After that you can select one of the sample projects.
I don't use their IDE but EWARM. Probably you can invoke CubeMX from inside the IDE.
Regards, Dieter
-
#3 Reply
Posted by
Picuino
on 29 Apr, 2024 19:53
-
you could start with arduino v2.xx and install all stm32 librairies / boards ... download and install "stm32programmer" , not the same as stm32 cube
when you have all ready, com port and port type selected .... you can use arduino examples on stm32 without problems
i use nucleo L432KC and nucleo144-F412ZG boards like this ...
you use the integrated st-link of the nucleo boards for the programming interface
When uploading the program to the board it asks me for the file STM32_Programmer_CLI.exe
-
#4 Reply
Posted by
Picuino
on 29 Apr, 2024 20:02
-
I have added to the PATH the path where the application STM32_Programmer_CLI.exe was located and now it does not give the previous error.
Now it gives this error:
Sketch uses 13016 bytes (2%) of program storage space. Maximum is 524288 bytes.
Global variables use 1300 bytes (0%) of dynamic memory, leaving 162540 bytes for local variables. Maximum is 163840 bytes.
-------------------------------------------------------------------
STM32CubeProgrammer v2.16.0
-------------------------------------------------------------------
ST-LINK SN : 066AFF575056716587092913
ST-LINK FW : V2J36M26
Board : NUCLEO-L412KB
Voltage : 3.26V
SWD freq : 4000 KHz
Connect mode: Under Reset
Reset mode : Hardware reset
Error: Unable to list supported devices
Error: Cannot identify the device
Failed uploading: uploading error: exit status 1
-
#5 Reply
Posted by
Picuino
on 30 Apr, 2024 15:29
-
I don't understand how it can be so complicated to just plug in a simple development board.
I have tried it with Arduino and it gives me error.
I have installed all the ST tools in the latest version (STMCubeMX, STMCubeIDE, STMProgrammer and libraries for NUCLEO-L412KB) and it doesn't work either.
The error that STMCube gives me is attached:
-
#6 Reply
Posted by
dietert1
on 30 Apr, 2024 15:41
-
The board includes a STLink USB debugger. Is that device enumerated when you plug it into your workstation? I remember downloading and installing a driver for that.
After enumeration there are three USB interfaces:
the STLink debugger "STMicroelectronics STLink dongle",
a CDC serial device "STMicroelectronics Virtual COM Port (COMnn)" and
a memory device with two files on it (DETAILS.TXT and MBED.HTM)
Regards, Dieter
-
-
You can also try with openocd. Don't know about the availability and how to use it under Windows, but on Linux I find it quite easy.
Under Linux there is no need for a driver to use the ST-link, but there is the need for setting an udev rule for it to be able to use it. For openocd a target file is needed which you can most likely find on line or setup your self based on other examples.
-
#8 Reply
Posted by
Picuino
on 30 Apr, 2024 16:00
-
The board includes a STLink USB debugger. Is that device enumerated when you plug it into your workstation? I remember downloading and installing a driver for that.
After enumeration there are three USB interfaces:
the STLink debugger "STMicroelectronics STLink dongle",
a CDC serial device "STMicroelectronics Virtual COM Port (COMnn)" and
a memory device with two files on it (DETAILS.TXT and MBED.HTM)
Regards, Dieter
I'm working in Windows 10.
* I can see the memory device with two files on it.
* The port com6 is linked to the board. Arduino debug and STM32CubeProgrammer recognize the microprocessor and the board without problems.
* In the device manager I can see ST-Link Debug
Perhaps is a problem with the project example for the board. I have selected the board well (I have checked it several times), but perhaps the example project is missing something.
Regards.
-
#9 Reply
Posted by
dietert1
on 30 Apr, 2024 16:27
-
As far as i know the cube IDE is based on eclipse and with eclipse i remember that one needs to configure the make and run steps. If it doesn't work automatically, maybe because you loaded source files instead of the project file. The project file should provide the required configuration. There should be a choice of "Release" and "Debug", at least that's what i have in EWARM.
Regards, Dieter
-
#10 Reply
Posted by
Picuino
on 30 Apr, 2024 16:46
-
I think I had opened it as File instead of as Project.
Now it does not give error.
The problem now is that the program bypasses Avast's antivirus shield.
It says that ST-LINK_gdbserver.exe is infected with IDP.Generic.
-
#11 Reply
Posted by
Picuino
on 30 Apr, 2024 16:55
-
Could be a false positive.
I have scanned the file on the virustotal.com website and it does not give any infection results.
-
#12 Reply
Posted by
Picuino
on 30 Apr, 2024 16:59
-
Ok it is running in debug mode.
Thank you very much.
-
-
I think I had opened it as File instead of as Project.
Now it does not give error.
The problem now is that the program bypasses Avast's antivirus shield.
It says that ST-LINK_gdbserver.exe is infected with IDP.Generic.
Avast's heuristics thinks there is something wrong with the file because the program, in order to access to the debug probe, performs external calls to a DLL that is located elsewere from where they use to be (anywhere in the path variable, current directory, or system path), because such path to the DLL is passed as command line parameter from the IDE.
-
#14 Reply
Posted by
eugene
on 01 May, 2024 17:28
-
-
#15 Reply
Posted by
Picuino
on 01 May, 2024 20:00
-
I did not know them. Thank you very much.
-
#16 Reply
Posted by
dietert1
on 02 May, 2024 16:05
-
Another nice learning series is "FreeRTOS TUTORIALS" on youtube by ControllersTech. They show it using CubeIDE.
Regards, Dieter
-
-
for the STM32_Programmer_CLI.exe error
You have to install them to their default locations, and for Arduino IDE, i use the full install, not the portable one
took me hours to figure this out, no help from ST nor Arduino
Once you select the right board type, programming interface, com port ... and once you install the libraries related to some projects, mostly the FreeRTOS ... Timer ...
-
#18 Reply
Posted by
Picuino
on 13 May, 2024 18:00
-
I have not been able to turn the LD3 led back on again. I don't know what I am doing wrong. The project compiles without errors and downloads to the board. A few days ago I managed to turn on the led, so the board is fine, but now I have not managed to do it again.
The project is generated with CubeMX and modified the main.c so that the led turns on and off, but it doesn't work.
I attach the main.c program:
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2024 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart2;
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
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();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
HAL_GPIO_WritePin(LD3_GPIO_Port, LD3_Pin, GPIO_PIN_SET);
HAL_Delay(100);
HAL_GPIO_WritePin(LD3_GPIO_Port, LD3_Pin, GPIO_PIN_RESET);
HAL_Delay(100);
}
/* 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 RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 1;
RCC_OscInitStruct.PLL.PLLN = 20;
RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
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_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief USART2 Initialization Function
* @param None
* @retval None
*/
static void MX_USART2_UART_Init(void)
{
/* USER CODE BEGIN USART2_Init 0 */
/* USER CODE END USART2_Init 0 */
/* USER CODE BEGIN USART2_Init 1 */
/* USER CODE END USART2_Init 1 */
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART2_Init 2 */
/* USER CODE END USART2_Init 2 */
}
/**
* @brief GPIO Initialization Function
* @param None
* @retval None
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(LD3_GPIO_Port, LD3_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin : PA1 */
GPIO_InitStruct.Pin = GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pin : LD3_Pin */
GPIO_InitStruct.Pin = LD3_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LD3_GPIO_Port, &GPIO_InitStruct);
/* 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 */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
EDIT:
This is my code:
/* USER CODE BEGIN WHILE */
while (1)
{
HAL_GPIO_WritePin(LD3_GPIO_Port, LD3_Pin, GPIO_PIN_SET);
HAL_Delay(100);
HAL_GPIO_WritePin(LD3_GPIO_Port, LD3_Pin, GPIO_PIN_RESET);
HAL_Delay(100);
}
-
#19 Reply
Posted by
8goran8
on 14 May, 2024 07:11
-
Just increase the value for HAL_Delay.
Try with HAL_Delay(1000);
-
#20 Reply
Posted by
dietert1
on 14 May, 2024 07:33
-
Also i would recommend to keep those
/* USER CODE BEGIN .. */
/* USER CODE END .. */
blocks created by CubeMX intact and use them properly in order to not lose my code the next time CubeMX regenerates the project.
Last week i wrote a lot of code for a STM32L432 and found it nice to work with. I used C++ and didn't have to think about RAM or Flash limits - somewhat unusual when working with a MCU. Although it has a single precision FPU i used lots of doubles.
Regards, Dieter
-
#21 Reply
Posted by
Picuino
on 14 May, 2024 07:53
-
Yes, it is quite a powerful microcontroller in many ways. Much more than any of the ones I've used so far, including the 16bit ones.
I've had the STM32 board in a drawer for quite some time and I've finally decided to use it.
The problem is that, for some reason, it's hard for me to start something as simple as the "hello world" of microcontrollers (blinking led).
EDIT:
When I change the pin to a different pin, it remains as an input and not as an output. Of course the output voltage value does not change either.
-
#22 Reply
Posted by
Picuino
on 14 May, 2024 13:49
-
I have no idea what the problem was.
I have reinstalled all the IDE programs again and now it works fine. Finally I have the led blinking.
-
#23 Reply
Posted by
Picuino
on 14 May, 2024 15:34
-
I am testing turning a digital output on and off. The program I am using is as follows.
while (0) {
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET);
}
On the oscilloscope I get a 470kHz square signal, which seems to me too slow for an 80MHz microcontroller.
Is there any way to write directly to the registers to turn on and off a digital output?
-
#24 Reply
Posted by
Picuino
on 14 May, 2024 15:42
-
I answer myself:
while (1) {
GPIOA->BSRR |= (1<<3); // Set PA3 (Pin A2 in the Nucleo board)
GPIOA->BSRR |= (1<<(3+16)); // Reset PA3
}
1880kHz output (200ns High and 300ns Low)
I think the clock is set too slow.
EDIT:
After configuring the internal clock to 80MHz, the output doesn't work.
That was the mistake I had. I don't know how to set the clock properly with the external oscillator.