【esp32s3】7 - VSCode + PlatformIO + Arduino + 構建項目


一、PlatformIO

1.1. 概述

官方文檔:What is PlatformIO?

PlatformIO 是一個跨平臺的物聯網開發生態系統,專門為嵌入式系統開發設計,支持多種開發板和框架。

1.1.1. 主要特點

  • 跨平臺:支持 Windows、macOS 和 Linux
  • 多框架支持:支持 Arduino、ESP-IDF、mbed、FreeRTOS 等
  • 多硬件支持:支持 1000+ 開發板和 40+ 開發平臺,包含ESP,STM32等
  • 專業工具鏈:集成了編譯器、調試器、串口監視器等專業工具
  • 主要組成部分
    1. PlatformIO Core (CLI)
      • 核心引擎,基于 Python 開發
      • 提供命令行界面
      • 管理平臺、工具鏈和庫
      • 可通過 pio 命令使用
    2. PlatformIO IDE
      • 基于 VSCode 的集成開發環境擴展
      • 提供圖形化界面
      • 內置終端、串口監視器、調試器等工具
      • 項目配置通過 platformio.ini 文件管理
    3. PlatformIO Home
      • 基于 Web 的儀表板
      • 用于管理開發板、平臺和庫
      • 提供項目模板和示例代碼
      • 可通過 pio home 命令啟動

1.1.2. 插件介紹

入門第一課就是被網絡問題難到…介紹插件主要包含哪些內容,在什么時候會用到然后下載,
可以自行選擇魔法上網,或是找別人已經下載好的文件丟進去。

  • 下載vscode和插件后,就會在C:\Users\用戶名\錄下創建文件夾.platformio
  • 下面是文件夾內容的介紹,不同內容會在執行不同指令時主動在線下載
.platformio
├── .cache        			# 臨時緩存 (可清理)
│   ├── http 				# 下載的壓縮包緩存(平臺、工具鏈、庫等)
│   ├── content 			# 解壓后的臨時內容
│   ├── pio-packages 		# 包管理器緩存
│   ├── tmp 				# 臨時構建文件
│   └── ...
├── packages      			# 工具鏈/框架/庫二進制 (核心)
│   ├── contrib-piohome		# 插件的 web 界面
│   ├── toolchain-* 		# 各種架構的編譯工具鏈(如 xtensa-esp32-elf)
│   ├── framework-* 		# 各種框架(如 arduino, esp-idf)
│   ├── tool-* 				# 開發工具(如 openocd, cmake)
│   ├── library-* 			# 下載的第三方庫
│   └── ...
├── penv          			# Python虛擬環境
├── platforms     			# 平臺定義文件
│   ├── espressif32
│   └── ...
└── python3       			# 嵌入式Python解釋器
  • .platformio/python3.platformio/penv 會在安裝插件后自動下載,除非在首選項中關閉設置。關閉后就不使用內置Python解釋器,使用自行安裝的路徑

在這里插入圖片描述

  • .platformio/packages/contrib-piohome 會在打開 pio home 時下載,也就相當于是一開始下載了。如果沒有就會打不開home界面,一直顯示Loading...

在這里插入圖片描述

  • .platformio/packages/framework-* 會在創建工程或是手動下載芯片包時下載。本體很小,只有幾MB。
  • 剩余的其他內容就是大頭了,包含編譯鏈和調試工具等,還有依賴庫。
  • 全部下載完可能有幾個G,如果你的工程涉及到東西很多,它會下載一堆,像是esp-idf-541這種,雖然我自己安裝了,但不認,必須使用內置下載。所以會出現新建一個工程等一天,編譯一個工程又等一天,調試一個工程又等一天的夸張情況。
  • 更加離譜的時候,雖然顯示超時失敗了,實際上python還在下載中,刪除文件夾會提示被占用,要到任務管理器里結束進程才可以。

在這里插入圖片描述


1.2. 在線安裝

網上有很多教程,離線或在線:

  • 離線就是把別人下載的.platformio文件直接拷貝過來,如果是你的同學或是同事,你們要搭建的環境一致,而且ta的前幾天內搭建好的,這樣拷貝過來直接用好像問題不大。
  • 否者考慮到離線的時效性與局限性,還是使用在線下載的方式比較好,在線下載又分還代理源或是直接梯子全局代理

離線安裝推薦教程:Arduino IDE太難用?5分鐘"離線"安裝PlatformIO,無需等待,編程體驗原地起飛
在線安裝推薦教程:Arduino不好用?極速安裝Platformio,盡享vscode絲滑


1.2.1. 全局代理

  • 手機下載梯子Every Proxy,然后手機和電腦處于同一局域網(路由器)下即可。一般家里或辦公室應該都是連接同一個路由器的網線或wifi。下載的東西多達幾G,所以謹慎用流量。
  • 一般梯子就一個啟動和關閉鍵,很簡單,出于安全考慮,我這里就不分享可用的梯子。Every Proxy也很簡單,右上角設置菜單里選擇局域網IP地址,一般192.168.x.xxx,然后主界面打開HTTP/HTTPS即可。

