STM32F407IGHX与Ubuntu20.04虚拟串口通信

发布时间:2024-09-18  

为了让RobomasterC板(这块板用的是STM32F407IGHX的芯片)能与上位机进行通讯。我最近翻了不少博客和CSDN文章,看到了很多文章存在一些问题,经过了一下午试错,我成功实现了STM32F407IGHX利用STM32CubeIDE进行配置并然后用HAL库进行编程,与安装有ROS的Ubuntu进行虚拟串口通信。


在翻看博客的时候我发现,RM以及上下位机通信资料并不多,而且很多已有资料都只讲述了实现原理,却没有讲如何具体一步步实现某个功能,这就导致初学者可能在翻看过程中,越看越懵,反而写不出一份能用的代码。


所以这篇文章会尽可能详细的讲怎么实现串口通信,而尽量少讲其原理,由于很多文章都已经详尽的写出了串口通信的原理了,所以我就不在赘述原理而着重于实现过程。


此外,我也会把一些小问题和建议写出来,以便一篇文章就解决所有可能存在的问题。


一、概述

1、STM32端(所谓的下位机):这边采用的是通过有图形化的STM32CubeIDE配置工程,配置好USB-CDC创建一个虚拟串口,与上位机通信。

2、Ubuntu端(所谓的上位机):上位机是版本20.04的ubuntu,安装有版本为noetic的ROS,通过建立一个ROS节点来打开串口并建立通信。

二、STM32端具体实现过程

思路:利用STM32CubeIDE配置好USB-CDC,接着修改对应的头文件,自定义所需的函数。

1、配置过程

1)先配置时钟RCC,设置高速时钟High Speed Clock为内部时钟(Crystal/Ceramic Resonator),另一个暂时用不到所以不设置。

pYYBAGPgWCaAB9l7AASa33mKzYc484.png

2)配置下载与调试(必须设置,否则会锁芯片,到时候还需要通过BOOT重启,比较麻烦)

设置为Serial Wire,时钟为SysTick(当然看你到底有什么,如果你拥有的是ST-LINK,那么可以这样设置)

poYBAGPgWDOAZuGGAASGDlfWGk8236.png

3)设置USB模式,打开Connectivity,选择USB-OYG-FS(快速),选择Mode的Device_only(从机模式)。然后点开左下方的NVIC Settings,勾选Enabled,从而能够开启中断。

pYYBAGPgWEmASCHiAANdQFYYRmw168.png

poYBAGPgWF2ATzk1AASexP_Bahw862.pngpoYBAGPgWHeATX2sAATDFUTsjtw656.png

备注:还要返回到NVIC中,设置USB中断的优先级,这里设置个4就行(毕竟没有启动其他外设,所以中断就不需要太严谨)、

4)打开MiddleWare,设置USB的具体工作方式,选择Class For FS IP的Communication Device Class,即VCP(虚拟串口),其余设置保持默认即可,不需要额外修改。

pYYBAGPgWIWAdc4dAANrUHRyZUc732.png

5)时钟树设置(时钟树的设置,需要查阅所使用开发板的具体原理图)

例如,RobomasterC板原理图里是如此说明的,所以Input frequency要设置成12MHz。此外,下方画红线部分是USB的时钟,USB的时钟需要设置成48MHz才能工作,其余部分看自己的需求。

pYYBAGPgWJKAfkXTAAA8K_syjLo001.pngpYYBAGPgWKGAX5z4AAHFyEnxA58795.png

6)堆栈设置,堆栈的大小需要足够大,才能满足USB初始化的需求,此处设置Heap Size为0X600即可解决初始化失败的问题,另一个不用改。

poYBAGPgWK2AUjwQAAFlacL4880476.png

7)到此,所有的初始化已经结束了,只需要Ctrl+s,保存并生成代码即可,下方两个选项均选择Yes,即可生成STM32CubeIDE工程

pYYBAGPgWLyANge-AAAlH-eZ22M870.png
pYYBAGPgWMiATUvOAAAyikQ1uh0956.png

2、代码的修改

这里要先打开工程里的USB_DEVICE中的App的usbd_cdc_if.c,重构官方给出的代码,具体内容如下

pYYBAGPgWNaAQWTzAAKg8BNXg7g774.png

/* USER CODE BEGIN Header */

/**

  ******************************************************************************

  * @file           : usbd_cdc_if.c

  * @version        : v1.0_Cube

  * @brief          : Usb device for Virtual Com Port.

  ******************************************************************************

  * @attention

  *

  * Copyright (c) 2023 STMicroelectronics.

  * All rights reserved.

  *

  * This software is licensed under terms that can be found in the LICENSE file

  * in the root directory of this software component.

  * If no LICENSE file comes with this software, it is provided AS-IS.

  *

  ******************************************************************************

  */

/* USER CODE END Header */


/* Includes ------------------------------------------------------------------*/

#include 'usbd_cdc_if.h'


/* USER CODE BEGIN INCLUDE */


/* USER CODE END INCLUDE */


/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/

/* Private macro -------------------------------------------------------------*/


/* USER CODE BEGIN PV */

/* Private variables ---------------------------------------------------------*/


/* USER CODE END PV */


