Я получил новую плату ядра 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 и собрать ответ в буфере, а затем проанализировать его. это общение.
помогите ребята..
С уважением, Оливия
Базовая инициализация 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() и приложением. входит в бесконечный цикл, так как не видит обработчика прерывания.
Скотт Сейдман
Всплеск напряжения
Бенс Кауликс
Бенс Кауликс
Бенс Кауликс
Оливия Кристи
Бенс Кауликс
Оливия Кристи