在這里插入圖片描述

  • 電腦端的Window設置如下,輸入Every Proxy里顯示的IP:端口地址即可。不要點擊下方的請勿將代理服務器用于本地(Intranet)地址
  • 設置完后打開瀏覽器,輸入個谷歌地址,如果能順利打開,就代表成功了。

在這里插入圖片描述

  • VSCode 里也要用戶設置里查找Http Proxy,找到下圖兩個輸入框,寫入http://IP:端口地址,然后重啟VSCode,保險起見可以再重啟電腦。

在這里插入圖片描述

  • 至此準備工作已經完成,期間請確保梯子和網絡的穩定,避免失敗。

1.2.2. 安裝插件

  • 下載VSCode,然后應用商店里搜索 PlatformIO 下載安裝。確保C:\Users\用戶名\.platformio文件夾里沒之前安裝遺留的東西,有的話就刪掉。
  • 插件下載應用后,會開始下載python,然后再下載PlatformIO Core,下載完后左邊就能看到PLATFORMIO菜單欄。
  • 然后會彈出PIO Home界面顯示Loading...,代表在下載PlatformIO Home,下載完成后就能看到主頁了。
  • 注意!!!直到彈出主頁前,不記得進行其他操作,耐心等待它自動下載完成。無聊的話可以自行打開.platformio看看里面文件夾的變動,一直刷新文件夾能看到文件大小一直變動,代表自動下載進行中。

在這里插入圖片描述

  • 主頁上方欄中有一個放大圖標,是在瀏覽器打開PlatformIO Home頁面的意思的。界面是一樣的,聽說瀏覽器頁面打開下載會快一點。我感覺差不多

在這里插入圖片描述

  • 接下來開始安裝芯片包,根據下圖指引,在安裝頁面搜索esp,然后點擊進入。

在這里插入圖片描述

  • 進入頁面后選擇版本下載,我目前最新是6.11.0。點擊下載后可以看到.platformio/.cache大小一直變大,耐心的等待下載完成。

在這里插入圖片描述

  • 下載完成后會有彈窗提示,也可以看到文件夾.platformio/packages內多了toolchain-xtensa-esp32tool-esptoolpy工具鏈,還有文件夾.platformio\platforms\espressif32

在這里插入圖片描述

  • 如果你安裝到一半退出,可能也會看得到安裝完成的假象,是因為你只安裝了.platformio\platforms\espressif32文件夾,這個文件夾才4MB左右,倉庫在github上,可以直接獲取。真正的大頭是.platformio/packages內的工具。
  • 不過問題不大,即使這里沒安裝,之后新建/編譯/下載工程時是必定需要安裝的,否者會直接失敗中斷。

在這里插入圖片描述


1.2.3. 新建工程

  • 插件工程需要指定開發板類型board,一般只想建給空例程,也要指定開發板,沒辦法,去官網找找最小系統開發板的型號。

官網地址:開發板概覽|樂鑫科技

  • 下面兩款都算的最小核心板了,如果你用的是其他開發板,你可以自行搜索。如果沒有找到一模一樣,就找類似的,flashPSRAM,和ESP32型號相同即可。

在這里插入圖片描述
在這里插入圖片描述

  • 然后再插件的芯片包里搜索看看,是否有符合開發板類型。

在這里插入圖片描述

  • 然后開始新建工程,在主頁點擊New Project,彈窗如下,自定義選擇工程路徑。

在這里插入圖片描述

  • 點擊確認后就能看到等待加載,瀏覽本地路徑,能看到工程大體已經有了。

在這里插入圖片描述

  • 但彈窗還沒顯示結束,因為還有很多其他工具鏈需要下載,可以看到.platformio/.cache大小一直變大,耐心的等待下載完成。

在這里插入圖片描述

  • 1個G還在下載…

在這里插入圖片描述

  • 最后終于彈窗成功,下載完成了。瀏覽.platformio/packages文件夾里又多幾個其他工具。

在這里插入圖片描述

  • 然后大體工程結構如下,后面章節具體介紹。
  • 在代碼里添加一些打印內容。然后編譯下載。

在這里插入圖片描述

  • 編譯下載時又會檢查是否缺少工具鏈,如果缺少的話會再下載。所以就算你前面中途停止問題也不大,最后肯定還是要下載的。
PACKAGES:- framework-arduinoespressif32 @ 3.20017.241212+sha.dcc1105b- tool-esptoolpy @ 1.40501.0 (4.5.1)- tool-openocd-esp32 @ 2.1100.20220706 (11.0)- toolchain-riscv32-esp @ 8.4.0+2021r2-patch5- toolchain-xtensa-esp32s3 @ 8.4.0+2021r2-patch5

在這里插入圖片描述

