He estado creando un prototipo de mi proyecto con el STM32F103 "Bluepill" y, para el producto final, quiero pasar al STM32F042F6 que tiene una huella TSSOP-20 más pequeña. Necesito usar UART en mis comunicaciones con el dispositivo, así que intenté crear un programa de transmisión UART simple para verificar que el periférico UART funcionaba correctamente. Aquí está mi código.
#include "stm32f0xx.h"
#include "stm32f0xx_hal.h"
#include "stm32f0xx_hal_conf.h"
void Startup_Sequence(void);
void Error_Handler(void);
void SystemClock_Config(void);
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *UartHandle);
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle);
UART_HandleTypeDef UartHandle;
__IO ITStatus UartReady = RESET;
int main(void)
{
HAL_Init();
//SystemInit();
SystemClock_Config();
GPIO_InitTypeDef GPIO_InitStruct;
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_USART1_CLK_ENABLE();
// Setup LED Pin
GPIO_InitStruct.Pin = GPIO_PIN_4;
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);
// Setup UART Tx Pin
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// Setup UART Rx pin
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
//Setup UART Instance
UartHandle.Instance = USART1;
UartHandle.Init.BaudRate = 9600;
UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
UartHandle.Init.StopBits = UART_STOPBITS_1;
UartHandle.Init.Parity = UART_PARITY_NONE;
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
UartHandle.Init.Mode = UART_MODE_TX_RX;
UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
UartHandle.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
UartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
//Error handling
if(HAL_UART_Init(&UartHandle) != HAL_OK) {
Error_Handler();
}
Startup_Sequence();
HAL_NVIC_SetPriority(USART1_IRQn, 0, 1);
HAL_NVIC_EnableIRQ(USART1_IRQn);
char hello[6] = "hello\n";
while(1) {
if(HAL_UART_Transmit_IT(&UartHandle, (uint8_t *)hello, 6) != HAL_OK) {
Error_Handler();
}
}
}
void Startup_Sequence(void) {
int i;
for (i=1; i<50;i++) {
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_4);
HAL_Delay((1.0/i) * 1000);
}
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
}
void Error_Handler(void) {
while(1) {
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_4);
HAL_Delay(1000);
}
}
/**
* Associates the interrupt handler with the UartHandle
*/
void USART1_IRQHandler(void) {
HAL_UART_IRQHandler(&UartHandle);
}
/**
* This function is called when transmitting
* @param UartHandle [Pointer to UartHandle]
*/
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *UartHandle) {
UartReady = SET;
}
/**
* This function is called when receiving
* @param UartHandle [Pointer to UartHandle]
*/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle) {
UartReady = SET;
}
void SystemClock_Config(void) {
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInit;
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48;
RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType =
RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI48;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) !=
HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;
PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK1;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
/**Configure the Systick interrupt time
*/
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
/**Configure the Systick
*/
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
El periférico UART se inicializa correctamente, porque no se llama al controlador de errores hasta después de que se haya completado la Startup_Sequence (). Entonces, ¿por qué se llama ErrorHandler cuando intento transmitir? He intentado enviar utilizando el modo de bloqueo, pero solo se agota el tiempo de espera cada vez.
EDITAR: He rastreado el error hasta la función de inicialización. Aquí está el Registro de GDB enlace pero no puedo encontrar ningún lugar donde no se devuelva HAL_OK.
¿Hay algún problema con mi configuración del periférico UART? ¿O hay un problema con el reloj del sistema? Por favor avise.