Ich habe mein Projekt mit dem STM32F103 „Bluepill“ prototypisiert und möchte für das Endprodukt auf den STM32F042F6 umsteigen, der einen kleineren TSSOP-20-Footprint hat. Ich muss UART in meiner Kommunikation mit dem Gerät verwenden, also habe ich versucht, ein einfaches UART-Sendeprogramm zu erstellen, um zu überprüfen, ob das UART-Peripheriegerät ordnungsgemäß funktioniert. Hier ist mein Code.
#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);
}
Das UART-Peripheriegerät wird korrekt initialisiert, da der Error Handler erst aufgerufen wird, nachdem Startup_Sequence() abgeschlossen ist. Warum wird also der ErrorHandler aufgerufen, wenn ich versuche zu übertragen? Ich habe versucht, im Sperrmodus zu senden, aber es kommt jedes Mal zu einer Zeitüberschreitung.
EDIT: Ich habe den Fehler bis zur Initialisierungsfunktion verfolgt. Hier ist das GDB-Protokoll https://hastebin.com/xopohaniyu.coffeescript , aber ich kann nirgendwo finden, wo HAL_OK nicht zurückgegeben wird.
Stimmt etwas mit meiner Einrichtung des UART-Peripheriegeräts nicht? Oder gibt es ein Problem mit der Systemuhr? Bitte beraten.
Das GPIO-Setup ist beim F0 etwas komplizierter und flexibler. Hier sollten Sie auch setzen GPIO_InitStruct.Alternate = GPIO_AF1_USART1
, da es sonst einen zufälligen Wert bekommt, da es sich um eine unitialisierte automatische Variable handelt. Aktivieren Sie die Warnungen im Compiler und achten Sie darauf, sie sind aus einem bestimmten Grund da.
HAL_UART_Transmit_IT()
wird erneut aufgerufen, bevor die vorherige Übertragung beendet ist. Sie sollten warten, bis das UartReady
Flag gesetzt ist, und es vor dem Wiederholen zurücksetzen.
Chris Stratton
Chris Stratton