STM32F031K6 Проблема с прерываниями HAL UART

введите описание изображения здесьЯ получил новую плату ядра STM32F0 31 K6, и мне нужно сделать интерфейс GSM UART на этой плате. Мне нужно отправить AT и получить OK от платы GSM в качестве первого шага. Я могу успешно передать AT, но не могу ничего получить. Я использую ИАР. Я использую PA9-TX и PA10-RX. Как создать код передачи и приема с использованием прерываний с помощью этой библиотеки HAL. Я написал код с использованием прерываний, и он не дает ни одного символа. это мой код

     int main(void)
{

  HAL_Init();
  /* Configure the system clock to 48 MHz */
  SystemClock_Config();
    /* Configure LED3 */
  BSP_LED_Init(LED3);
  UART_Init();
  BSP_LED_Off(LED3);
  if(HAL_UART_Transmit(&UartHandle, (uint8_t*)aTxBuffer, TXBUFFERSIZE,100)!= HAL_OK)
  {
    Error_Handler();
  }

    if(HAL_UART_Receive_IT(&UartHandle, (uint8_t *)aRxBuffer,6) != HAL_OK)
  {
    Error_Handler();
  }
   /*##-5- Wait for the end of the transfer ###################################*/   
  while (UartReady != SET)
  {
  } 
    /* Reset transmission flag */
  UartReady = RESET;
  /*if(HAL_UART_Transmit(&UartHandle, (uint8_t*)aRxBuffer, 6,1000)!= HAL_OK)
  {
    Error_Handler();
  }*/
  while (1)
  {
  }
}

обработчик IRQ

void USARTx_IRQHandler(void)
{
  HAL_UART_IRQHandler(&UartHandle);
}

Получить функцию обратного вызова

void  HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
  if(UartHandle->Instance == USARTx)
  {  
    /* Set transmission flag: transfer complete */
    UartReady = SET;
    BSP_LED_On(LED3); 
  }
}

И когда я отлаживаю код, застрявший на этом месте.

/*##-5- Wait for the end of the transfer ###################################*/   
  while (UartReady != SET)
  {
  } 

Мое фактическое приложение состоит в том, чтобы отправить SMS на плату GSM с помощью UART и собрать ответ в буфере, а затем проанализировать его. это общение.

помогите ребята..

С уважением, Оливия

Я рекомендую начать с создания минимального компилируемого кода, который не делает того, что, по вашему мнению, он должен делать, а также любых идей, которые вы получили в результате попыток отладки.
Пожалуйста, сделайте следующее... Прочтите это: electronics.stackexchange.com/help/how-to-ask Задайте конкретный вопрос и предоставьте все подробности, касающиеся вашего вопроса. Хороший вопрос не требует пояснений. Какой GSM интерфейс? Какая шина связи? SPI I2C или RS232 (и это лишь некоторые из них). Такие вопросы не должны задаваться.
@laptop2d Согласно названию, это UART. Но неясно, как это должно было быть включено в тело вопроса.
@OliviaChristy Если у вас есть код, который не работает, вы также должны добавить его в вопрос. И схема, может быть, убедитесь, что вы не перепутали линии RX-TX.
Добавьте схемы, управление потоком по умолчанию отключено или включено на модуле?
контакты управления потоком доступны на микроконтроллерах PA0 и PA1. но он работает как входной и выходной АЦП в заголовках.
Какова конфигурация управления потоком в отношении модуля GSM? Также меня не интересует схема платы Nucleo, меня интересует ваша схема, как вы подключили модуль GSM к Nucleo. Возможно, вам следует попытаться отправить и получить внутри основного несколько раз. В основном ваш код выглядит нормально (правильный обратный вызов и обработчик прерываний), но черт знает, чего ожидает ваш модуль GSM, поскольку вы все еще не добавили таблицу данных.
привет, ребята, я сделал это. У всех, у кого есть проблемы с прерыванием uart на платах stm32, использующих библиотеку hal, перейдите по этой ссылке. letanphuc.net/2015/09/stm32f0-uart-tutorial-5/#comment-278 Мне помогло

