Reputation: 21
I have two boards: a NUCLEO-F411RE and a STM32L467G Discovery.
I need to make a Virtual Com connection between my STM32L467G Discovery and my PC.
For the NUCLEO : The USART2 is connected to ST-Link, so i can communicate with my PC with USART on USB. So, I enable the GPIOA and USART2 Clock. After that, i configure my GPIOA to link Ports 2 and 3 on the USART2, and it works well! I can receive some characters on my PC.
For the STM32L467G Discovery : The STM32L467G Discovery has the USART2 on Port 2 and 3 on GPIOA too. But, in the documentation, they say that the USART2 is connected with the ST-Link with USART2 on Port 5 and 6 in GPIOD. So, i have modify my souce code but i can't receive anything in my computer..
Check my sources:
Main.c
#include "stm32l4xx.h"
#include "stm32l476g_discovery.h"
UART_HandleTypeDef huart2;
GPIO_InitTypeDef GPIO_InitStruct;
void configure_system_clock(void);
int main(void)
{
HAL_Init(); // HAL Init
configure_system_clock(); // Configure Clock
__GPIOD_CLK_ENABLE(); // Enable GPIOD clock
__USART2_CLK_ENABLE(); // Enable USART2 Clock
huart2.Instance = USART2;
huart2.Init.BaudRate = 9600;
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;
HAL_UART_Init(&huart2);
/**USART2 GPIO Configuration
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
char *msg = "Hello YOU\n\r";
HAL_UART_Transmit(&huart2, (uint8_t*)msg, 15, 0xFFFF);
while (42);
}
void configure_system_clock(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
__PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = 6;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
RCC_OscInitStruct.PLL.PLLQ = 7;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);
}
This code works fine on the Nucleo NUCLEO-F411RE (but with GPIOA and port 2 and 3).
On my STM32L467G Discovery, that code totaly fail, with GPIOD port 5 and 6 && with GPIOA port 2 and 3.
I can't see the problem, can you help me please?
Upvotes: 0
Views: 2351
Reputation: 812
Generate the startup using STM-Cube
Please look at this solution I gave just this week to someone in a similar situation. I took the challenge since I have been experiencing the same frustrations.
I have found it always best to work at the highest possible level when starting a project, regardless. I want to be in a position to leverage technical advances as they occur.
Portable, well documented, high level applications are easily maintained and can be quickly ported to newer processors and architectures.
Optimisation at the bits and bytes level comes later to meet specific performance targets not already met.
By concentrating on the high level solution, new approaches to the algorithm often yield better performance advantages than low level optimisations.
Removing bloated initialisation sequences may save a few hundred bytes of startup code and shave a few microseconds, but startup is seldom on the critical path.
Having a working product on the shelf a month before the opposition can be worth your whole business.
If blinding speed is needed, migrate to higher powered architectures before you begin e.g. STM7 series.
A profiler will quickly yield remaining bottlenecks. These can be optimised, using the high level implementation as specification.
Yes, STM libs (and many other libs e.g. sprintf) are big and bloated, yes they do not address everyone's requirements. But they are nonetheless useful and constantly being improved outside of my budget.
The cost of development is measured in man hours, save them.
Start by configuring everything in CUBE and generating the code, use as many of the features of the chipset and libraries as you can to provide the best solution at a high level.
Build up a library of second layer solutions and optimisation you can reuse in other applications.
The recent upgrade to STMCube and HAL libraries corrected a number of problems I experienced in the past. Not perfect, but very usable and worthwhile. Improvement is ongoing.
Spend the bulk of your time developing the application, rather than fiddling round with unnecessary low level optimisation.
This tends to make your boss happy - even if your only boss is the bank manager.
Hopefully the problems you (we) experienced are now a thing of the past.
Upvotes: 1
Reputation: 381
You are initializing the UART in the main and that could be ok, but you are not catching the way HAL libraries want you to initialize the peripheral's pin. You should do that in the HAL_UART_MspInit() function you can find in stm32f4_hal_msp.c file.
Your main should look like this
HAL_Init(); // HAL Init
configure_system_clock(); // Configure Clock
huart2.Instance = USART2;
huart2.Init.BaudRate = 9600;
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;
HAL_UART_Init(&huart2);
HAL_UART_Transmit(&huart2, (uint8_t*)msg, 15, 0xFFFF);
Then in your HAL_UART_MspInit(UART_HandleTypeDef* huart) you should have something like this:
GPIO_InitTypeDef GPIO_InitStruct;
if(huart->Instance==USART2)
{
/* Peripheral clock enable */
__USART2_CLK_ENABLE();
__GPIOD_CLK_ENABLE();
/**USART2 GPIO Configuration */
GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
HAL_NVIC_SetPriority(USART2_IRQn, 0, 1);
HAL_NVIC_EnableIRQ(USART2_IRQn);
}
Pay attention to "GPIO_PULLUP", I suggest you to config GPIO like this for UART. You also have to define the UART Handler in your stm32f4_it.c file:
void USART2_IRQHandler(void)
{
HAL_UART_IRQHandler(&huart2);
}
Upvotes: 3