PACKAGES:- framework-arduinoespressif32 @ 3.20017.241212+sha.dcc1105b- tool-esptoolpy @ 1.40501.0 (4.5.1)- tool-mkfatfs @ 2.0.1- tool-mklittlefs @ 1.203.210628 (2.3)- tool-mkspiffs @ 2.230.0 (2.30)- tool-openocd-esp32 @ 2.1100.20220706 (11.0)- toolchain-riscv32-esp @ 8.4.0+2021r2-patch5- toolchain-xtensa-esp32s3 @ 8.4.0+2021r2-patch5

在這里插入圖片描述

  • 可以看到文件夾里又多了一些東西。。。

在這里插入圖片描述

  • 如果你下載失敗,可能是因為你選擇的開發板類型對不上,硬件配置不對。
  • 比如我選了8MB的flash的開發板,實際上我用的開發板是只有4MB,那它就報錯了。

在這里插入圖片描述


1.3. platformio.ini 項目配置

PlatformIO項目配置文件: PlatformIO Project Configuration File
推薦筆記:platformIO 自定義板子方法


1.3.1. [env:xxx] 獨立環境配置

  • 定義一個或多個環境配置,可以通過PIO界面手動切換選擇。
; 定義 env 環境
[env:env_0]
platform = espressif32                          ; 指定平臺版本
board = esp32-s3-devkitc-1                      ; 明確選擇開發板 會影響:默認引腳映射,閃存配置,調試接口設置
framework = arduino                             ; 使用 Arduino 兼容層 進行開發; 定義 env 環境
[env:env_1]
platform = espressif32                          ; 指定平臺版本
board = esp32-s3-devkitm-1                      ; 明確選擇開發板 會影響:默認引腳映射,閃存配置,調試接口設置
framework = arduino                             ; 使用 Arduino 兼容層 進行開發

在這里插入圖片描述


1.3.2. [platformio] 全局環境配置

  • 可以定義 [platformio] ,在里面設置默認env環境。
  • 但是,如果手動選擇還是以手動選擇為準。因為手動選擇是直接加在編譯命令 pio run 中的
; 全局配置
[platformio]
default_envs = env_0                            ; 指定 env 環境
description = sad_him_description               ; 描述項目,顯示在 PIO HOME 的項目介紹里; 定義 env 環境
[env:env_0]
platform = espressif32                          ; 指定平臺版本
board = esp32-s3-devkitc-1                      ; 明確選擇開發板 會影響:默認引腳映射,閃存配置,調試接口設置
framework = arduino                             ; 使用 Arduino 兼容層 進行開發; 定義 env 環境
[env:env_1]
platform = espressif32                          ; 指定平臺版本
board = esp32-s3-devkitm-1                      ; 明確選擇開發板 會影響:默認引腳映射,閃存配置,調試接口設置
framework = arduino                             ; 使用 Arduino 兼容層 進行開發
  • 其中 description 是一個文本提示,沒啥實際作用,效果如下:

在這里插入圖片描述


1.3.3. [env] 自動繼承配置

官方例子:Common [env]

  • 如果所有 env 中有相同配置,可以單獨列舉,會自動集成到所有子配置。下面例子和上面結果相同。
  • 如果有重復配置會根據優先級覆蓋,[env:xxxx]里的內容優先級最高。
; 全局配置
[platformio]
default_envs = env_0                            ; 指定 env 環境
description = sad_him_description               ; 描述項目,顯示在 PIO HOME 的項目介紹里[env]
platform = espressif32                          ; 指定平臺版本
framework = arduino                             ; 使用 Arduino 兼容層 進行開發; 定義 env 環境
[env:env_0]
board = esp32-s3-devkitc-1                      ; 明確選擇開發板 會影響:默認引腳映射,閃存配置,調試接口設置; 定義 env 環境
[env:env_1]
board = esp32-s3-devkitm-1                      ; 明確選擇開發板 會影響:默認引腳映射,閃存配置,調試接口設置

1.3.4. [common] 手動繼承配置 extends 和 ${}

  • [common] 字段是約定俗成一個公共配置的字段。實際上,根據需要可以定義其他更多容易字符的字段。
  • 然后可以使用 extends 或是 ${common.lib_deps} 方式全部部分繼承配置。
; 全局配置
[platformio]
default_envs = env_0                            ; 指定 env 環境
description = sad_him_description               ; 描述項目,顯示在 PIO HOME 的項目介紹里[common]
lib_deps =                                      ; 添加一些庫Dep1                                        ; 偽代碼,假設是一個庫Dep2[env]
platform = espressif32                          ; 指定平臺版本
framework = arduino                             ; 使用 Arduino 兼容層 進行開發; 定義 env 環境
[env:env_0]
board = esp32-s3-devkitc-1                      ; 明確選擇開發板 會影響:默認引腳映射,閃存配置,調試接口設置
lib_deps =${common.lib_deps}                          ; 使用 common 中的庫Dep3                                        ; 偽代碼,假設是一個庫; 定義 env 環境
[env:env_1]
board = esp32-s3-devkitm-1                      ; 明確選擇開發板 會影響:默認引腳映射,閃存配置,調試接口設置
extends = common                                ; 繼承 common 中的配置

