CubeMX生成STM32工程文件,对串口测试使用(一)

  • 目录

    引言

    硬件连接

    软件配置步骤

    步骤一:开启 USART 和相关时钟

    步骤二:配置 USART 参数

    步骤三:配置USART(GPIO)

    数据发送和接收

    发送数据

    阻塞方式发送数据

    中断方式发送数据

    接收数据

     阻塞方式接收数据

     中断方式接收数据


    引言

    • 项目基于STM32F103C8T6开发,工程代码基于CubeMX生成,具体代码生成步骤见用CubeMX生成STM32F103C8T6的工程。本节对生成的工程代码进行初步的解析,实现利用串口实现简单的数据收发。
  • 硬件连接

    • 首先,确保 STM32 芯片的 USART 引脚正确连接到外部设备。对于 USART1,通常 TX 引脚(发送引脚)连接到外部设备的接收引脚,RX 引脚(接收引脚)连接到外部设备的发送引脚,即交叉连接。
  • 软件配置步骤

    • 主要介绍HAL库工程对串口的初始化流程,这部分初始化CubeMX已经帮我们写好了,下
      面对HAL库对串口初始化流程进行介绍。

    • 步骤一:开启 USART 和相关时钟

      • 在使用 USART 之前,需要开启 USART 模块以及其对应的时钟。对于 USART1,在 STM32CubeMX 生成的代码中,通常在main函数的初始化部分或者MX_GPIO_InitMX_USART1_Init函数中有相关的时钟配置。

    • 步骤二:配置 USART 参数

      • 这里将 USART1 的波特率设置为 115200bps,数据位长度为 8 位,1 个停止位,无奇偶校验,工作模式为发送和接收,无硬件流控制,过采样为 16 倍。通过UART_HandleTypeDef结构体来配置 USART 的参数。这些参数包括波特率、数据位长度、停止位、奇偶校验位等。

      • 以下是一个配置 USART1 参数的代码片段:

  • /* USART1 init function */
    
    void MX_USART1_UART_Init(void)
    {
    
      /* USER CODE BEGIN USART1_Init 0 */
    
      /* USER CODE END USART1_Init 0 */
    
      /* USER CODE BEGIN USART1_Init 1 */
    
      /* USER CODE END USART1_Init 1 */
      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;
      if (HAL_UART_Init(&huart1) != HAL_OK)
      {
        Error_Handler();
      }
      /* USER CODE BEGIN USART1_Init 2 */
    
      /* USER CODE END USART1_Init 2 */
    
    }
    • 步骤三:配置USART(GPIO)

  • void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
    {
    
      GPIO_InitTypeDef GPIO_InitStruct = {0};
      if(uartHandle->Instance==USART1)
      {
      /* USER CODE BEGIN USART1_MspInit 0 */
    
      /* USER CODE END USART1_MspInit 0 */
        /* USART1 clock enable */
        __HAL_RCC_USART1_CLK_ENABLE();
    
        __HAL_RCC_GPIOA_CLK_ENABLE();
        /**USART1 GPIO Configuration
        PA9     ------> USART1_TX
        PA10     ------> USART1_RX
        */
        GPIO_InitStruct.Pin = Current_485_TX_Pin;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
        HAL_GPIO_Init(Current_485_TX_GPIO_Port, &GPIO_InitStruct);
    
        GPIO_InitStruct.Pin = Current_485_RX_Pin;
        GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        HAL_GPIO_Init(Current_485_RX_GPIO_Port, &GPIO_InitStruct);
    
        /* USART1 interrupt Init */
        HAL_NVIC_SetPriority(USART1_IRQn, 1, 0);
        HAL_NVIC_EnableIRQ(USART1_IRQn);
      /* USER CODE BEGIN USART1_MspInit 1 */
    
      /* USER CODE END USART1_MspInit 1 */
      }
      else if(uartHandle->Instance==USART2)
      {
      /* USER CODE BEGIN USART2_MspInit 0 */
    
      /* USER CODE END USART2_MspInit 0 */
        /* USART2 clock enable */
        __HAL_RCC_USART2_CLK_ENABLE();
    
        __HAL_RCC_GPIOA_CLK_ENABLE();
        /**USART2 GPIO Configuration
        PA2     ------> USART2_TX
        PA3     ------> USART2_RX
        */
        GPIO_InitStruct.Pin = BDS_TX_Pin;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
        HAL_GPIO_Init(BDS_TX_GPIO_Port, &GPIO_InitStruct);
    
        GPIO_InitStruct.Pin = BDS_RX_Pin;
        GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        HAL_GPIO_Init(BDS_RX_GPIO_Port, &GPIO_InitStruct);
    
        /* USART2 interrupt Init */
        HAL_NVIC_SetPriority(USART2_IRQn, 1, 0);
        HAL_NVIC_EnableIRQ(USART2_IRQn);
      /* USER CODE BEGIN USART2_MspInit 1 */
    
      /* USER CODE END USART2_MspInit 1 */
      }
      else if(uartHandle->Instance==USART3)
      {
      /* USER CODE BEGIN USART3_MspInit 0 */
    
      /* USER CODE END USART3_MspInit 0 */
        /* USART3 clock enable */
        __HAL_RCC_USART3_CLK_ENABLE();
    
        __HAL_RCC_GPIOB_CLK_ENABLE();
        /**USART3 GPIO Configuration
        PB10     ------> USART3_TX
        PB11     ------> USART3_RX
        */
        GPIO_InitStruct.Pin = LORA_TX_Pin;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
        HAL_GPIO_Init(LORA_TX_GPIO_Port, &GPIO_InitStruct);
    
        GPIO_InitStruct.Pin = LORA_RX_Pin;
        GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        HAL_GPIO_Init(LORA_RX_GPIO_Port, &GPIO_InitStruct);
    
        /* USART3 interrupt Init */
        HAL_NVIC_SetPriority(USART3_IRQn, 1, 0);
        HAL_NVIC_EnableIRQ(USART3_IRQn);
      /* USER CODE BEGIN USART3_MspInit 1 */
    
      /* USER CODE END USART3_MspInit 1 */
      }
    }

    数据发送和接收

    • 发送数据

    • 阻塞方式发送数据

      可以使用HAL_UART_Transmit函数。例如,发送一个字符串 “Hello World”。