Ответы (3)

Базовая инициализация UART с прерываниями с использованием HAL выглядит примерно так, как показано ниже. Я не хочу описывать параметры, так как они вполне очевидны. Это фактическая конфигурация контактов и конфигурация периферийного устройства UART. HAL_UART_MspInitвызывается HAL_UART_Init, чтобы использовать его вам нужно только позвонить MX_USART1_UART_Init.

#include "stm32f0xx_hal.h"

UART_HandleTypeDef huart1;

void MX_USART1_UART_Init(void)
{
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  huart1.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;
  huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  HAL_UART_Init(&huart1);
}

void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
  GPIO_InitTypeDef GPIO_InitStruct;
  if(huart->Instance==USART1)
  {
    __USART1_CLK_ENABLE();

    /**USART1 GPIO Configuration    
    PA2     ------> USART1_TX
    PA3     ------> USART1_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_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF1_USART1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);       
    HAL_NVIC_EnableIRQ(USART1_IRQn);               // Enable Interrupt
  }
}

Обработка прерывания следующая:

void USART1_IRQHandler()
{
  HAL_UART_IRQHandler(&huart1);
}

Это фактический ISR и HAL_UART_IRQHandler(&huart1)функция-обработчик, определенная HAL. Он проверяет, какой флаг источника прерывания был установлен, вызывает обратный вызов или ожидает получения дополнительных байтов и очищает флаги прерывания.

В случае прерывания RX этот обработчик подсчитывает полученные байты и, когда получено желаемое количество, вызывает эту функцию обратного вызова:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  if (huart->Instance == USART1)
  {
    // Your buffer is full with your data process it here or set a flag
  }
}

Обратный вызов имеет слабое объявление, вы должны его реализовать.

Теперь об использовании. Для отправки можно использовать следующую функцию HAL, это самая простая:

HAL_UART_Transmit(&huart1, (uint8_t*)"AT\r", 3, 0xFFFFFF)

Для приема с прерыванием необходимо использовать следующую функцию:

HAL_UART_Receive_IT(&huart1, uint8_t *pData, uint16_t size)

где pDataуказатель на приемный буфер и sizeожидаемое количество байтов. Будет HAL_UART_IRQHandler(&huart1)вызывать обратный вызов, если количество полученных байтов равно size.

Все это можно сгенерировать с помощью генератора кода STM32CubeMX , за исключением обратных вызовов, которые не генерируются.


Модуль GSM, вероятно, по умолчанию имеет режим эха, поэтому, чтобы AT\rон ответил с помощью \r\nAT\r\n\r\nOK\r\n, следует подождать 12 байт.

Режим эха можно отключить с помощью ATE0команды и сохранить по умолчанию с помощью AT&Wкоманды. От этого ответ будет \r\nOK\r\nна AT\r.

Недавно я столкнулся с подобной проблемой с моим модулем LTE. Оказывается, во многих таких модулях аппаратное управление потоком данных включено по умолчанию. Вы также можете использовать аппаратное управление потоком на своем конце или просто заземлить вывод CTS модуля.

Также по какой-то причине в моем случае маркировка для RX/TX и RTS/CTS была изменена. Итак, приведенное выше решение не сработало, вы можете попробовать поменять местами соединения.

Спасибо ребята за дискуссию! Я столкнулся с похожей проблемой. В моем случае я включил прерывания (NVIC_EnableIRQ), написал вызов HAL_UART_RxCpltCallback() и HAL_UART_Receive_IT().

Но я пропустил это:

недействительными USART1_IRQHandler () { HAL_UART_IRQHandler (& huart1); }

Без обработчика выше прерывание не может быть перехвачено HAL_UART_RxCpltCallback() и приложением. входит в бесконечный цикл, так как не видит обработчика прерывания.