0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

STM32F407IGHX與Ubuntu20.04虛擬串口通信

墨髯啊 ? 來(lái)源:墨髯啊 ? 作者:墨髯啊 ? 2023-02-06 09:34 ? 次閱讀

為了讓RobomasterC板(這塊板用的是STM32F407IGHX的芯片)能與上位機(jī)進(jìn)行通訊。我最近翻了不少博客和CSDN文章,看到了很多文章存在一些問(wèn)題,經(jīng)過(guò)了一下午試錯(cuò),我成功實(shí)現(xiàn)了STM32F407IGHX利用STM32CubeIDE進(jìn)行配置并然后用HAL庫(kù)進(jìn)行編程,與安裝有ROS的Ubuntu進(jìn)行虛擬串口通信。

在翻看博客的時(shí)候我發(fā)現(xiàn),RM以及上下位機(jī)通信資料并不多,而且很多已有資料都只講述了實(shí)現(xiàn)原理,卻沒(méi)有講如何具體一步步實(shí)現(xiàn)某個(gè)功能,這就導(dǎo)致初學(xué)者可能在翻看過(guò)程中,越看越懵,反而寫(xiě)不出一份能用的代碼。

所以這篇文章會(huì)盡可能詳細(xì)的講怎么實(shí)現(xiàn)串口通信,而盡量少講其原理,由于很多文章都已經(jīng)詳盡的寫(xiě)出了串口通信的原理了,所以我就不在贅述原理而著重于實(shí)現(xiàn)過(guò)程。

此外,我也會(huì)把一些小問(wèn)題和建議寫(xiě)出來(lái),以便一篇文章就解決所有可能存在的問(wèn)題。

一、概述

1、STM32端(所謂的下位機(jī)):這邊采用的是通過(guò)有圖形化的STM32CubeIDE配置工程,配置好USB-CDC創(chuàng)建一個(gè)虛擬串口,與上位機(jī)通信。

2、Ubuntu端(所謂的上位機(jī)):上位機(jī)是版本20.04的ubuntu,安裝有版本為noetic的ROS,通過(guò)建立一個(gè)ROS節(jié)點(diǎn)來(lái)打開(kāi)串口并建立通信。

二、STM32端具體實(shí)現(xiàn)過(guò)程

思路:利用STM32CubeIDE配置好USB-CDC,接著修改對(duì)應(yīng)的頭文件,自定義所需的函數(shù)。

1、配置過(guò)程

1)先配置時(shí)鐘RCC,設(shè)置高速時(shí)鐘High Speed Clock為內(nèi)部時(shí)鐘(Crystal/Ceramic Resonator),另一個(gè)暫時(shí)用不到所以不設(shè)置。

pYYBAGPgWCaAB9l7AASa33mKzYc484.png

2)配置下載與調(diào)試(必須設(shè)置,否則會(huì)鎖芯片,到時(shí)候還需要通過(guò)BOOT重啟,比較麻煩)

設(shè)置為Serial Wire,時(shí)鐘為SysTick(當(dāng)然看你到底有什么,如果你擁有的是ST-LINK,那么可以這樣設(shè)置)

poYBAGPgWDOAZuGGAASGDlfWGk8236.png

3)設(shè)置USB模式,打開(kāi)Connectivity,選擇USB-OYG-FS(快速),選擇Mode的Device_only(從機(jī)模式)。然后點(diǎn)開(kāi)左下方的NVIC Settings,勾選Enabled,從而能夠開(kāi)啟中斷。

pYYBAGPgWEmASCHiAANdQFYYRmw168.png

poYBAGPgWF2ATzk1AASexP_Bahw862.pngpoYBAGPgWHeATX2sAATDFUTsjtw656.png

備注:還要返回到NVIC中,設(shè)置USB中斷的優(yōu)先級(jí),這里設(shè)置個(gè)4就行(畢竟沒(méi)有啟動(dòng)其他外設(shè),所以中斷就不需要太嚴(yán)謹(jǐn))、

