色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

STM32F407IGHX與Ubuntu20.04虛擬串口通信

墨髯啊 ? 來源:墨髯啊 ? 作者:墨髯啊 ? 2023-02-06 09:34 ? 次閱讀

為了讓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).          */
  /*******************************************************************************/
    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 */

/**
  * @}
  */

/**
  * @}
  */

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

3、自定義結構體

在這里我不會給出具體的代碼,但我會舉個例子來說明如何定義所需結構體。

typedef struct ControlData_Chassis _Controldata_Chassis;//這里是定義該結構體的別名
typedef struct ControlData_Chassis{
    uint8_t Y_Speed; //縱軸方向速度
    uint8_t X_Speed; //橫軸方向速度
    uint8_t Rotational_Speed; //小車旋轉速度
    uint8_t Chassis_State; //底盤狀態
}*_Controldata_ChassisInfo;//這里定義了該結構體的結構體指針。C語言允許這樣的操作!

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

此外,可以把結構體定義在頭文件中,便于在.c文件里函數的具體實現。

4、自定義解包/打包函數

這里我也只會給出一個例子。

void Pack_Data(_FeedBack* feedback,uint8_t* feedArray)
{    //把數組中信息封入數據包中
    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;//暫時無意義
    feedArray[7] = 0XFE;//芝士幀尾
}

實際上,解包函數也是類似上文的操作,只不過是反了過來。

注:1.可以利用與 “ | ” 來將兩個數據拼成一個,將拆分的數據合成一個。

2.幀頭和幀尾起到了驗證的作用,可以用來驗證數據完整性。

5、自定義發送/接收函數

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

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

6、備注

1)如果你要定義一個結構體指針并想給它賦值,那么你需要在賦值前給它分配空間,否則這個指針無法進行賦值。

例子:

_FeedBack* ft,fd;

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

三、Ubuntu端具體實現過程

思路:利用ROS的serial包來實現串口通信。

1、創建工程

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

2、創建主程序

我這里使用的是Visual Studio Code來編寫代碼。

可以先在終端切換到你所需要編寫代碼的文件夾,然后輸入 code . (注意后面那個點也是要輸入的,然后VS就會啟動并打開這個文件夾)。

poYBAGPgWQqAF9K5AABG8N0_WpQ144.png

接著就可以在VS里創建新.cpp文件。

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

2、創建好.cpp文件,記得要到CMakeList.txt里添加上該頭文件(其實只要去掉這三個語句前的#號,并修改部分內容即可,其他部分不用動)。

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}

)

可以參考下方貼出的代碼來修改你的配置。

{
    "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
  }

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

#include "serial/serial.h"http://調用串口相關頭文件
#include "ros/ros.h"http://在ros下使用serial包進行通訊
#include "iostream"
//全局變量定義區
    serial::Serial sp;//創建一個Serial類
    serial::Timeout to = serial::Timeout::simpleTimeout(5000);//創建timeout//全局變量定義區


int main(int argc,char** argv){
    setlocale(LC_CTYPE,"zh_CN.utf8");//設置中文輸出
    ros::init(argc,argv,"serial_port");
    ros::NodeHandle n;//創建句柄
    // serial::Serial sp;//創建一個Serial類
    // serial::Timeout to = serial::Timeout::simpleTimeout(5000);//創建timeout
    sp.setPort("/dev/ttyACM0");//設置要打開的串口名稱
    sp.setBaudrate(115200);//設置串口通信的波特率
    sp.setTimeout(to);//串口設置timeout
    try
    {
        sp.open();//嘗試啟動串口
    }
    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!");//判斷是否成功開啟串口
    }
    else
    {
        return -1;
    }
    ros::Rate loop_rate(500);
    while(ros::ok())
    {
        Data_Receive();//此處為自定義函數,不要復制,我沒給出具體實現過程
        Data_Transmit();//此處為自定義函數,不要復制,我沒給出具體實現過程
 loop_rate.sleep(); 
}
 sp.close();
 return 0;
 }

3、備注

1)創建結構體,枚舉,打包/解包函數,發送/接收函數和STM32端幾乎一樣,所以可以按照STM32端的思路來操作。但是要注意,上位機的代碼應該是和下位機相對應的,下位機接收到的數據是來自上位機的,所以幀頭幀尾以及結構體成員應該保持一致。避免發送出錯。

2)如果你想要在ROS工程里自定義一個頭文件和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

)

否則會報錯,找不到該頭文件。修改方式參考上圖粗體部分。

四、可能存在的報錯

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

我的解決辦法:

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

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

2、Ubuntu無法打開串口

1)連接有問題或者根本沒有連接

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

3)STM32CubeIDE報錯GDB服務端無法打開。

我在博客里已經給出了詳盡的解釋

關于STM32CubeIDE無法正常啟動GDB服務端的解決辦法 - 墨髯 - 博客園 (cnblogs.com)

五、備注

1、實際上,很多的配置都需要看自己的需求來搞,我之前就盲目抄了其他人的時鐘樹配置,導致設備無法被電腦識別。所以如果出現問題,最好先去翻翻官方文檔。很多問題都可以通過官方文檔來解決。

2、整片文章里,我幾乎沒有提到過函數報錯的問題,主要是我暫時沒有考慮關于報錯的問題,所以代碼中很少會有關于報錯的內容。這個問題,可以等以后完善此通訊協議時解決。