1.3.5. extra_configs 導入配置文件

  • 在一些多配置的項目中,會需要更多配置環境分配,全部都寫在platformio.ini里就不合適,會進行詳細的分類。嵌套導入多個文件。
; 全局配置
[platformio]
default_envs = env_0                            ; 指定 env 環境extra_configs =                                 ; 添加一些額外的配置文件,可以簡單類比頭文件,最最終導入到這里一起,使用配置可以互相指定繼承arch/*/*.ini                                ; 偽代碼,假設是架構相關的配置文件variants/*/platformio.ini                   ; 偽代碼,假設是變體相關的配置文件description = sad_him_description               ; 描述項目,顯示在 PIO HOME 的項目介紹里
  • arch 文件是存放不同芯片類型的,大致內容如下,因為通過extra_configs導入最終是匯總在platformio.ini,這樣就可以相互繼承了。
  • 這和頭文件的機制一樣,一個頭文件定義宏定義,最終導入在一個.c里,那它們就相當于是寫在一個.c中,可以相互嵌套。頭文件還需要順序問題,這給platformio.ini文件貌似沒有順序限制。

在這里插入圖片描述
在這里插入圖片描述

  • variants 文件里存放的就是獨立環境配置 env,最終也是一起導入platformio.ini文件,然后可以被default_envs = env_0指定默認環境。
  • 注意,這些文件夾的命名應該沒有限制,但大家應該有約定俗成的規范,所以盡量一致。

在這里插入圖片描述


1.3.6. 總結

  • 根據上面的學習,可以嘗試規劃一下項目結構,多加archvariants文件,然后填入測試內容。
  • 看懂這步有助于你看到別人的項目,下面只是個示例。

在這里插入圖片描述

  • 最后在獨立環境配置中設置自己的東西,因為優先級最高,所以重名也沒關系。
  • 前面一堆脫褲子放屁的操作,最后有用生效的是如下內容。因為所有內容都被重新定義了

在這里插入圖片描述

;  ==== 定義一個名為 env_0 的 PlatformIO 環境 ====
[env:env_0]
platform = espressif32                          ; 指定平臺版本
board = esp32-s3-devkitc-1                      ; 明確選擇開發板 會影響:默認引腳映射,閃存配置,調試接口設置
framework = arduino                             ; 使用 Arduino 兼容層 進行開發; ==== 調試配置 ====
debug_tool = esp-builtin                        ; 使用內置USB-JTAG; ==== 下載配置 ====
upload_protocol = esp-builtin                   ; 使用內置USB-JTAG; ==== 串口監視配置 ====
monitor_port = COM4                             ; 指定端口號
monitor_speed = 115200                          ; 指定波特率
monitor_filters = esp32_exception_decoder       ; 當 ESP32 運行時發生崩潰(如內存錯誤、斷言失敗、看門狗觸發等),會輸出 十六進制格式的異常調用棧; ==== 編譯配置 ====
build_type = debug                              ; 配置構建模式的關鍵參數 debug / release 模式
build_flags =                                   ; 向底層編譯器傳遞額外的 編譯選項 和 宏定義-Og                                         ; 啟用調試符號-ggdb3                                      ; 生成GDB調試信息-D ARDUINO_USB_MODE=1                       ; 啟用USB模式-D ARDUINO_USB_CDC_ON_BOOT=1                ; 啟動時自動初始化USB CDC-D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_INFO  ; 可選日志級別:; ARDUHAL_LOG_LEVEL_NONE; ARDUHAL_LOG_LEVEL_ERROR; ARDUHAL_LOG_LEVEL_WARN; ARDUHAL_LOG_LEVEL_INFO (默認); ARDUHAL_LOG_LEVEL_DEBUG; ARDUHAL_LOG_LEVEL_VERBOSE

1.4.board 開發板配置

推薦筆記: platformIO 自定義板子方法

官方說明:board

  • 類型:字符串(ID) | 多選:否
  • pio會查找本地工程目錄和庫目錄,找到同名的文件導入。
    • 本地工程目錄: boards
    • 本地庫目錄:.platformio\platforms\espressif32\boards
    • 使用命令查看: pio boards [OPTIONS] [FILTER]

1.4.1. 自定義開發板 boards.json

  • 可以從本地庫里挑選需要的開發板文件,然后拷貝到本地工程的boards
    在這里插入圖片描述

  • 自定義一個名字避免重名,效果如下:

在這里插入圖片描述

  • 然后編譯就能看到,終端打印的信息已經改變了

在這里插入圖片描述

  • 接下來細看一下開發板文件.json的內容,會發現好像格式和platformio.ini 文件的一模一樣啊?一個屬性,然后指定內容。所以開發板文件其實就是官方庫提供的快捷設置,所以才能四行配置環境就編譯運行。
[env:env_0]
platform = espressif32                          ; 指定平臺版本
board = sad_him                                 ; 明確選擇開發板 會影響:默認引腳映射,閃存配置,調試接口設置
framework = arduino                             ; 使用 Arduino 兼容層 進行開發