4)打開(kāi)MiddleWare,設(shè)置USB的具體工作方式,選擇Class For FS IP的Communication Device Class,即VCP(虛擬串口),其余設(shè)置保持默認(rèn)即可,不需要額外修改。

pYYBAGPgWIWAdc4dAANrUHRyZUc732.png

5)時(shí)鐘樹(shù)設(shè)置(時(shí)鐘樹(shù)的設(shè)置,需要查閱所使用開(kāi)發(fā)板的具體原理圖)

例如,RobomasterC板原理圖里是如此說(shuō)明的,所以Input frequency要設(shè)置成12MHz。此外,下方畫(huà)紅線部分是USB的時(shí)鐘,USB的時(shí)鐘需要設(shè)置成48MHz才能工作,其余部分看自己的需求。

pYYBAGPgWJKAfkXTAAA8K_syjLo001.pngpYYBAGPgWKGAX5z4AAHFyEnxA58795.png

6)堆棧設(shè)置,堆棧的大小需要足夠大,才能滿足USB初始化的需求,此處設(shè)置Heap Size為0X600即可解決初始化失敗的問(wèn)題,另一個(gè)不用改。

poYBAGPgWK2AUjwQAAFlacL4880476.png

7)到此,所有的初始化已經(jīng)結(jié)束了,只需要Ctrl+s,保存并生成代碼即可,下方兩個(gè)選項(xiàng)均選擇Yes,即可生成STM32CubeIDE工程

pYYBAGPgWLyANge-AAAlH-eZ22M870.png
pYYBAGPgWMiATUvOAAAyikQ1uh0956.png

2、代碼的修改

這里要先打開(kāi)工程里的USB_DEVICE中的App的usbd_cdc_if.c,重構(gòu)官方給出的代碼,具體內(nèi)容如下

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).          */
  /*******************************************************************************/
    case CDC_SET_LINE_CODING:

    break;

    case CDC_GET_LINE_CODING:

    break;

    case CDC_SET_CONTROL_LINE_STATE:

    break;

    case CDC_SEND_BREAK:

    break;

  default:
    break;
  }

  return (USBD_OK);
  /* USER CODE END 5 */
}

/**
  * @brief  Data received over USB OUT endpoint are sent over CDC interface
  *         through this function.
  *
  *         @note
  *         This function will issue a NAK packet on any OUT packet received on
  *         USB endpoint until exiting this function. If you exit this function
  *         before transfer is complete on CDC interface (ie. using DMA controller)
  *         it will result in receiving more data while previous ones are still
  *         not sent.
  *
  * @param  Buf: Buffer of data to be received
  * @param  Len: Number of data received (in bytes)
  * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
  */
static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{
  /* USER CODE BEGIN 6 */
  USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
  USBD_CDC_ReceivePacket(&hUsbDeviceFS);
  return (USBD_OK);
  /* USER CODE END 6 */
}

/**
  * @brief  CDC_Transmit_FS
  *         Data to send over USB IN endpoint are sent over CDC interface
  *         through this function.
  *         @note
  *
  *
  * @param  Buf: Buffer of data to be sent
  * @param  Len: Number of data to be sent (in bytes)
  * @retval USBD_OK if all operations are OK else USBD_FAIL or USBD_BUSY
  */
uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
{
  uint8_t result = USBD_OK;
  /* USER CODE BEGIN 7 */
  USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData;
  if (hcdc->TxState != 0){
    return USBD_BUSY;
  }
  USBD_CDC_SetTxBuffer(&hUsbDeviceFS, Buf, Len);
  result = USBD_CDC_TransmitPacket(&hUsbDeviceFS);
  /* USER CODE END 7 */
  return result;
}