uint8_t data[] = "Hello World";
HAL_UART_Transmit(&huart1, data, sizeof(data), 1000);

              这个函数会将data数组中的数据通过 USART1 发送出去,数据长度为sizeof(data)字节,超时时间为 1000 毫秒。如果在超时时间内没有发送完所有数据,函数会返回错误。

             中断方式发送数据

               使用HAL_UART_Transmit_IT函数。例如:

uint8_t data[] = "Async Send";
HAL_UART_Transmit_IT(&huart1, data, sizeof(data));

              调用这个函数后,数据发送过程会在后台通过中断来处理,函数会立即返回,程序可以继续执行其他任务。当数据发送完成后,会触发相应的中断服务程序。

        接收数据

          阻塞方式接收数据

           使用HAL_UART_Receive函数。例如,接收 10 个字节的数据到receiveBuffer中,程序会一直等待,直到接收到指定长度的数据或者超时。

uint8_t receiveBuffer[10];
HAL_UART_Receive(&huart1, receiveBuffer, sizeof(receiveBuffer), 1000);

          中断方式接收数据

           使用HAL_UART_Receive_IT函数,函数调用后立即返回,当接收到数据时会触发中断服务程序来处理数据接收

uint8_t receiveBuffer[10];
HAL_UART_Receive_IT(&huart1, receiveBuffer, sizeof(receiveBuffer));

你可能感兴趣的:(单片机,stm32,嵌入式硬件,信息与通信)