1.4.2. 下載與調試開發板

  • 其中的esp32s3.cfg是熟面孔,使用idf配置時也會用到,
  • 另外,我手頭上的開發板flash只有4MB,所以修改一下定義:分區表和flash大小,
    "arduino":{"ldscript": "esp32s3_out.ld","partitions": "bare_minimum_2MB.csv"},"upload": {"flash_size": "4MB","maximum_ram_size": 327680,"maximum_size": 4194304,"require_upload_port": true,"speed": 460800},

在這里插入圖片描述

  • 然后進去監聽一下,有循環打印東西:
  • 未知問題:不知道為啥我總是要按一次ctrl+c才能接收內容,貌似下載后沒有自動復位?有usb-to-串口下載,或使用opencd下載,按照之前idf的開發思路,我是想用ocd,但很不順利。

在這里插入圖片描述

  • 然后就可以試一下調試功能,默認自帶的三種調試配置,都是可用的,注意projectEnvName定義是否和配置一致。

在這里插入圖片描述

在這里插入圖片描述

  • 進入調試后會發現,默認斷點卡在了void app_main(),這就很熟悉了,
  • 開頭幾個宏定義是判斷是否打開串口,會發現ARDUINO_USB_CDC_ON_BOOT其實就是前面build_flags 配置的內容,所以其實就是定義了全局宏定義的感覺。因為這個文件是庫里的框架,如果在工程里面定義,它是讀取不到的,只能在編譯過程中定義。
  • 然后定義了一個任務線程loopTask,里面執行了setup();,然后for(;;)死循環執行了loop();里面還有一個看門狗復位的操作esp_task_wdt_reset();
  • 所以明顯,其實ARDUINO框架就是在idf框架上套了一層。

在這里插入圖片描述


1.4.3. 自定義分區表 partitions.csv

官方文檔:Partition Tables
在這里插入圖片描述

  • 前面我使用了庫里的分區表,和idf開發時一樣,可以更改為本地工程的,支持路徑索引,默認根路徑當然就是platformio.ini,因為所有配置其實都是導入它的目錄下嘛。
  • 可以修改開發板文件sad_him.json,也可以修改獨立環境配置platformio.ini
"arduino":{"ldscript": "esp32s3_out.ld","partitions": "partitions/partitions_test.csv"},
board_build.partitions = partitions/partitions_test.csv
  • 編譯后冒失看到啥效果,idf編譯終端會打印分區表內容的,這里只有一個警告,分區ffs_him沒有對齊字節0x1000

在這里插入圖片描述


1.4.4. 自定義引腳映射 pins_arduino.h

  • 在開發板定義文件中,有一段定義引腳映射的內容:
    "hwids": [["0x303A","0x1001"]],"mcu": "esp32s3","variant": "esp32s3"