/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY

  * @brief Usb device library.

  * @{

  */


/** @addtogroup USBD_CDC_IF

  * @{

  */


/** @defgroup USBD_CDC_IF_Private_TypesDefinitions USBD_CDC_IF_Private_TypesDefinitions

  * @brief Private types.

  * @{

  */


/* USER CODE BEGIN PRIVATE_TYPES */


/* USER CODE END PRIVATE_TYPES */


/**

  * @}

  */


/** @defgroup USBD_CDC_IF_Private_Defines USBD_CDC_IF_Private_Defines

  * @brief Private defines.

  * @{

  */


/* USER CODE BEGIN PRIVATE_DEFINES */

/* USER CODE END PRIVATE_DEFINES */


/**

  * @}

  */


/** @defgroup USBD_CDC_IF_Private_Macros USBD_CDC_IF_Private_Macros

  * @brief Private macros.

  * @{

  */


/* USER CODE BEGIN PRIVATE_MACRO */


/* USER CODE END PRIVATE_MACRO */


/**

  * @}

  */


/** @defgroup USBD_CDC_IF_Private_Variables USBD_CDC_IF_Private_Variables

  * @brief Private variables.

  * @{

  */

/* Create buffer for reception and transmission           */

/* It's up to user to redefine and/or remove those define */

/** Received data over USB are stored in this buffer      */

uint8_t UserRxBufferFS[APP_RX_DATA_SIZE];


/** Data to send over USB CDC are stored in this buffer   */

uint8_t UserTxBufferFS[APP_TX_DATA_SIZE];


/* USER CODE BEGIN PRIVATE_VARIABLES */


/* USER CODE END PRIVATE_VARIABLES */


/**

  * @}

  */


/** @defgroup USBD_CDC_IF_Exported_Variables USBD_CDC_IF_Exported_Variables

  * @brief Public variables.

  * @{

  */


extern USBD_HandleTypeDef hUsbDeviceFS;


/* USER CODE BEGIN EXPORTED_VARIABLES */


/* USER CODE END EXPORTED_VARIABLES */


/**

  * @}

  */


/** @defgroup USBD_CDC_IF_Private_FunctionPrototypes USBD_CDC_IF_Private_FunctionPrototypes

  * @brief Private functions declaration.

  * @{

  */


static int8_t CDC_Init_FS(void);

static int8_t CDC_DeInit_FS(void);

static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length);

static int8_t CDC_Receive_FS(uint8_t* pbuf, uint32_t *Len);

static int8_t CDC_TransmitCplt_FS(uint8_t *pbuf, uint32_t *Len, uint8_t epnum);


/* USER CODE BEGIN PRIVATE_FUNCTIONS_DECLARATION */


/* USER CODE END PRIVATE_FUNCTIONS_DECLARATION */


/**

  * @}

  */


USBD_CDC_ItfTypeDef USBD_Interface_fops_FS =

{

  CDC_Init_FS,

  CDC_DeInit_FS,

  CDC_Control_FS,

  CDC_Receive_FS,

  CDC_TransmitCplt_FS

};


/* Private functions ---------------------------------------------------------*/

/**

  * @brief  Initializes the CDC media low layer over the FS USB IP

  * @retval USBD_OK if all operations are OK else USBD_FAIL

  */

static int8_t CDC_Init_FS(void)

{

  /* USER CODE BEGIN 3 */

  /* Set Application Buffers */

  USBD_CDC_SetTxBuffer(&hUsbDeviceFS, UserTxBufferFS, 0);

  USBD_CDC_SetRxBuffer(&hUsbDeviceFS, UserRxBufferFS);

  return (USBD_OK);

  /* USER CODE END 3 */

}


/**

  * @brief  DeInitializes the CDC media low layer

  * @retval USBD_OK if all operations are OK else USBD_FAIL

  */

static int8_t CDC_DeInit_FS(void)

{

  /* USER CODE BEGIN 4 */

  return (USBD_OK);

  /* USER CODE END 4 */

}


/**

  * @brief  Manage the CDC class requests

  * @param  cmd: Command code

  * @param  pbuf: Buffer containing command data (request parameters)

  * @param  length: Number of data to be sent (in bytes)

  * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL

  */

static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length)

{

  /* USER CODE BEGIN 5 */

  switch(cmd)

  {

    case CDC_SEND_ENCAPSULATED_COMMAND:


    break;


    case CDC_GET_ENCAPSULATED_RESPONSE:


    break;


    case CDC_SET_COMM_FEATURE:


    break;


    case CDC_GET_COMM_FEATURE:


    break;


    case CDC_CLEAR_COMM_FEATURE:


    break;


  /*******************************************************************************/

  /* Line Coding Structure                                                       */

  /*-----------------------------------------------------------------------------*/

  /* Offset | Field       | Size | Value  | Description                          */

  /* 0      | dwDTERate   |   4  | Number |Data terminal rate, in bits per second*/

  /* 4      | bCharFormat |   1  | Number | Stop bits                            */

  /*                                        0 - 1 Stop bit                       */

  /*                                        1 - 1.5 Stop bits                    */

  /*                                        2 - 2 Stop bits                      */

  /* 5      | bParityType |  1   | Number | Parity                               */

  /*                                        0 - None                             */

  /*                                        1 - Odd                              */

  /*                                        2 - Even                             */

  /*                                        3 - Mark                             */

  /*                                        4 - Space                            */

  /* 6      | bDataBits  |   1   | Number Data bits (5, 6, 7, 8 or 16).          */

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>