/**
  * @brief  CDC_TransmitCplt_FS
  *         Data transmitted callback
  *
  *         @note
  *         This function is IN transfer complete callback used to inform user that
  *         the submitted Data is successfully sent over USB.
  *
  * @param  Buf: Buffer of data to be received
  * @param  Len: Number of data received (in bytes)
  * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
  */
static int8_t CDC_TransmitCplt_FS(uint8_t *Buf, uint32_t *Len, uint8_t epnum)
{
  uint8_t result = USBD_OK;
  /* USER CODE BEGIN 13 */
  if(flag)
  {
      CDC_Transmit_FS(UserTxBufferFS, APP_TX_DATA_SIZE);
  }

  UNUSED(Buf);
  UNUSED(Len);
  UNUSED(epnum);
  /* USER CODE END 13 */
  return result;
}

/* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION */

/* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */

/**
  * @}
  */

/**
  * @}
  */

注意,不要輕易重新初始化代碼,否則這些對(duì)官方代碼的修改會(huì)被重新覆蓋,導(dǎo)致又要再改一遍,最好一次就初始化好。

3、自定義結(jié)構(gòu)體

在這里我不會(huì)給出具體的代碼,但我會(huì)舉個(gè)例子來(lái)說(shuō)明如何定義所需結(jié)構(gòu)體。

typedef struct ControlData_Chassis _Controldata_Chassis;//這里是定義該結(jié)構(gòu)體的別名
typedef struct ControlData_Chassis{
    uint8_t Y_Speed; //縱軸方向速度
    uint8_t X_Speed; //橫軸方向速度
    uint8_t Rotational_Speed; //小車(chē)旋轉(zhuǎn)速度
    uint8_t Chassis_State; //底盤(pán)狀態(tài)
}*_Controldata_ChassisInfo;//這里定義了該結(jié)構(gòu)體的結(jié)構(gòu)體指針。C語(yǔ)言允許這樣的操作!

在實(shí)際操作的時(shí)候,可以把這種結(jié)構(gòu)體變量的數(shù)值放入到指定的數(shù)組中(這也就是所謂的打包。而把接收到的數(shù)組中的數(shù)據(jù)按結(jié)構(gòu)體成員形式放入到指定結(jié)構(gòu)體的過(guò)程,就稱之為解包。),從而實(shí)現(xiàn)打包。

此外,可以把結(jié)構(gòu)體定義在頭文件中,便于在.c文件里函數(shù)的具體實(shí)現(xiàn)。

4、自定義解包/打包函數(shù)

這里我也只會(huì)給出一個(gè)例子。

void Pack_Data(_FeedBack* feedback,uint8_t* feedArray)
{    //把數(shù)組中信息封入數(shù)據(jù)包中
    feedArray[0] = 0XFF;//這是幀頭
    feedArray[1] = feedback->Shoot_Mode;
    feedArray[2] = feedback->Shoot_Speed;
    feedArray[3] = feedback->Armor_Id;
    feedArray[4] = (uint8_t)(feedback->HP_Remain);
    feedArray[5] = (uint8_t)(feedback->HP_Remain >> 8);
    feedArray[6] = 0XAA;//暫時(shí)無(wú)意義
    feedArray[7] = 0XFE;//芝士幀尾
}

實(shí)際上,解包函數(shù)也是類似上文的操作,只不過(guò)是反了過(guò)來(lái)。

注:1.可以利用與 “ | ” 來(lái)將兩個(gè)數(shù)據(jù)拼成一個(gè),將拆分的數(shù)據(jù)合成一個(gè)。

2.幀頭和幀尾起到了驗(yàn)證的作用,可以用來(lái)驗(yàn)證數(shù)據(jù)完整性。

5、自定義發(fā)送/接收函數(shù)

int CDC_SendFeed(uint8_t* Fed, uint16_t Len)
{
    CDC_Transmit_FS(Fed, Len);
    return 0;
}

上文調(diào)用了之前修改過(guò)的官方代碼,這樣模塊化的代碼更容易理解與閱讀。

