如何将Quectel L89H模块连接到STM32WL55JC1并通过UART获取数据?

2fjabf4q  于 2023-06-21  发布在  其他
关注(0)|答案(1)|浏览(120)

最近我开始使用STM32开发GNSS,我对STM32生态系统非常陌生。我有一个IRNSS点击从MikroE有L89H,我正试图集成L89H与STM32WL55JC1控制器。
我已经实现了UART接收来自L89H的NMEA消息。我已经将TX、RX、3、3v、GND引脚连接到STM32的RX、TX、3.3v和地。但是当我执行代码时,串行监视器上没有显示NMEA消息。我不知道我要去哪里,我会很感激在这种情况下对我的帮助。
当我插入设备时,我可以看到PPS LED正在 Flink ,这意味着我的设备正在接收卫星信号。
文档中提到默认波特率为9600。所以我使用默认波特率。
我将相同的IRNSS点击连接到Clicker 2 STM32控制器,当我上传示例GNSS FW时,我可以看到控制器接收到的NMEA消息。但是当我连接到STM32WL55JC1时,同一块板不工作。
我正在使用以下代码读取和打印CUBE IDE中的NMEA消息:

#include "main.h"
#include "malloc.h"
#include "string.h"
 
 
UART_HandleTypeDef huart1;
 
uint8_t* RX_BUFFER = NULL;
 
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);
 
int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_USART1_UART_Init();
 
  while (1)
  {
 
      RX_BUFFER = (uint8_t*)malloc(400 * sizeof(uint8_t));
      HAL_UART_Receive(&huart1,(uint8_t *)RX_BUFFER,350,500);
      HAL_Delay(1000);
      int size = sizeof(RX_BUFFER);
      HAL_UART_Transmit(&huart1,(uint8_t *)RX_BUFFER,size,500);
      HAL_Delay(1000);
  }
 
}
 
 
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
 
 
  HAL_PWR_EnableBkUpAccess();
  __HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW);
 
  /** Configure the main internal regulator output voltage
  */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
 
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE|RCC_OSCILLATORTYPE_MSI;
  RCC_OscInitStruct.LSEState = RCC_LSE_ON;
  RCC_OscInitStruct.MSIState = RCC_MSI_ON;
  RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
  RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1;
  RCC_OscInitStruct.PLL.PLLN = 24;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
 
  /** Configure the SYSCLKSource, HCLK, PCLK1 and PCLK2 clocks dividers
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK3|RCC_CLOCKTYPE_HCLK
                              |RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1
                              |RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.AHBCLK3Divider = RCC_SYSCLK_DIV1;
 
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}
 
/**
  * @brief USART1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_USART1_UART_Init(void)
{
 
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 9600;
  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_ONE_BIT_SAMPLE_DISABLE;
  huart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;
  huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetTxFifoThreshold(&huart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetRxFifoThreshold(&huart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_DisableFifoMode(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
 
 
}
 
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
 
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
 
  HAL_GPIO_WritePin(Wake_up_GPIO_Port, Wake_up_Pin, GPIO_PIN_RESET);
 
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(Reset_GPIO_Port, Reset_Pin, GPIO_PIN_RESET);
 
  /*Configure GPIO pin : Wake_up_Pin */
  GPIO_InitStruct.Pin = Wake_up_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(Wake_up_GPIO_Port, &GPIO_InitStruct);
 
  /*Configure GPIO pin : Reset_Pin */
  GPIO_InitStruct.Pin = Reset_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(Reset_GPIO_Port, &GPIO_InitStruct);
 
 
}
 
void Error_Handler(void)
{
  __disable_irq();
  while (1)
  {
  }
}
 
#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

如果您需要任何其他信息,请告诉我。
最好的问候,Pavan Ravuru

rta7y2nd

rta7y2nd1#

  • 警告:* 我对STM32 HAL不太熟悉

有些问题...
1.在每次循环迭代中执行malloc。您正在泄漏内存。将malloc移动到while上方

  1. sizeof(RXBUFFER)不正确。它是一个 * 指针 * 的大小,而 * 不是 * 该指针指向的长度。所以,这是4或8个字节,而不是你期望的400个字节。
    1.你不是在处理接收超时。
  2. 400字节[在9600波特时]是0.4秒的数据。这会产生相对较大的 * 延迟 *,可能导致UART的内部FIFO溢出。最好使用更小的值。
    1.如果UART正在接收GNSS/GPS数据,为什么要将其回显到设备?我的怀疑是,如果设备接受数据[在所有],它是配置它。所以,回传GPS数据只是向设备发送了胡言乱语?
    1.你为什么要做HAL_Delay
    1.不需要那么多uint8_t *转换。
    我看过的大多数指南都推荐使用中断或DMA(例如:HAL_UART_Receive_ITHAL_UART_Receive_DMA
    我找到了HAL_UART_Receive的源代码:https://www.disca.upv.es/aperles/arm_cortex_m3/llibre/st/STM32F439xx_User_Manual/stm32f4xx__hal__uart_8c_source.html
    从它,如果你得到一个超时,[我认为]你可以使用huart->RxXferCount来确定传输的实际数据量。
    这是[一个小技巧],代替使用中断或DMA版本。
    您可能希望实现环形缓冲区或将索引“滑动”到单独的RX和TX缓冲区中。
    再问一次...你为什么把GPS数据传回设备?这对我来说毫无意义。您是否需要/有另一个UART或其他设备?这只是示例代码,您想处理GPS数据吗?
    下面是一些重构的代码。这只是一个“猜测”。
UART_HandleTypeDef huart1;

uint8_t *rx_buffer = NULL;

// NOTE/BUG: this might produce better latency with a much smaller value
#define BUFMAX      400

int
main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_USART1_UART_Init();

    rx_buffer = malloc(BUFMAX)
    // check for malloc failure ...

    int actual_rxlen;
    HAL_StatusTypeDef code;

    // expected amount to read
    // NOTES:
    // (1) we may want a smaller amount to reduce latency on the
    //     HAL_UART_Receive call
    int expected_rxlen = BUFMAX;

    while (1) {
        code = HAL_UART_Receive(&huart1, rx_buffer, expected_rxlen, 500);

        // normal transfer
        if (code == HAL_OK)
            actual_rxlen = expected_rxlen;

        // timeout ...
        else
            actual_rxlen = expected_rxlen - huart1.RxXferCount;

// NOTE/BUG: why use huart1 here???
// NOTE/BUG: this has the same timeout potential/issue as the receive above
        if (actual_rxlen > 0)
            HAL_UART_Transmit(&huart1, rx_buffer, actual_rxlen, 500);
    }
}

相关问题