Estoy tratando de enviar y recibir datos hacia y desde un STM32F1xx. Tengo el STM32 para enviar correctamente los datos a la computadora. Lo hice usando el siguiente código.
__HAL_RCC_USART1_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
//Setup UART RX Pin
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
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;
//Error handling
if(HAL_UART_DeInit(&UartHandle) != HAL_OK) {
Error_Handler();
}
if(HAL_UART_Init(&UartHandle) != HAL_OK) {
Error_Handler();
}
char msg[] = "testing\n\r";
while(1) {
HAL_UART_Transmit(&UartHandle, (uint8_t*)msg, sizeof(msg), 10);
}
El código anterior funciona perfectamente. Luego traté de enviar datos desde la computadora al STM32. Probé el siguiente código
if(HAL_UART_Receive_IT(&UartHandle, (uint8_t*)msg, 5) == HAL_OK) {
char msg[] = "HAL_OK";
HAL_UART_Transmit(&UartHandle, (uint8_t*)msg, sizeof(msg), 10);
}
y no funcionó. No se enviaron datos a la computadora cuando envié un byte al STM32. Hice un poco de depuración y la función de recepción devuelve HAL_OK una vez al principio, y luego de eso devuelve HAL_BUSY. Esto me hace pensar que tienes que usar interrupciones, pero las estoy usando con Receive_IT. ¿Cómo soluciono este problema?
No lo veo habilitando la interrupción UART o llamando a los controladores IRQ apropiados y eso podría ser un problema.
Aquí hay un ejemplo completo de una aplicación UART Echo hecha con HAL que escribí para el tema de documentación SO STM32. Como la documentación de SO se cerrará, he citado el ejemplo completo. Fue escrito para un STM32F4 pero con HAL es casi lo mismo para un STM32F1.
En este ejemplo, el microcontrolador devuelve los bytes recibidos al remitente mediante la interrupción UART RX.
#include "stm32f4xx.h"
UART_HandleTypeDef huart2;
/* Single byte to store input */
uint8_t byte;
void SystemClock_Config(void);
/* UART2 Interrupt Service Routine */
void USART2_IRQHandler(void)
{
HAL_UART_IRQHandler(&huart2);
}
/* This callback is called by the HAL_UART_IRQHandler when the given number of bytes are received */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART2)
{
/* Transmit one byte with 100 ms timeout */
HAL_UART_Transmit(&huart2, &byte, 1, 100);
/* Receive one byte in interrupt mode */
HAL_UART_Receive_IT(&huart2, &byte, 1);
}
}
void uart_gpio_init()
{
GPIO_InitTypeDef GPIO_InitStruct;
__GPIOA_CLK_ENABLE();
/**USART2 GPIO Configuration
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
void uart_init()
{
__USART2_CLK_ENABLE();
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;
HAL_UART_Init(&huart2);
/* Peripheral interrupt init*/
HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART2_IRQn);
}
int main(void)
{
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
uart_gpio_init();
uart_init();
HAL_UART_Receive_IT(&huart2, &byte, 1);
while(1)
{
}
}
Este ejemplo usó un STM32F4 Discovery (STM32F407VG), GPIO y los valores de funciones alternativas deben cambiarse de acuerdo con el microcontrolador STM32 en uso.
No debería necesitar usar interrupciones, la agrupación es un método válido para la comunicación UART. Mirando su código, la configuración de GPIO parece estar apagada. El pin Tx está configurado como función alternativa pero no definió la función.
Al mirar la respuesta de @Bence, puede ver que los pines usan af 7 para las funciones USART. Sugeriría agregar la siguiente línea antes de llamar al primer HAL_GPIO_Init:
GPIO_InitStruct.Alternate = GPIO_AFx_USART1;
Y cambie GPIO_InitStruct.MODE para el pin Rx a lo siguiente:
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Alternate = GPIO_AFx_USART1;
Tendrá que reemplazar "AFx" con la función alternativa adecuada para que esos pines funcionen con USART1. Puede encontrar esa información en la hoja de datos de MCU. Por lo general, en una mesa después de la descripción del pin.
Cuando se utilizan pines conectados a un periférico en lugar de una E/S simple, debe realizar un mux adecuado del físico. Lea un poco sobre la muxización de pines del microcontrolador.
dibosco
tom eaton
while(1)
ciclo reemplazando la declaración de transmisión.dibosco
tom eaton
dibosco
tom eaton
krambo
_IT
sufijo significa queHAL_UART_Receive_IT()
se supone que debe usarse en modo de interrupción. Pero no estás tratando de usar el modo de interrupción. Tal vez deberías usarHAL_UART_Receive()
en su lugar.Arce