6、備注

1)如果你要定義一個(gè)結(jié)構(gòu)體指針并想給它賦值,那么你需要在賦值前給它分配空間,否則這個(gè)指針無(wú)法進(jìn)行賦值。

例子:

_FeedBack* ft,fd;

ft=(_FeedBack*)malloc(sizeof(_FeedBack));//這里是結(jié)構(gòu)體的空間分配以及具體賦值

三、Ubuntu端具體實(shí)現(xiàn)過(guò)程

思路:利用ROS的serial包來(lái)實(shí)現(xiàn)串口通信。

1、創(chuàng)建工程

此處創(chuàng)建工程,要記得包含roscpp rospy std_msgs 以及serial包(serial包是串口通信的關(guān)鍵)

2、創(chuàng)建主程序

我這里使用的是Visual Studio Code來(lái)編寫(xiě)代碼。

可以先在終端切換到你所需要編寫(xiě)代碼的文件夾,然后輸入 code . (注意后面那個(gè)點(diǎn)也是要輸入的,然后VS就會(huì)啟動(dòng)并打開(kāi)這個(gè)文件夾)。

poYBAGPgWQqAF9K5AABG8N0_WpQ144.png

接著就可以在VS里創(chuàng)建新.cpp文件。

注意:1、如果#include "ros/ros.h"時(shí)發(fā)現(xiàn)找不到所需的頭文件,那么需要修改該工程的配置。按住Shift+Ctrl+P ,即可打開(kāi)配置欄,然后選中第一個(gè)即可。

2、創(chuàng)建好.cpp文件,記得要到CMakeList.txt里添加上該頭文件(其實(shí)只要去掉這三個(gè)語(yǔ)句前的#號(hào),并修改部分內(nèi)容即可,其他部分不用動(dòng))。

add_executable(robo-serial src/robo-serial.cpp)

add_dependencies(robo-serial ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

target_link_libraries(robo-serial

${catkin_LIBRARIES}

)

可以參考下方貼出的代碼來(lái)修改你的配置。

{
    "configurations": [
      {
        "browse": {
          "databaseFilename": "${workspaceFolder}/.vscode/browse.vc.db",
          "limitSymbolsToIncludedHeaders": false
        },
        "includePath": [
          "/home/jinshuai/ros-test/tf_test/devel/include/**",
          "/opt/ros/noetic/include/**",
          "/usr/include/**"
        ],
        "name": "ROS",
        "intelliSenseMode": "gcc-x64",
        "compilerPath": "/usr/bin/gcc",
        "cStandard": "gnu11",
        "cppStandard": "c++14"
      }
    ],
    "version": 4
  }

我在這里會(huì)給出初始化的大概配置,而具體代碼不會(huì)提供,各位可以參考這個(gè)代碼進(jìn)行修改。

#include "serial/serial.h"http://調(diào)用串口相關(guān)頭文件
#include "ros/ros.h"http://在ros下使用serial包進(jìn)行通訊
#include "iostream"
//全局變量定義區(qū)
    serial::Serial sp;//創(chuàng)建一個(gè)Serial類
    serial::Timeout to = serial::Timeout::simpleTimeout(5000);//創(chuàng)建timeout//全局變量定義區(qū)


int main(int argc,char** argv){
    setlocale(LC_CTYPE,"zh_CN.utf8");//設(shè)置中文輸出
    ros::init(argc,argv,"serial_port");
    ros::NodeHandle n;//創(chuàng)建句柄
    // serial::Serial sp;//創(chuàng)建一個(gè)Serial類
    // serial::Timeout to = serial::Timeout::simpleTimeout(5000);//創(chuàng)建timeout
    sp.setPort("/dev/ttyACM0");//設(shè)置要打開(kāi)的串口名稱
    sp.setBaudrate(115200);//設(shè)置串口通信的波特率
    sp.setTimeout(to);//串口設(shè)置timeout
    try
    {
        sp.open();//嘗試啟動(dòng)串口
    }
    catch(serial::IOException& e)
    {
        ROS_ERROR_STREAM("Unable to open port!Please check your setting!");
        return -1;
    }
    if(sp.isOpen())
    {
        ROS_INFO_STREAM("/dev/ttyACM0 is opened!");//判斷是否成功開(kāi)啟串口
    }
    else
    {
        return -1;
    }
    ros::Rate loop_rate(500);
    while(ros::ok())
    {
        Data_Receive();//此處為自定義函數(shù),不要復(fù)制,我沒(méi)給出具體實(shí)現(xiàn)過(guò)程
        Data_Transmit();//此處為自定義函數(shù),不要復(fù)制,我沒(méi)給出具體實(shí)現(xiàn)過(guò)程
 loop_rate.sleep(); 
}
 sp.close();
 return 0;
 }

3、備注

1)創(chuàng)建結(jié)構(gòu)體,枚舉,打包/解包函數(shù),發(fā)送/接收函數(shù)和STM32端幾乎一樣,所以可以按照STM32端的思路來(lái)操作。但是要注意,上位機(jī)的代碼應(yīng)該是和下位機(jī)相對(duì)應(yīng)的,下位機(jī)接收到的數(shù)據(jù)是來(lái)自上位機(jī)的,所以幀頭幀尾以及結(jié)構(gòu)體成員應(yīng)該保持一致。避免發(fā)送出錯(cuò)。

2)如果你想要在ROS工程里自定義一個(gè)頭文件和C文件,那么記得去修改CMakeList.txt里的