審核編輯:湯梓紅

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 通信協議
    +關注

    關注

    28

    文章

    892

    瀏覽量

    40332
  • Linux
    +關注

    關注

    87

    文章

    11314

    瀏覽量

    209799
  • STM32
    +關注

    關注

    2270

    文章

    10906

    瀏覽量

    356503
  • 串口通信
    +關注

    關注

    34

    文章

    1626

    瀏覽量

    55566
  • Ubuntu
    +關注

    關注

    5

    文章

    563

    瀏覽量

    29857
收藏 人收藏

    評論

    相關推薦

    STM32F407 串口配置步驟

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

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

    hx711接拉力傳感器接stm32F103C8T6,該函數能正常運行,讀取數據,但是用stm32F407IGHX時,val的值一直在不規則跳變,而且按壓拉力傳感器也沒有改變,接線和配置引腳沒有問題
    發表于 11-03 22:23

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

    怎樣利用Ubuntu20.04去安裝Mentor Calibre 2020?有沒有人遇到過這個問題啊
    發表于 06-23 07:19

    請問在Ubuntu20.04下如何燒錄CH32F103C8T6?

    請教, 在Ubuntu20.04下如何燒錄CH32F103C8T6?STM32F1/STM32F4可以通過stlink下載, CH32F10
    發表于 05-20 07:43

    RK3588S-PC的ubuntu20.04系統上運行ros報錯

    用官方的ubuntu20.04安裝ros 運行示例時出現如下問題,請問我該怎么解決
    發表于 12-30 14:35

    stm32f407串口通信的代碼

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

    STM32F407串口采用DMA收發數據

    STM32F407串口采用DMA收發數據調試可用!
    發表于 06-17 16:00 ?60次下載

    STM32F407串口UART 基礎配置STM32CubeMX

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

    Ubuntu20.04系統中使用用STM32F2107RCT6點亮一個二極管燈

    Ubuntu20.04系統中使用用STM32F2107RCT6點亮一個二極管燈
    發表于 12-05 14:51 ?8次下載
    <b class='flag-5'>Ubuntu20.04</b>系統中使用用<b class='flag-5'>STM32F</b>2107RCT6點亮一個二極管燈

    STM32F407-雙串口實驗

    STM32F407-雙串口實驗,程序將串口1和串口2全部調通,可同時使用
    發表于 06-13 15:06 ?29次下載

    如何制作ubuntu20.04的文件系統

    firefly自帶的文件系統,由于缺少一些基本功能模塊,因此,我們可以自己手動制作一個ubuntu20.04的文件系統。
    的頭像 發表于 10-17 12:12 ?3804次閱讀

    【ROC-RK3568-PC開發板試用體驗】燒錄Ubuntu20.04系統

    ://www.t-firefly.com/doc/download/107.html下 固件-Ubuntu 網盤下下載 Ubuntu/Ubuntu20.04/ROC-RK3568-PC-UBU
    的頭像 發表于 10-19 10:08 ?5832次閱讀
    【ROC-RK3568-PC開發板試用體驗】燒錄<b class='flag-5'>Ubuntu20.04</b>系統

    ubuntu20.04安裝教程

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

    Ubuntu 20.04如何更改用戶名

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

    【北京迅為】iTOP-LS2K0500開發板快速使用編譯環境ubuntu20.04第一章加載迅為提供 Ubuntu20.04

    【北京迅為】iTOP-LS2K0500開發板快速使用編譯環境ubuntu20.04第一章加載迅為提供 Ubuntu20.04
    的頭像 發表于 09-18 16:43 ?496次閱讀
    【北京迅為】iTOP-LS2K0500開發板快速使用編譯環境<b class='flag-5'>ubuntu20.04</b>第一章加載迅為提供 <b class='flag-5'>Ubuntu20.04</b>
    主站蜘蛛池模板: 久久性综合亚洲精品电影网| 一级做a爰片久久毛片一| 泰国淫乐园实录| 在线伦理电影网| 国产午夜AV无码无片久久96| 青青草原伊人| 中文字幕一区二区三区在线观看| 国产欧美一区二区三区在线看 | 九九久久久| 午夜影院一区二区三区| 国产成人无码精品久久久影院| 欧美日韩高清一区二区三区| 99精品成人无码A片观看金桔| 久久精品国产亚洲AV影院| 一道本av免费不卡播放| 久久99精品国产99久久6男男| 91伊人久久大香线蕉| 男女夜晚在爽视频免费观看| 在线播放午夜理论片| 日本丝袜护士| 国产精品国产三级国产AV麻豆| 双性大乳浪受噗呲噗呲h总| 国产爱豆果冻传媒在线观看| 一道精品视频一区二区三区| 强开少妇嫩苞又嫩又紧九色| 黑丝袜论坛| 在线观看国产区| 十八禁啪啦啪漫画| 捆绑调教网站| xart欧美一区在线播放| 色悠久久久久综合欧美99| 国产成人在线视频网站| 中文亚洲大香伊蕉不卡一区| 女人张腿让男人桶免费| 超碰最新网站| 午夜爱情动作片P| 精品欧美一区二区三区四区 | 攵女yin乱合集高h| 无限资源在线观看播放| 摸老师丝袜小内内摸出水| 國產麻豆AVMDXMDX|