你提供的 sad_him.json 文件片段是一個典型的 ESP32-S3 開發板的硬件標識配置,我來解析關鍵信息:

  1. HWIDs (硬件標識符):

    "hwids": [["0x303A", "0x1001"]]
    
    • 0x303A 是 USB 廠商 ID (Vendor ID),這是 Espressif 的官方標識
    • 0x1001 是產品 ID (Product ID),對應特定開發板型號
    • 這個組合用于 USB 驅動識別你的 ESP32-S3 開發板
  2. MCU 型號:

    "mcu": "esp32s3"
    
    • 明確指定微控制器為 ESP32-S3 系列
    • 影響編譯器選擇正確的工具鏈(如 xtensa-esp32s3-elf-
  3. 變體聲明:

    "variant": "esp32s3"
    
    • 通常對應開發板引腳定義文件(如 pins.csv)的目錄名
    • 在 Arduino-ESP32 中會指向 variants/esp32s3/pins_arduino.h 下的板級定義

在這里插入圖片描述

  • 可以將該文件拷貝到工程中,其實就是之前創建的variants文件夾,
  • 如果這給設置錯會提示找不到pins_arduino.h文件。

在這里插入圖片描述

  • 設置正確后報錯還是有,查了一下,需要在build_flags里添加頭文件搜索路徑,這個不是默認包含的頭文件路徑。。。這下就正常了
build_flags =                                   ; 向底層編譯器傳遞額外的 編譯選項 和 宏定義-I variants/env_0                           ; 指定額外的頭文件搜索路徑
  • 再來看看這個引腳映射的內容,是定義了默認的u0i2cspi的引腳,
  • arduino的庫函數需要這些引腳,因為默認是不配置引腳的,直接使用這里配置的引腳(迷惑,為什么要這樣)。

在這里插入圖片描述


1.4.5. 總結

  • 至此大概對工程架構有了一定認識,還有很多其他配置項沒有介紹,需要時再去官網手冊查找:

Options

在這里插入圖片描述

  • 原本使用menuconfig菜單配置的內容也被隱藏了起來,非常不直觀。一知半解的開始Arduino編程了~

二、Arduino

2.1. GPIO

逆天,Arduino 的庫里只有頭文件沒有源碼原型,我想看idf的庫函數,還得跑回idf工程里查看。

  • idf的例程內容.c.h完全拷貝,加上#include <Arduino.h>,就能直接用。
  • 然后Arduino本身有另外的封裝好的gpio初始化接口,也很簡單。
#define LED_PIN 2
#define BUTTON_PIN 4void setup() {pinMode(LED_PIN, OUTPUT);pinMode(BUTTON_PIN, INPUT_PULLUP);
}void loop() {if (digitalRead(BUTTON_PIN) == LOW) {  // 按鈕按下(接地)digitalWrite(LED_PIN, HIGH);} else {digitalWrite(LED_PIN, LOW);}
}
#include <Arduino.h>
#include "driver/gpio.h"#include <stdio.h>
#include "gpio_reg_test.h"#include "esp_log.h"
#include "driver/gpio.h" // 需要添加依賴 PRIV_REQUIRES driver
#include "driver/rtc_io.h"
#include "hal/gpio_hal.h" // 好像不需要額外添加依賴?
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"// 配置參數
#define BLINK_GPIO GPIO_NUM_45      // 使用GPIO4作為示例(可根據需要修改) 42/ 43 / 44 / 45 / 46 /
#define BLINK_GPIO_SEL (1)          // 查看gpio的功能映射表
#define BLINK_DELAY_MS (5*1000)     // 閃爍間隔(毫秒)static const char *TAG = "gpio_reg_test.c";static uint32_t * const TEST_GPIO_OUT_W1TS_REG = (uint32_t *)(0x60004000 + 0x0008); // GPIO0 ~ 31 輸出置位寄存器
static uint32_t * const TEST_GPIO_OUT_W1TC_REG = (uint32_t *)(0x60004000 + 0x000C); // GPIO0 ~ 31 輸出清零寄存器static uint32_t * const TEST_GPIO_OUT1_W1TS_REG = (uint32_t *)(0x60004000 + 0x0014); // GPIO32 ~ 48 輸出置位寄存器
static uint32_t * const TEST_GPIO_OUT1_W1TC_REG = (uint32_t *)(0x60004000 + 0x0018); // GPIO32 ~ 48 輸出清零寄存器// 測試 gpio 寄存器 函數
void gpio_reg_test_fun(void)
{// GPIO配置結構體gpio_config_t io_conf = {.pin_bit_mask = (1ULL << BLINK_GPIO),  // 選擇GPIO.mode = GPIO_MODE_OUTPUT,              // 輸出模式.pull_up_en = GPIO_PULLUP_DISABLE,     // 不上拉.pull_down_en = GPIO_PULLDOWN_DISABLE, // 不下拉.intr_type = GPIO_INTR_DISABLE         // 禁用中斷};// 初始化GPIOESP_ERROR_CHECK(gpio_config(&io_conf));extern esp_err_t gpio_func_sel(gpio_num_t gpio_num, uint32_t func); // 庫函數的頭文件沒有聲明這個函數// gpio_func_sel(BLINK_GPIO, BLINK_GPIO_SEL); // 修改GPIO功能// gpio_hal_iomux_func_sel(BLINK_GPIO, BLINK_GPIO_SEL); // 修改GPIO功能,不是這個,這個要入寄存器,而不是引腳號extern void deinit_uart0(void);deinit_uart0(); // 刪除驅動,內含釋放緩存和停止中斷// 主循環while (1){// 調用庫函數 設置高電平ESP_ERROR_CHECK(gpio_set_level(BLINK_GPIO, 1));ESP_LOGI(TAG, "GPIO%d set HIGH", BLINK_GPIO);vTaskDelay(pdMS_TO_TICKS(BLINK_DELAY_MS));// 調用庫函數 設置低電平ESP_ERROR_CHECK(gpio_set_level(BLINK_GPIO, 0));ESP_LOGI(TAG, "GPIO%d set LOW", BLINK_GPIO);vTaskDelay(pdMS_TO_TICKS(BLINK_DELAY_MS));uint32_t blink_gpio = BLINK_GPIO; // 重新定義變量,避免警告if (blink_gpio <= 31) {// 調用寄存器 設置高電平TEST_GPIO_OUT_W1TS_REG[0] |= (1 << blink_gpio);ESP_LOGI(TAG, "GPIO%d set HIGH", BLINK_GPIO);vTaskDelay(pdMS_TO_TICKS(BLINK_DELAY_MS));// 調用寄存器 設置低電平TEST_GPIO_OUT_W1TC_REG[0] |= (1 << blink_gpio);ESP_LOGI(TAG, "GPIO%d set LOW", BLINK_GPIO);vTaskDelay(pdMS_TO_TICKS(BLINK_DELAY_MS));} else {blink_gpio -= 32; // 偏移// 調用寄存器 設置高電平TEST_GPIO_OUT1_W1TS_REG[0] |= (1 << blink_gpio);ESP_LOGI(TAG, "GPIO%d set HIGH", BLINK_GPIO);vTaskDelay(pdMS_TO_TICKS(BLINK_DELAY_MS));// 調用寄存器 設置低電平TEST_GPIO_OUT1_W1TC_REG[0] |= (1 << blink_gpio);ESP_LOGI(TAG, "GPIO%d set LOW", BLINK_GPIO);vTaskDelay(pdMS_TO_TICKS(BLINK_DELAY_MS));}}
}#include "driver/uart.h"void deinit_uart0(void)
{// 1. 等待發送完成uart_wait_tx_done(UART_NUM_0, pdMS_TO_TICKS(100));// 2. 恢復 GPIO 引腳,內部調用 gpio_func_sel(io_num, PIN_FUNC_GPIO); 恢復gpio功能。uart_set_pin(UART_NUM_0,UART_PIN_NO_CHANGE,  // TXUART_PIN_NO_CHANGE,  // RXUART_PIN_NO_CHANGE,  // RTSUART_PIN_NO_CHANGE); // CTS// 3. 刪除驅動,內含釋放緩存和停止中斷uart_driver_delete(UART_NUM_0);
}

2.2. 總結

  • 我發現用 PlatformIO + Arduino ,貌似是為了它的庫和c++環境,對于esp-idfArduino的反而不太重要?
  • 而且Arduino本身底層還是esp-idf,所以直接把esp-idf的代碼拷貝過去就能用,c++c向下完美兼容。
  • 后續會著重學習開源庫的邏輯。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/93262.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/93262.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/93262.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

LE AUDIO CIS/BIS音頻傳輸時延的計算

LE AUDIO音頻總時延計算方法 按照BAP的規范,LE AUDIO音頻總延時包括三個部分:Audio Processing Time,Transport Latency,Presentation Delay。如下圖所示是播放音樂的示例圖: 這里還有一個麥克風錄音的總時延示例圖: Audio Processing Time:這個就是音頻DSP獲取音頻數…

git 修改 更新

git 修改 更新先更新&#xff0c;后修改# 暫存當前修改 git add . git stash# 獲取最新的 main 分支 git checkout main git pull# 新建開發分支 git checkout -b lbg_0727# ?? 先把 main 的最新代碼合并/變基到當前分支&#xff08;用于消除沖突&#xff09; # 方法1&#x…

飛鶴困局:增長神話的裂痕

增長天花板已然逼近&#xff0c;飛鶴需要探尋新方向。作者|安德魯編輯|文昌龍“飛鶴&#xff0c;更適合中國寶寶體質”——這句曾讓無數媽媽點頭的廣告語&#xff0c;幫飛鶴坐上了中國奶粉市場的頭把交椅。可多年后&#xff0c;時代紅利退潮&#xff0c;故事不好講了。飛鶴的利…

Java設計模式之<建造者模式>

目錄 1、建造者模式 2、建造者模式結構 3、實現 4、工廠模式對比 5、適用場景差異 前言 建造者模式是一種創建型設計模式。用于封裝復雜對象的構建過程&#xff0c;通過步驟構建產品類。它包括產品類、抽象建造者、具體建造者和指揮者角色。 優點在于靈活性、解耦和易擴展…

fchown/fchownat系統調用及示例

55. fchmod - 通過文件描述符改變文件權限 函數介紹 fchmod是一個Linux系統調用&#xff0c;用于通過文件描述符來改變文件的訪問權限。它是chmod函數的文件描述符版本&#xff0c;避免了路徑名解析。 函數原型 #include <sys/stat.h> #include <unistd.h>int fchm…

20250726-5-Kubernetes 網絡-Service 代理模式詳解(iptables與ipvs)_筆記

一、服務三種常用類型 ?? 1. LoadBalancer類型 工作原理:與NodePort類似,在每個節點上啟用端口暴露服務,同時Kubernetes會請求底層云平臺(如阿里云、騰訊云、AWS等)的負載均衡器,將每個Node([NodeIP]:[NodePort])作為后端添加。 自動化實現:云廠商通過官方實現的控制…

horizon置備出錯

報錯內容如下&#xff1a; [2025/7/28 19:15] 置備 Customization failure: Customization of the guest operating system is not supported due to the given reason: 期間出錯 解決方法&#xff1a;將模板轉換為虛擬機&#xff0c;安裝vmtools&#xff1b;再安裝vmtools之后…

【unitrix】 6.19 Ord特質(ord.rs)

一、源碼 這段代碼定義了一個標記特征&#xff08;marker trait&#xff09;Ord 和三個實現&#xff0c;用于將類型標記與 Rust 標準庫中的 Ordering 枚舉關聯起來。 use crate::sealed::Sealed; use core::cmp::Ordering; use crate::number::{Greater, Equal, Less}; /// 用于…

數據結構之順序表鏈表棧

順序表 什么是 list list 的使用 線性表是什么 順序表是什么 順序表和線性表的關系 順序表和數組的區別 List 和 ArrayList 的關系 如何自己模擬實現 myArrayList ArrayList 的構造 ArrayList 的常見方法 以下兩種寫法有什么區別 ArrayList<Integer> arrayLis…

day062-監控告警方式與Grafana優雅展示

文章目錄0. 老男孩思想-馬太效應1. API監控2. zabbix的API接口2.1 生成zabbix的api token2.2 訪問格式2.3 前端添加web監測3. 監控告警方式3.1 云監控-郵件告警3.1.1 郵箱開啟授權碼3.1.2 zabbix前端配置3.1.3 消息模板3.1.4 配置郵箱收件人信息3.1.5 配置觸發器3.2 企業微信告…

Ettus USRP X410/X440 運行 ADC 自校準

Ettus USRP X410/X440 運行 ADC 自校準 打開一個接收&#xff08;Rx&#xff09;會話到您在設備名稱輸入中指定的設備并返回會話句柄 out&#xff0c;您可以使用該句柄在所有后續 NI-USRP VI 中識別此儀器會話。 支持設備&#xff1a;Ettus USRP X410/X440輸入/輸出 文明.png 會…

Qt元類型系統(QMetaType)詳解

Qt元類型系統詳解一、Qt元類型系統(QMetaType)詳解1. 核心功能2. 注冊機制3. 關鍵技術點4. 信號槽支持5. 流式傳輸支持6. 使用場景7. 注意事項二、完整示例1、基本實例2、基本實例3、元類型在信號槽中的應用4、高級用法三、元對象編譯器moc元對象編譯器&#xff08;Moc&#xf…

《C++繼承詳解:從入門到理解公有、私有與保護繼承》

《C繼承詳解&#xff1a;從入門到理解公有、私有與保護繼承》 文章目錄《C繼承詳解&#xff1a;從入門到理解公有、私有與保護繼承》一、繼承的概念及定義1.1 繼承的概念1.2 繼承定義1.2.1 定義格式1.2.2 繼承基類成員訪問方式的變化1.3 繼承類模版二、基類和派生類間的轉換三、…

佳能iR-ADV C5560復印機如何掃描文件到電腦

打印機與電腦連接首先&#xff0c;確保佳能iR-ADV C5560復印機通過USB或Wi-Fi等網絡連接的方式成功連接到電腦。這可以通過USB線纜或Wi-Fi等網絡來實現。連接完成后&#xff0c;便可利用打印機內置的掃描功能&#xff0c;輕松將文件掃描并傳輸至電腦中。【掃描操作步驟】接下來…

騰訊AI IDE

1.官網說明&#xff1a;打開騰訊AI IDE官網。2.安裝說明&#xff1a;安裝成功后的界面。3.登錄 說明&#xff1a;通過郵箱和密碼登錄。4.成功說明&#xff1a;成功登錄如下界面。5.簡單一問說明&#xff1a;理解能力感覺不錯。擁有Claude-3.7-Sonnet??&#xff0c;??Claude…

【LeetCode 熱題 100】(一)哈希

1. 兩數之和 class Solution {public int[] twoSum(int[] nums, int target) {int length nums.length;// 1.聲明一個hashmap {nums[i], i}HashMap<Integer, Integer> map new HashMap<>();for (int i 0; i < length; i) {int second target - nums[i];if(m…

PMOS快速關斷電路、PMOS加速關斷電路

[電源系列]二、低成本MOS快速關斷電路原理分析 MOS的減速加速電路設計 分享一個微碧在網上看到的電路情況 加速電路1 PMOS關斷時間較長。 當用100kHz的頻率驅動PMOS時&#xff0c;PMOS G極的電壓信號并不是一個脈沖波&#xff0c;PMOS一直處于線性放大的狀態&#xff0c;并且…

Docker筆記(基本命令、掛載本地gpu、Dockerfile文件配置、數據掛載、docker換源)

Docker 主要用于環境搭建以及服務部署 基本命令 1.查看鏡像 docker images 2.查看容器 docker ps # 查看容器僅僅為查看運行狀態的容器 docker ps -a # 查看所有狀態的容器3.退出容器 exit4.刪除鏡像、容器 docker rm 鏡像ID docker rm 容器ID docker rm -f 容器ID # 強制刪除…

算法競賽階段二-數據結構(37)數據結構循環鏈表模擬實現

之前單鏈表中&#xff0c;數組全初始化為0&#xff0c;末尾最后一個next 存的就是0&#xff0c;指向的就是頭節點循環鏈表的基本概念循環鏈表是一種特殊的鏈表&#xff0c;其尾節點的指針域指向頭節點&#xff0c;形成一個閉環。與普通單鏈表相比&#xff0c;循環鏈表的遍歷需要…

20250727讓飛凌OK3576-C開發板在Rockchip的原廠Android14下通過耳機播音

20250727讓飛凌OK3576-C開發板在Rockchip的原廠Android14下通過耳機播音 2025/7/27 23:28緣起&#xff1a;很容易知道 飛凌OK3576-C開發板 使用的聲卡芯片是 NAU88C22YG 新唐科技(NUVOTON) NAU8822LYG NAU88C22YG 新唐立體聲音頻編解碼芯片原理圖&#xff1a;OK3576-C V1.2_202…