add_executable(robo-serial src/robo-serial.cpp)

add_dependencies(robo-serial Test ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

target_link_libraries(robo-serial Test

${catkin_LIBRARIES}

)

add_library(Serial

src/Test.h

src/Test.cpp

)

否則會(huì)報(bào)錯(cuò),找不到該頭文件。修改方式參考上圖粗體部分。

四、可能存在的報(bào)錯(cuò)

1、如果PC無(wú)法連接到虛擬串口,并顯示“無(wú)法獲取設(shè)備描述符”

我的解決辦法:

1)線路連接不良或者線路有問(wèn)題,建議重新連接或者換一根線(有一定可能)

2)工程配置錯(cuò)誤,時(shí)鐘樹(shù)有誤(需要根據(jù)你的開(kāi)發(fā)板,重新觀察時(shí)鐘樹(shù)的配置。是否引入了正確的時(shí)鐘,以及是否配置好了USB時(shí)鐘(48MHz))

2、Ubuntu無(wú)法打開(kāi)串口

1)連接有問(wèn)題或者根本沒(méi)有連接

2)沒(méi)有權(quán)限打開(kāi)串口(進(jìn)入管理員模式(終端輸入sudo -i),接著編輯/etc/udev/rules.d/70-ttyusb.rules,加上一行KERNEL=="ttyUSB[0-9]*",MODE="0666" 保存退出即可。注意,要看具體需要給什么串口權(quán)限,虛擬串口一般叫做/dev/ttyACM0,所以可以寫(xiě)入KERNEL=="ttyACM[0-9]*",MODE="0666" ,而真實(shí)串口一般叫/dev/ttyUSB0,可以用KERNEL=="ttyUSB[0-9]*",MODE="0666" 。)

3)STM32CubeIDE報(bào)錯(cuò)GDB服務(wù)端無(wú)法打開(kāi)。

我在博客里已經(jīng)給出了詳盡的解釋

關(guān)于STM32CubeIDE無(wú)法正常啟動(dòng)GDB服務(wù)端的解決辦法 - 墨髯 - 博客園 (cnblogs.com)

五、備注

1、實(shí)際上,很多的配置都需要看自己的需求來(lái)搞,我之前就盲目抄了其他人的時(shí)鐘樹(shù)配置,導(dǎo)致設(shè)備無(wú)法被電腦識(shí)別。所以如果出現(xiàn)問(wèn)題,最好先去翻翻官方文檔。很多問(wèn)題都可以通過(guò)官方文檔來(lái)解決。

2、整片文章里,我?guī)缀鯖](méi)有提到過(guò)函數(shù)報(bào)錯(cuò)的問(wèn)題,主要是我暫時(shí)沒(méi)有考慮關(guān)于報(bào)錯(cuò)的問(wèn)題,所以代碼中很少會(huì)有關(guān)于報(bào)錯(cuò)的內(nèi)容。這個(gè)問(wèn)題,可以等以后完善此通訊協(xié)議時(shí)解決。

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 通信協(xié)議
    +關(guān)注

    關(guān)注

    28

    文章

    911

    瀏覽量

    40403
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11342

    瀏覽量

    210222
  • STM32
    +關(guān)注

    關(guān)注

    2271

    文章

    10923

    瀏覽量

    357215
  • 串口通信
    +關(guān)注

    關(guān)注

    34

    文章

    1627

    瀏覽量

    55675
  • Ubuntu
    +關(guān)注

    關(guān)注

    5

    文章

    566

    瀏覽量

    29966
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    STM32F407 串口配置步驟

    介紹STM32F407串口配置步驟,完成串口的數(shù)據(jù)發(fā)送與接收、實(shí)現(xiàn)中斷接收,支持printf重定向。
    的頭像 發(fā)表于 07-06 14:29 ?3356次閱讀
    <b class='flag-5'>STM32F407</b> <b class='flag-5'>串口</b>配置步驟

    為什么hx711模塊在stm32F103C8T6能讀取拉力傳感器數(shù)據(jù),在stm32F407IGHX使用時(shí)數(shù)據(jù)紊亂?

    hx711接拉力傳感器接stm32F103C8T6,該函數(shù)能正常運(yùn)行,讀取數(shù)據(jù),但是用stm32F407IGHX時(shí),val的值一直在不規(guī)則跳變,而且按壓拉力傳感器也沒(méi)有改變,接線和配置引腳沒(méi)有問(wèn)題
    發(fā)表于 11-03 22:23

    怎樣利用Ubuntu20.04去安裝Mentor Calibre 2020?

    怎樣利用Ubuntu20.04去安裝Mentor Calibre 2020?有沒(méi)有人遇到過(guò)這個(gè)問(wèn)題啊
    發(fā)表于 06-23 07:19

    請(qǐng)問(wèn)在Ubuntu20.04下如何燒錄CH32F103C8T6?

    請(qǐng)教, 在Ubuntu20.04下如何燒錄CH32F103C8T6?STM32F1/STM32F4可以通過(guò)stlink下載, CH32F10
    發(fā)表于 05-20 07:43

    stm32f407串口通信的代碼

    stm32f407串口通信的代碼 原理圖還有封裝 很清楚自己畫(huà)的
    發(fā)表于 03-21 17:22 ?0次下載

    STM32F407串口采用DMA收發(fā)數(shù)據(jù)

    STM32F407串口采用DMA收發(fā)數(shù)據(jù)調(diào)試可用!
    發(fā)表于 06-17 16:00 ?60次下載

    STM32F407串口UART 基礎(chǔ)配置STM32CubeMX

    STM32F407串口UART 基礎(chǔ)配置STM32CubeMX
    發(fā)表于 11-29 16:06 ?56次下載
    <b class='flag-5'>STM32F407</b>的<b class='flag-5'>串口</b>UART 基礎(chǔ)配置<b class='flag-5'>STM32</b>CubeMX

    Ubuntu20.04系統(tǒng)中使用用STM32F2107RCT6點(diǎn)亮一個(gè)二極管燈

    Ubuntu20.04系統(tǒng)中使用用STM32F2107RCT6點(diǎn)亮一個(gè)二極管燈
    發(fā)表于 12-05 14:51 ?8次下載
    <b class='flag-5'>Ubuntu20.04</b>系統(tǒng)中使用用<b class='flag-5'>STM32F</b>2107RCT6點(diǎn)亮一個(gè)二極管燈

    STM32F407-雙串口實(shí)驗(yàn)

    STM32F407-雙串口實(shí)驗(yàn),程序?qū)?b class='flag-5'>串口1和串口2全部調(diào)通,可同時(shí)使用
    發(fā)表于 06-13 15:06 ?29次下載

    如何制作ubuntu20.04的文件系統(tǒng)

    firefly自帶的文件系統(tǒng),由于缺少一些基本功能模塊,因此,我們可以自己手動(dòng)制作一個(gè)ubuntu20.04的文件系統(tǒng)。
    的頭像 發(fā)表于 10-17 12:12 ?3837次閱讀

    【ROC-RK3568-PC開(kāi)發(fā)板試用體驗(yàn)】燒錄Ubuntu20.04系統(tǒng)

    ://www.t-firefly.com/doc/download/107.html下 固件-Ubuntu 網(wǎng)盤(pán)下下載 Ubuntu/Ubuntu20.04/ROC-RK3568-PC-UBU
    的頭像 發(fā)表于 10-19 10:08 ?5909次閱讀
    【ROC-RK3568-PC開(kāi)發(fā)板試用體驗(yàn)】燒錄<b class='flag-5'>Ubuntu20.04</b>系統(tǒng)

    ubuntu20.04安裝教程

    Ubuntu 20.04 的安裝步驟如下: 制作啟動(dòng)U盤(pán)。首先下載Ubuntu 20.04的鏡像文件和UltraISO(鏡像制作工具)。然后使用UltraISO打開(kāi)下載的鏡像文件,插入
    的頭像 發(fā)表于 11-13 16:59 ?2327次閱讀

    Ubuntu 20.04如何更改用戶名

    產(chǎn)品簡(jiǎn)介本文適用于所有RK3568/RK3588平臺(tái)產(chǎn)品在Ubuntu20.04系統(tǒng)上如何更改用戶名,本文以IDO-EVB3588開(kāi)發(fā)板為例,在ubuntu20.04系統(tǒng)上修改用戶名industio
    的頭像 發(fā)表于 01-26 08:34 ?909次閱讀
    <b class='flag-5'>Ubuntu</b> <b class='flag-5'>20.04</b>如何更改用戶名

    【北京迅為】iTOP-LS2K0500開(kāi)發(fā)板快速使用編譯環(huán)境ubuntu20.04第一章加載迅為提供 Ubuntu20.04

    【北京迅為】iTOP-LS2K0500開(kāi)發(fā)板快速使用編譯環(huán)境ubuntu20.04第一章加載迅為提供 Ubuntu20.04
    的頭像 發(fā)表于 09-18 16:43 ?537次閱讀
    【北京迅為】iTOP-LS2K0500開(kāi)發(fā)板快速使用編譯環(huán)境<b class='flag-5'>ubuntu20.04</b>第一章加載迅為提供 <b class='flag-5'>Ubuntu20.04</b>

    Ubuntu20.04取消root賬號(hào)自動(dòng)登錄的方法,觸覺(jué)智能RK3568開(kāi)發(fā)板演示

    Ubuntu20.04默認(rèn)情況下為root賬號(hào)自動(dòng)登錄,本文介紹如何取消root賬號(hào)自動(dòng)登錄,改為通過(guò)輸入賬號(hào)密碼登錄,使用觸覺(jué)智能EVB3568鴻蒙開(kāi)發(fā)板演示
    的頭像 發(fā)表于 01-17 15:42 ?283次閱讀
    <b class='flag-5'>Ubuntu20.04</b>取消root賬號(hào)自動(dòng)登錄的方法,觸覺(jué)智能RK3568開(kāi)發(fā)板演示