[{"data":1,"prerenderedAt":4667},["ShallowReactive",2],{"wiki-page-/zh-tw/wiki/2026-01-07-esp32-jiao-cheng/ch4-jiao-cheng":3,"wiki-doc-items-/zh-tw/wiki/2026-01-07-esp32-jiao-cheng/ch4-jiao-cheng":4629,"language-switcher-data-/zh-tw/wiki/2026-01-07-esp32-jiao-cheng/ch4-jiao-cheng":4651,"wiki-i18n-paths-/zh-tw/wiki/2026-01-07-esp32-jiao-cheng/ch4-jiao-cheng":4666},{"id":4,"title":5,"body":6,"canonicalPath":4610,"chapter":4611,"chapterSort":4612,"date":4613,"description":12,"docI18nKey":4614,"docKey":4615,"docRoot":4616,"docTitle":4617,"extension":4618,"i18nKey":4619,"isBlogPost":4620,"isWikiDoc":414,"isWikiIndex":4620,"layout":4621,"legacyPath":4621,"locale":4622,"localeSlug":4623,"meta":4624,"navigation":414,"path":4610,"seo":4625,"sourcePath":4626,"sourceStem":4619,"stem":4627,"wikiDepth":348,"__hash__":4628},"content/_i18n/zh-tw/wiki/2026-01-07-ESP32教程/ch4-教程.md","教程",{"type":7,"value":8,"toc":4602},"minimark",[9,13,19,23,27,34,41,50,53,62,67,73,78,81,86,89,94,111,122,129,134,140,145,151,156,161,166,172,190,216,222,234,239,245,251,257,262,265,270,273,276,281,286,291,296,299,302,305,310,313,316,321,324,327,332,335,366,369,374,379,382,387,430,433,438,536,542,545,550,553,566,572,575,580,583,588,591,596,602,606,608,612,626,630,633,636,699,702,705,886,889,892,1024,1030,1036,1039,1044,1047,1052,1061,1067,1072,1082,1087,1091,1096,1223,1226,1235,1240,1250,1256,1272,1279,1308,1311,1338,1341,1345,1348,1354,1357,1360,1365,1370,1373,1378,1383,1387,1391,1394,1397,1402,1405,1410,1413,1418,1421,1428,1432,1439,1442,1472,1482,1607,1627,1641,1760,1766,1780,1788,1795,1869,1889,1895,2152,2159,2198,2212,2215,2219,2229,2240,2247,2283,2297,2393,2412,2577,2585,2590,2726,2749,2752,2757,2761,2764,2769,2772,2777,2780,2785,2788,2793,2796,2801,2810,2897,2907,2912,2934,2945,2958,2965,3019,3031,3044,3051,3183,3186,3538,3545,3579,3582,3600,3606,3849,3858,4351,4436,4439,4444,4449,4454,4467,4473,4478,4481,4484,4506,4511,4516,4519,4524,4527,4532,4537,4542,4550,4553,4556,4561,4568,4573,4576,4590,4593,4598],[10,11,12],"p",{},"下面教程我以ESP32S3和Fedora Linux為例.",[10,14,15],{},[16,17,18],"strong",{},"本教程特點是,雖然大部分基於正點原子教程,但是正點原子教程用了非常多的宏定義,這並不適合新手進行閱讀,本教程會盡量少用宏定義,儘量能夠把最原本的代碼教給你.",[20,21,22],"h3",{"id":22},"基礎工程創建",[24,25,26],"h4",{"id":26},"準備工作",[10,28,29,30],{},"(一些老版本必須移動這個文件夾)\n複製一下這個文件夾",[31,32,33],"code",{},"esp-idf/tools/templates/sample_project",[10,35,36],{},[37,38],"img",{"alt":39,"src":40},"alt text","https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768314488557.webp",[10,42,43,44,47],{},"複製到這裡",[31,45,46],{},"esp-idf/examples/get-started/sample_project",[37,48],{"alt":39,"src":49},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768314551666.webp",[24,51,52],{"id":52},"創建新工程",[10,54,55,56,59],{},"點擊",[31,57,58],{},"New Projects",[37,60],{"alt":39,"src":61},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768314732108.webp",[10,63,64],{},[37,65],{"alt":39,"src":66},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768314940430.webp",[10,68,69,70],{},"下面這倆選哪個都行,一些老版本沒有最底下那個選項.(正常最新版選最底下那個就行)\n",[37,71],{"alt":39,"src":72},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768315043852.webp",[10,74,75],{},[37,76],{"alt":39,"src":77},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768315170936.webp",[10,79,80],{},"創建成功",[10,82,83],{},[37,84],{"alt":39,"src":85},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768316173024.webp",[24,87,88],{"id":88},"menuconfig配置",[10,90,91],{},[37,92],{"alt":39,"src":93},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768316263151.webp",[95,96,97,108],"ol",{},[98,99,100,101,104,105],"li",{},"配置主頻\n搜索",[31,102,103],{},"CPU",",找到CPU主頻的設置,設置CPU主頻為240MHz(最大)\n",[37,106],{"alt":39,"src":107},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768316286100.webp",[98,109,110],{},"配置Flash和RAM",[10,112,113,114,117,118,121],{},"搜",[31,115,116],{},"Flash",",設置",[31,119,120],{},"Flash SPI mode","為QIO,這種模式下速度最快.",[10,123,124,125,128],{},"查看淘寶自己買的ESP32S3型號,",[31,126,127],{},"ESP32-S3 N16R8","得知我的Flash為16M,RAM為8M",[10,130,131],{},[37,132],{"alt":39,"src":133},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768316646459.webp",[10,135,113,136,139],{},[31,137,138],{},"PSRAM","並打勾",[10,141,142],{},[37,143],{"alt":39,"src":144},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768316691252.webp",[10,146,147,148],{},"查看官方給的PSRAM介紹,我們應該選",[31,149,150],{},"Octal SPI",[10,152,153],{},[37,154],{"alt":39,"src":155},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768316801358.webp",[10,157,158],{},[37,159],{"alt":39,"src":160},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768316830677.webp",[10,162,163],{},[37,164],{"alt":39,"src":165},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768316860867.webp",[95,167,169],{"start":168},3,[98,170,171],{},"配置FreeRTOS",[10,173,174,175,178,179,182,183,186,187],{},"將",[31,176,177],{},"configTICK_RATE_HZ","配置為",[31,180,181],{},"1000",",這樣週期為1ms,",[31,184,185],{},"vTaskDelay()","函數的單位也就變成了ms.\n",[37,188],{"alt":39,"src":189},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768316998368.webp",[95,191,193,210],{"start":192},4,[98,194,195,196,199,200,203,204,207],{},"配置分區表\n搜",[31,197,198],{},"partition",",找到",[31,201,202],{},"partition table",",並配置為",[31,205,206],{},"自定义分区表CSV",[37,208],{"alt":39,"src":209},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768317232438.webp",[98,211,212,213],{},"保存\n",[37,214],{"alt":39,"src":215},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768317262632.webp",[10,217,218,219],{},"舊的備份可以刪掉\n",[37,220],{"alt":39,"src":221},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768317292811.webp",[95,223,225],{"start":224},6,[98,226,227,228,199,231],{},"編輯分區表\nctrl shift P一起摁,輸入",[31,229,230],{},"Partition Table",[31,232,233],{},"Open Partition Table Eidtors UI",[10,235,236],{},[37,237],{"alt":39,"src":238},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768317456014.webp",[10,240,241,242],{},"按照下面一點都別抄錯的抄下來\n",[37,243],{"alt":39,"src":244},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768317821742.webp",[10,246,247,248],{},"可以看到都生成完畢了\n",[37,249],{"alt":39,"src":250},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768317884257.webp",[95,252,254],{"start":253},7,[98,255,256],{},"編譯測試",[10,258,259],{},[37,260],{"alt":39,"src":261},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768317920177.webp",[10,263,264],{},"如圖則為編譯成功",[10,266,267],{},[37,268],{"alt":39,"src":269},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768317956841.webp",[20,271,272],{"id":272},"分區表簡介",[10,274,275],{},"分區表作用是將Flash分為多個存儲區域,記錄每個區域的特定功能和用途.",[10,277,278],{},[37,279],{"alt":39,"src":280},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768364806657.webp",[10,282,283],{},[37,284],{"alt":39,"src":285},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768364833756.webp",[10,287,288],{},[37,289],{"alt":39,"src":290},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768364863022.webp",[10,292,293],{},[37,294],{"alt":39,"src":295},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768364885473.webp",[20,297,298],{"id":298},"自定義工程架構及添加組件",[24,300,301],{"id":301},"介紹工程架構",[10,303,304],{},"以下是樂鑫官方的工程結構:",[10,306,307],{},[37,308],{"alt":39,"src":309},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768364924079.webp",[10,311,312],{},"這種明顯是很雜糅的",[10,314,315],{},"以下是正點原子的工程結構,更加模塊化,擴展性更靈活,分層更清晰.",[10,317,318],{},[37,319],{"alt":39,"src":320},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768365242442.webp",[24,322,323],{"id":323},"創建工程架構",[10,325,326],{},"複製basic工程,並粘貼到你存放代碼的文件夾,然後重命名為N01_LED.",[10,328,329],{},[37,330],{"alt":39,"src":331},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768365712006.webp",[10,333,334],{},"用VScode打開新創建的文件夾",[336,337,342],"pre",{"className":338,"code":339,"language":340,"meta":341,"style":341},"language-bash shiki shiki-themes github-light github-dark","cd ~/UserFolder/MySource/ESP32_Projects/N01_LED\ncode .\n","bash","",[31,343,344,357],{"__ignoreMap":341},[345,346,349,353],"span",{"class":347,"line":348},"line",1,[345,350,352],{"class":351},"sj4cs","cd",[345,354,356],{"class":355},"sZZnC"," ~/UserFolder/MySource/ESP32_Projects/N01_LED\n",[345,358,360,363],{"class":347,"line":359},2,[345,361,31],{"class":362},"sScJk",[345,364,365],{"class":355}," .\n",[10,367,368],{},"創建以下文件",[10,370,371],{},[37,372],{"alt":39,"src":373},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768374450746.webp",[10,375,376],{},[37,377],{"alt":39,"src":378},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768374502096.webp",[10,380,381],{},"打開頂層CMakeLists",[10,383,384],{},[37,385],{"alt":39,"src":386},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768373817706.webp",[336,388,392],{"className":389,"code":390,"language":391,"meta":341,"style":341},"language-cmake shiki shiki-themes github-light github-dark","# Set the extra component directories\nset(EXTRA_COMPONENT_DIRS components/Middlewares)\n\n# Add compile options,warning has color.\nadd_compile_options(-fdiagnostics-color=always)\n","cmake",[31,393,394,400,410,416,421],{"__ignoreMap":341},[345,395,396],{"class":347,"line":348},[345,397,399],{"class":398},"sJ8bj","# Set the extra component directories\n",[345,401,402,406],{"class":347,"line":359},[345,403,405],{"class":404},"szBVR","set",[345,407,409],{"class":408},"sVt8B","(EXTRA_COMPONENT_DIRS components/Middlewares)\n",[345,411,412],{"class":347,"line":168},[345,413,415],{"emptyLinePlaceholder":414},true,"\n",[345,417,418],{"class":347,"line":192},[345,419,420],{"class":398},"# Add compile options,warning has color.\n",[345,422,424,427],{"class":347,"line":423},5,[345,425,426],{"class":404},"add_compile_options",[345,428,429],{"class":408},"(-fdiagnostics-color=always)\n",[10,431,432],{},"修改BSP裡的CMakeLists",[10,434,435],{},[37,436],{"alt":39,"src":437},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768374173407.webp",[336,439,441],{"className":389,"code":440,"language":391,"meta":341,"style":341},"set(src_dirs\n            LED)\n\nset(include_dirs\n            LED)\n\n# GPIO的一些组件在driver里\nset(requires\n            driver)\n\nidf_component_register(SRC_DIRS ${src_dirs}\n                      INCLUDE_DIRS ${include_dirs} REQUIRES ${requires})\n\ncomponent_compile_options(-ffast-math -O3 -Wno-error=format=-Wno-format)\n",[31,442,443,450,455,459,466,470,474,479,487,493,498,507,525,530],{"__ignoreMap":341},[345,444,445,447],{"class":347,"line":348},[345,446,405],{"class":404},[345,448,449],{"class":408},"(src_dirs\n",[345,451,452],{"class":347,"line":359},[345,453,454],{"class":408},"            LED)\n",[345,456,457],{"class":347,"line":168},[345,458,415],{"emptyLinePlaceholder":414},[345,460,461,463],{"class":347,"line":192},[345,462,405],{"class":404},[345,464,465],{"class":408},"(include_dirs\n",[345,467,468],{"class":347,"line":423},[345,469,454],{"class":408},[345,471,472],{"class":347,"line":224},[345,473,415],{"emptyLinePlaceholder":414},[345,475,476],{"class":347,"line":253},[345,477,478],{"class":398},"# GPIO的一些组件在driver里\n",[345,480,482,484],{"class":347,"line":481},8,[345,483,405],{"class":404},[345,485,486],{"class":408},"(requires\n",[345,488,490],{"class":347,"line":489},9,[345,491,492],{"class":408},"            driver)\n",[345,494,496],{"class":347,"line":495},10,[345,497,415],{"emptyLinePlaceholder":414},[345,499,501,504],{"class":347,"line":500},11,[345,502,503],{"class":408},"idf_component_register(SRC_DIRS ",[345,505,506],{"class":404},"${src_dirs}\n",[345,508,510,513,516,519,522],{"class":347,"line":509},12,[345,511,512],{"class":408},"                      INCLUDE_DIRS ",[345,514,515],{"class":404},"${include_dirs}",[345,517,518],{"class":408}," REQUIRES ",[345,520,521],{"class":404},"${requires}",[345,523,524],{"class":408},")\n",[345,526,528],{"class":347,"line":527},13,[345,529,415],{"emptyLinePlaceholder":414},[345,531,533],{"class":347,"line":532},14,[345,534,535],{"class":408},"component_compile_options(-ffast-math -O3 -Wno-error=format=-Wno-format)\n",[10,537,538,539],{},"清理再編譯看看\n",[37,540],{"alt":39,"src":541},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768374290311.webp",[10,543,544],{},"成功編譯",[10,546,547],{},[37,548],{"alt":39,"src":549},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768374519751.webp",[24,551,552],{"id":552},"添加組件",[10,554,555,556,559,560,563],{},"ctrl shift P搜索",[31,557,558],{},"esp component","找到",[31,561,562],{},"esp component registry",[37,564],{"alt":39,"src":565},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768374757763.webp",[10,567,568,569],{},"選擇型號\n",[37,570],{"alt":39,"src":571},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768374798596.webp",[10,573,574],{},"例如要安裝OpenAI,則搜索OpenAI",[10,576,577],{},[37,578],{"alt":39,"src":579},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768374854035.webp",[10,581,582],{},"點安裝",[10,584,585],{},[37,586],{"alt":39,"src":587},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768374870553.webp",[10,589,590],{},"安裝成功",[10,592,593],{},[37,594],{"alt":39,"src":595},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768374895177.webp",[10,597,598,599],{},"下圖所示就是安裝成功\n",[37,600],{"alt":39,"src":601},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768374968925.webp",[10,603,538,604],{},[37,605],{"alt":39,"src":541},[10,607,544],{},[10,609,610],{},[37,611],{"alt":39,"src":549},[10,613,614,615,618,619,622,623],{},"注意,在",[31,616,617],{},"main.c","裡可以直接調用添加的組件,但在",[31,620,621],{},"components","文件夾下的文件裡,不可以直接用,要修改",[31,624,625],{},"CMakeLists.txt",[20,627,629],{"id":628},"esp32的下載與調試","ESP32的下載與調試",[24,631,632],{"id":632},"下載",[10,634,635],{},"先寫一個程序,在main.c裡寫個helloworld.",[336,637,641],{"className":638,"code":639,"language":640,"meta":341,"style":341},"language-c shiki shiki-themes github-light github-dark","#include \u003Cstdio.h>\n\nvoid app_main(void)\n{\n    printf(\"Hello World!\\n\");\n}\n","c",[31,642,643,651,655,670,675,694],{"__ignoreMap":341},[345,644,645,648],{"class":347,"line":348},[345,646,647],{"class":404},"#include",[345,649,650],{"class":355}," \u003Cstdio.h>\n",[345,652,653],{"class":347,"line":359},[345,654,415],{"emptyLinePlaceholder":414},[345,656,657,660,663,666,668],{"class":347,"line":168},[345,658,659],{"class":404},"void",[345,661,662],{"class":362}," app_main",[345,664,665],{"class":408},"(",[345,667,659],{"class":404},[345,669,524],{"class":408},[345,671,672],{"class":347,"line":192},[345,673,674],{"class":408},"{\n",[345,676,677,680,682,685,688,691],{"class":347,"line":423},[345,678,679],{"class":362},"    printf",[345,681,665],{"class":408},[345,683,684],{"class":355},"\"Hello World!",[345,686,687],{"class":351},"\\n",[345,689,690],{"class":355},"\"",[345,692,693],{"class":408},");\n",[345,695,696],{"class":347,"line":224},[345,697,698],{"class":408},"}\n",[10,700,701],{},"你用一根USB-A轉USB-C的數據線,一頭在電腦上,一頭插到開發板的USB接口,而不是UART接口.",[10,703,704],{},"如圖",[95,706,707,794],{},[98,708,709,710,722,725,728,730,731,733,736,741,782,784,787,789,790,793],{},"查找設備",[95,711,712],{},[98,713,714,715,718,719],{},"Windows\n如果你是windows,則右鍵",[31,716,717],{},"此电脑",",點",[31,720,721],{},"管理",[723,724],"br",{},[37,726],{"alt":39,"src":727},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768375429763.webp",[723,729],{},"看到下面正常檢測出來了",[723,732],{},[37,734],{"alt":39,"src":735},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768375466417.webp",[95,737,738],{"start":359},[98,739,740],{},"Linux\n如果你是linux,則打開終端",[336,742,744],{"className":338,"code":743,"language":340,"meta":341,"style":341},"ls /dev | grep USB\n# 或者\n ls /dev | grep ACM\n",[31,745,746,763,768],{"__ignoreMap":341},[345,747,748,751,754,757,760],{"class":347,"line":348},[345,749,750],{"class":362},"ls",[345,752,753],{"class":355}," /dev",[345,755,756],{"class":404}," |",[345,758,759],{"class":362}," grep",[345,761,762],{"class":355}," USB\n",[345,764,765],{"class":347,"line":359},[345,766,767],{"class":398},"# 或者\n",[345,769,770,773,775,777,779],{"class":347,"line":168},[345,771,772],{"class":362}," ls",[345,774,753],{"class":355},[345,776,756],{"class":404},[345,778,759],{"class":362},[345,780,781],{"class":355}," ACM\n",[723,783],{},[37,785],{"alt":39,"src":786},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768449184448.webp",[723,788],{},"看是否有設備被檢測出來.如上圖,我的為",[31,791,792],{},"/dev/ttyACM0",".",[98,795,632,796,823,825,828,830,831,833,836,838,839,841,844,861,863,866,868,871,873,874,877,879,880,524,883],{},[95,797,798],{},[98,799,800,801,804,805,808,809,812,813,816,817,816,820,793],{},"Windows\n如果你是Windows,則要先選模式為",[31,802,803],{},"JTAG",",端口為檢測出來的端口",[31,806,807],{},"COM4",",芯片型號為",[31,810,811],{},"esp32s3",",然後點擊",[31,814,815],{},"清理",",",[31,818,819],{},"构建",[31,821,822],{},"烧录",[723,824],{},[37,826],{"alt":39,"src":827},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768375800452.webp",[723,829],{},"然後選擇yes",[723,832],{},[37,834],{"alt":39,"src":835},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768375960461.webp",[723,837],{},"如圖燒錄好了",[723,840],{},[37,842],{"alt":39,"src":843},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768376077047.webp",[95,845,846],{"start":359},[98,847,848,849,804,851,808,853,812,855,816,857,816,859,793],{},"Linux\n如果你是Linux,則要先選模式為",[31,850,803],{},[31,852,792],{},[31,854,811],{},[31,856,815],{},[31,858,819],{},[31,860,822],{},[723,862],{},[37,864],{"alt":39,"src":865},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768449239886.webp",[723,867],{},[37,869],{"alt":39,"src":870},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768449318480.webp",[723,872],{},"這裡選yes\n",[37,875],{"alt":39,"src":876},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768449382096.webp",[723,878],{},"如下圖就是燒錄成功了(如果你不能正常下載,請往下面找",[31,881,882],{},"常见问题",[37,884],{"alt":39,"src":885},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768539121456.webp",[24,887,888],{"id":888},"調試",[10,890,891],{},"先寫一個程序",[336,893,895],{"className":638,"code":894,"language":640,"meta":341,"style":341},"//包含FreeRTOS头文件(为了用vTaskDelay)\n#include \"freertos/FreeRTOS.h\"\n#include \"freertos/task.h\"\n\nint32_t i = 0;\n\nvoid app_main(void)\n{\n\n\n    //死循环,等同于while(1),但效率比while(1)更高\n    for(;;)\n    {\n        i++;\n        vTaskDelay(500 / portTICK_PERIOD_MS);  //延时500ms\n    }\n}\n",[31,896,897,902,909,916,920,937,941,953,957,961,965,970,978,983,993,1013,1019],{"__ignoreMap":341},[345,898,899],{"class":347,"line":348},[345,900,901],{"class":398},"//包含FreeRTOS头文件(为了用vTaskDelay)\n",[345,903,904,906],{"class":347,"line":359},[345,905,647],{"class":404},[345,907,908],{"class":355}," \"freertos/FreeRTOS.h\"\n",[345,910,911,913],{"class":347,"line":168},[345,912,647],{"class":404},[345,914,915],{"class":355}," \"freertos/task.h\"\n",[345,917,918],{"class":347,"line":192},[345,919,415],{"emptyLinePlaceholder":414},[345,921,922,925,928,931,934],{"class":347,"line":423},[345,923,924],{"class":404},"int32_t",[345,926,927],{"class":408}," i ",[345,929,930],{"class":404},"=",[345,932,933],{"class":351}," 0",[345,935,936],{"class":408},";\n",[345,938,939],{"class":347,"line":224},[345,940,415],{"emptyLinePlaceholder":414},[345,942,943,945,947,949,951],{"class":347,"line":253},[345,944,659],{"class":404},[345,946,662],{"class":362},[345,948,665],{"class":408},[345,950,659],{"class":404},[345,952,524],{"class":408},[345,954,955],{"class":347,"line":481},[345,956,674],{"class":408},[345,958,959],{"class":347,"line":489},[345,960,415],{"emptyLinePlaceholder":414},[345,962,963],{"class":347,"line":495},[345,964,415],{"emptyLinePlaceholder":414},[345,966,967],{"class":347,"line":500},[345,968,969],{"class":398},"    //死循环,等同于while(1),但效率比while(1)更高\n",[345,971,972,975],{"class":347,"line":509},[345,973,974],{"class":404},"    for",[345,976,977],{"class":408},"(;;)\n",[345,979,980],{"class":347,"line":527},[345,981,982],{"class":408},"    {\n",[345,984,985,988,991],{"class":347,"line":532},[345,986,987],{"class":408},"        i",[345,989,990],{"class":404},"++",[345,992,936],{"class":408},[345,994,996,999,1001,1004,1007,1010],{"class":347,"line":995},15,[345,997,998],{"class":362},"        vTaskDelay",[345,1000,665],{"class":408},[345,1002,1003],{"class":351},"500",[345,1005,1006],{"class":404}," /",[345,1008,1009],{"class":408}," portTICK_PERIOD_MS);",[345,1011,1012],{"class":398},"  //延时500ms\n",[345,1014,1016],{"class":347,"line":1015},16,[345,1017,1018],{"class":408},"    }\n",[345,1020,1022],{"class":347,"line":1021},17,[345,1023,698],{"class":408},[10,1025,1026,1027],{},"直接點調試,\n",[37,1028],{"alt":39,"src":1029},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768376418125.webp",[10,1031,1032,1033],{},"這樣就是正常進入debug了\n",[37,1034],{"alt":39,"src":1035},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768539536501.webp",[10,1037,1038],{},"下圖,\n第一個是開始運行.\n第二個是逐過程,一個函數一個函數的運行.\n第三個是單步調試,他會進入函數內部執行.\n第四個是單步跳出,會跳出這個函數.\n第五個是重啟程序,但在esp32裡有bug,貌似不會重啟,不知道後續是否會修.\n第六個是斷開鏈接,退出調試.",[10,1040,1041],{},[37,1042],{"alt":39,"src":1043},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768376495953.webp",[10,1045,1046],{},"也可以打斷點,這樣程序運行到斷點處就不會接著運行了.\n如圖",[10,1048,1049],{},[37,1050],{"alt":39,"src":1051},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768539606348.webp",[10,1053,1054,1055,1058],{},"然後也可以右鍵一個變量,把他添加到Watch,在程序某行打斷點,來看程序運行到這一行前(注意,這裡是在哪行打斷點,就是剛運行到哪行,那一個還沒有運行呢),這個變量的值為多少.\n如圖\n比如右鍵這個",[31,1056,1057],{},"i",[37,1059],{"alt":39,"src":1060},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768539649374.webp",[10,1062,1063,1064],{},"點擊這個",[31,1065,1066],{},"添加到监视(Add to Watch)",[10,1068,1069],{},[37,1070],{"alt":39,"src":1071},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768539673552.webp",[10,1073,1074,1075,1078,1079,1081],{},"你每次",[31,1076,1077],{},"开始运行(F5)","到斷點處,這個",[31,1080,1057],{},"都會加1.",[10,1083,1084],{},[37,1085],{"alt":39,"src":1086},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768539891853.webp",[1088,1089,1090],"h5",{"id":1090},"常見問題",[95,1092,1093],{},[98,1094,1095],{},"如果你是linux且遇到下面的這個問題",[336,1097,1099],{"className":338,"code":1098,"language":340,"meta":341,"style":341},"Open On-Chip Debugger v0.12.0-esp32-20250707 (2025-07-06-17:37) Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html [OpenOCD] Open On-Chip Debugger v0.12.0-esp32-20250707 (2025-07-06-17:37) Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html debug_level: 2 Info : esp_usb_jtag: VID set to 0x303a and PID to 0x1001 Info : esp_usb_jtag: capabilities descriptor set to 0x2000 Info : Listening on port 6666 for tcl connections Info : Listening on port 4444 for telnet connections ❌ Error: libusb_open() failed with LIBUSB_ERROR_ACCESS Error: libusb_open() failed with LIBUSB_ERROR_ACCESS ❌ Error: esp_usb_jtag: could not find or open device! /home/tungchiahui/.espressif/tools/openocd-esp32/v0.12.0-esp32-20250707/openocd-esp32/share/openocd/scripts/target/esp_common.cfg:9: Error: Traceback (most recent call last): File \"/home/tungchiahui/.espressif/tools/openocd-esp32/v0.12.0-esp32-20250707/openocd-esp32/share/openocd/scripts/target/esp_common.cfg\", line 9, in script Error: esp_usb_jtag: could not find or open device! /home/tungchiahui/.espressif/tools/openocd-esp32/v0.12.0-esp32-20250707/openocd-esp32/share/openocd/scripts/target/esp_common.cfg:9: Error: Traceback (most recent call last): File \"/home/tungchiahui/.espressif/tools/openocd-esp32/v0.12.0-esp32-20250707/openocd-esp32/share/openocd/scripts/target/esp_common.cfg\", line 9, in script For assistance with OpenOCD errors, please refer to our Troubleshooting FAQ: https://github.com/espressif/openocd-esp32/wiki/Troubleshooting-FAQ OpenOCD Exit with non-zero error code 1 [Stopped] : OpenOCD Server [/OpenOCD] [Flash] Can't perform JTAG flash, because OpenOCD server is not running! Flash has finished. You can monitor your device with 'ESP-IDF: Monitor command'然后tungchiahui@Dell-G15-5511:~/UserFolder/MySource/ESP32_Projects/N01_LED$ ls /dev | grep ACM ttyACM0 tungchiahui@Dell-G15-5511:~/UserFolder/MySource/ESP32_Projects/N01_LED$ lsusb Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 003 Device 002: ID 0416:b23c Winbond Electronics Corp. Gaming Keyboard Bus 003 Device 003: ID 046d:c539 Logitech, Inc. Lightspeed Receiver Bus 003 Device 004: ID 0c45:6720 Microdia Integrated_Webcam_HD Bus 003 Device 005: ID 8087:0026 Intel Corp. AX201 Bluetooth Bus 003 Device 006: ID 303a:1001 Espressif USB JTAG/serial debug unit Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub tungchiahui@Dell-G15-5511:~/UserFolder/MySource/ESP32_Projects/N01_LED\n",[31,1100,1101],{"__ignoreMap":341},[345,1102,1103,1106,1109,1112,1115,1118,1121,1124,1127,1130,1132,1135,1137,1140,1143,1146,1148,1151,1154,1157,1160,1163,1166,1169,1172,1175,1178,1181,1184,1186,1188,1190,1192,1194,1196,1198,1200,1203,1206,1209,1211,1214,1217,1220],{"class":347,"line":348},[345,1104,1105],{"class":362},"Open",[345,1107,1108],{"class":355}," On-Chip",[345,1110,1111],{"class":355}," Debugger",[345,1113,1114],{"class":355}," v0.12.0-esp32-20250707",[345,1116,1117],{"class":408}," (2025-07-06-17:37) Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html [OpenOCD] Open On-Chip Debugger v0.12.0-esp32-20250707 (",[345,1119,1120],{"class":362},"2025-07-06-17:37",[345,1122,1123],{"class":408},") Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html debug_level: 2 Info ",[345,1125,1126],{"class":351},":",[345,1128,1129],{"class":408}," esp_usb_jtag: VID set to 0x303a and PID to 0x1001 Info ",[345,1131,1126],{"class":351},[345,1133,1134],{"class":408}," esp_usb_jtag: capabilities descriptor set to 0x2000 Info ",[345,1136,1126],{"class":351},[345,1138,1139],{"class":408}," Listening on port 6666 ",[345,1141,1142],{"class":404},"for",[345,1144,1145],{"class":408}," tcl connections Info ",[345,1147,1126],{"class":351},[345,1149,1150],{"class":408}," Listening on port ",[345,1152,1153],{"class":351},"4444",[345,1155,1156],{"class":408}," for telnet connections ❌ Error: libusb_open() failed with LIBUSB_ERROR_ACCESS Error: libusb_open() failed with LIBUSB_ERROR_ACCESS ❌ Error: esp_usb_jtag: could not find or open device",[345,1158,1159],{"class":404},"!",[345,1161,1162],{"class":408}," /home/tungchiahui/.espressif/tools/openocd-esp32/v0.12.0-esp32-20250707/openocd-esp32/share/openocd/scripts/target/esp_common.cfg:9: Error: Traceback (",[345,1164,1165],{"class":362},"most",[345,1167,1168],{"class":355}," recent",[345,1170,1171],{"class":355}," call",[345,1173,1174],{"class":355}," last",[345,1176,1177],{"class":408},"): File ",[345,1179,1180],{"class":355},"\"/home/tungchiahui/.espressif/tools/openocd-esp32/v0.12.0-esp32-20250707/openocd-esp32/share/openocd/scripts/target/esp_common.cfg\"",[345,1182,1183],{"class":408},", line 9, in script Error: esp_usb_jtag: could not find or open device",[345,1185,1159],{"class":404},[345,1187,1162],{"class":408},[345,1189,1165],{"class":362},[345,1191,1168],{"class":355},[345,1193,1171],{"class":355},[345,1195,1174],{"class":355},[345,1197,1177],{"class":408},[345,1199,1180],{"class":355},[345,1201,1202],{"class":408},", line 9, in script For assistance with OpenOCD errors, please refer to our Troubleshooting FAQ: https://github.com/espressif/openocd-esp32/wiki/Troubleshooting-FAQ OpenOCD Exit with non-zero error code ",[345,1204,1205],{"class":351},"1",[345,1207,1208],{"class":408}," [Stopped] ",[345,1210,1126],{"class":351},[345,1212,1213],{"class":408}," OpenOCD Server [/OpenOCD] [Flash] Can",[345,1215,1216],{"class":355},"'t perform JTAG flash, because OpenOCD server is not running! Flash has finished. You can monitor your device with '",[345,1218,1219],{"class":408},"ESP-IDF: Monitor command",[345,1221,1222],{"class":355},"'然后tungchiahui@Dell-G15-5511:~/UserFolder/MySource/ESP32_Projects/N01_LED$ ls /dev | grep ACM ttyACM0 tungchiahui@Dell-G15-5511:~/UserFolder/MySource/ESP32_Projects/N01_LED$ lsusb Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 003 Device 002: ID 0416:b23c Winbond Electronics Corp. Gaming Keyboard Bus 003 Device 003: ID 046d:c539 Logitech, Inc. Lightspeed Receiver Bus 003 Device 004: ID 0c45:6720 Microdia Integrated_Webcam_HD Bus 003 Device 005: ID 8087:0026 Intel Corp. AX201 Bluetooth Bus 003 Device 006: ID 303a:1001 Espressif USB JTAG/serial debug unit Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub tungchiahui@Dell-G15-5511:~/UserFolder/MySource/ESP32_Projects/N01_LED\n",[10,1224,1225],{},"多半是因為權限問題.",[336,1227,1229],{"className":338,"code":1228,"language":340,"meta":341,"style":341},"lsusb\n",[31,1230,1231],{"__ignoreMap":341},[345,1232,1233],{"class":347,"line":348},[345,1234,1228],{"class":362},[10,1236,1237],{},[37,1238],{"alt":39,"src":1239},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768538777147.webp",[10,1241,1242,1243,1246,1247],{},"找到這個後面是",[31,1244,1245],{},"1001","的這個設備,記住它前面這個設備id,比如我的是",[31,1248,1249],{},"303a",[10,1251,1252,1253],{},"接下來,編輯",[31,1254,1255],{},"udev",[336,1257,1259],{"className":338,"code":1258,"language":340,"meta":341,"style":341},"sudo vim /etc/udev/rules.d/99-esp32-usb-jtag.rules\n",[31,1260,1261],{"__ignoreMap":341},[345,1262,1263,1266,1269],{"class":347,"line":348},[345,1264,1265],{"class":362},"sudo",[345,1267,1268],{"class":355}," vim",[345,1270,1271],{"class":355}," /etc/udev/rules.d/99-esp32-usb-jtag.rules\n",[10,1273,1274,1275,1278],{},"輸入以下內容(注意,這裡的",[31,1276,1277],{},"idVendor","要填上你對應的)",[336,1280,1282],{"className":338,"code":1281,"language":340,"meta":341,"style":341},"SUBSYSTEM==\"usb\", ATTR{idVendor}==\"303a\", MODE=\"0666\"\n",[31,1283,1284],{"__ignoreMap":341},[345,1285,1286,1289,1291,1294,1297,1300,1303,1305],{"class":347,"line":348},[345,1287,1288],{"class":408},"SUBSYSTEM",[345,1290,930],{"class":404},[345,1292,1293],{"class":355},"=\"usb\",",[345,1295,1296],{"class":362}," ATTR",[345,1298,1299],{"class":355},"{idVendor}==",[345,1301,1302],{"class":362},"\"303a\"",[345,1304,816],{"class":362},[345,1306,1307],{"class":355}," MODE=\"0666\"\n",[10,1309,1310],{},"保存後,先敲下面的命令",[336,1312,1314],{"className":338,"code":1313,"language":340,"meta":341,"style":341},"sudo udevadm control --reload-rules\nsudo udevadm trigger\n",[31,1315,1316,1329],{"__ignoreMap":341},[345,1317,1318,1320,1323,1326],{"class":347,"line":348},[345,1319,1265],{"class":362},[345,1321,1322],{"class":355}," udevadm",[345,1324,1325],{"class":355}," control",[345,1327,1328],{"class":351}," --reload-rules\n",[345,1330,1331,1333,1335],{"class":347,"line":359},[345,1332,1265],{"class":362},[345,1334,1322],{"class":355},[345,1336,1337],{"class":355}," trigger\n",[10,1339,1340],{},"然後插拔USB,再燒錄就成功了.",[20,1342,1344],{"id":1343},"esp32-s3的時鐘樹","ESP32-S3的時鐘樹",[24,1346,1347],{"id":1347},"時鐘",[10,1349,1350,1351],{},"時鐘是一個週期性翻轉的信號\n",[37,1352],{"alt":39,"src":1353},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768377363665.webp",[10,1355,1356],{},"每來一次時鐘邊沿,整個電路就會完整一次狀態的更新,\n這樣,整個系統就會往前一步.",[24,1358,1359],{"id":1359},"時鐘樹",[10,1361,1362],{},[37,1363],{"alt":39,"src":1364},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768377731446.webp",[10,1366,1367],{},[37,1368],{"alt":39,"src":1369},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768377775953.webp",[10,1371,1372],{},"OSC是高速晶振,CLK是時鐘,PLL是鎖相環,圖裡的DIV是分頻器,MUX是選擇器.\nOSC要接晶振.\nCLK是可用的時鐘信號.\nPLL為了被倍頻或者分頻的時鐘頻率.\nDIV為了省電,節約資源.\nMUX是選擇哪一個時鐘源.",[10,1374,1375],{},[37,1376],{"alt":39,"src":1377},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768378403104.webp",[10,1379,1380],{},[37,1381],{"alt":39,"src":1382},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768378429705.webp",[20,1384,1386],{"id":1385},"gpio","GPIO",[24,1388,1390],{"id":1389},"gpio理論","GPIO理論",[10,1392,1393],{},"實際上就是通用輸入輸出端口的意思,可以輸出高低電平,也可以讀取高低電平.",[10,1395,1396],{},"輸入的原理,就是如下圖,如果KEY按下會讓電路電平變為低,那就要上拉電阻,用下降沿來判斷按鍵是否按下.\n由於上拉電阻,所以剛開始KEY沒按下的時候下方電路的IO口那邊是高電平,一旦KEY按下,將會變成低電平,這樣就會有一個下降沿(電平由高變低).",[10,1398,1399],{},[37,1400],{"alt":39,"src":1401},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768390289518.webp",[10,1403,1404],{},"輸出,如下圖,當IO為高電平的時候,LED發光二極管導通,然後LED亮,當IO為低電平的時候,LED發光二極管不導通,LED滅.",[10,1406,1407],{},[37,1408],{"alt":39,"src":1409},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768390481849.webp",[10,1411,1412],{},"以下是ESP32的IO:",[10,1414,1415],{},[37,1416],{"alt":39,"src":1417},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768391351684.webp",[10,1419,1420],{},"他們是高度複用的,每一個都可以複用成其他外設的接口.",[10,1422,1423,1424,1427],{},"但有些特例,有些引腳不可以當輸出輸入,他們只能用來連接模塊上的FLASH或PSRAM.\n可以看正點原子的",[31,1425,1426],{},"esp32-s3_datasheet_cn.pdf","裡的詳細說明.",[24,1429,1431],{"id":1430},"gpio相關函數","GPIO相關函數",[95,1433,1434],{},[98,1435,1436],{},[16,1437,1438],{},"gpio_config",[10,1440,1441],{},"這個是GPIO初始化函數",[336,1443,1445],{"className":638,"code":1444,"language":640,"meta":341,"style":341},"esp_err_t gpio_config(const gpio_config_t *pGPIOConfig)\n",[31,1446,1447],{"__ignoreMap":341},[345,1448,1449,1452,1455,1457,1460,1463,1466,1470],{"class":347,"line":348},[345,1450,1451],{"class":351},"esp_err_t",[345,1453,1454],{"class":362}," gpio_config",[345,1456,665],{"class":408},[345,1458,1459],{"class":404},"const",[345,1461,1462],{"class":351}," gpio_config_t",[345,1464,1465],{"class":404}," *",[345,1467,1469],{"class":1468},"s4XuR","pGPIOConfig",[345,1471,524],{"class":408},[10,1473,1474,1475,718,1478,1481],{},"然後你右鍵選中",[31,1476,1477],{},"gpio_config_t",[31,1479,1480],{},"go to definition",",就會出現下面這個是GPIO初始化函數里的入口參數的結構體",[336,1483,1485],{"className":638,"code":1484,"language":640,"meta":341,"style":341},"/**\n * @brief Configuration parameters of GPIO pad for gpio_config function\n */\ntypedef struct {\n    uint64_t pin_bit_mask;          /*!\u003C GPIO pin: set with bit mask, each bit maps to a GPIO */\n    gpio_mode_t mode;               /*!\u003C GPIO mode: set input/output mode                     */\n    gpio_pullup_t pull_up_en;       /*!\u003C GPIO pull-up                                         */\n    gpio_pulldown_t pull_down_en;   /*!\u003C GPIO pull-down                                       */\n    gpio_int_type_t intr_type;      /*!\u003C GPIO interrupt type                                  */\n#if SOC_GPIO_SUPPORT_PIN_HYS_FILTER\n    gpio_hys_ctrl_mode_t hys_ctrl_mode;       /*!\u003C GPIO hysteresis: hysteresis filter on slope input    */\n#endif\n} gpio_config_t;\n",[31,1486,1487,1492,1503,1508,1519,1530,1541,1552,1563,1574,1582,1593,1598],{"__ignoreMap":341},[345,1488,1489],{"class":347,"line":348},[345,1490,1491],{"class":398},"/**\n",[345,1493,1494,1497,1500],{"class":347,"line":359},[345,1495,1496],{"class":398}," * ",[345,1498,1499],{"class":404},"@brief",[345,1501,1502],{"class":398}," Configuration parameters of GPIO pad for gpio_config function\n",[345,1504,1505],{"class":347,"line":168},[345,1506,1507],{"class":398}," */\n",[345,1509,1510,1513,1516],{"class":347,"line":192},[345,1511,1512],{"class":404},"typedef",[345,1514,1515],{"class":404}," struct",[345,1517,1518],{"class":408}," {\n",[345,1520,1521,1524,1527],{"class":347,"line":423},[345,1522,1523],{"class":404},"    uint64_t",[345,1525,1526],{"class":408}," pin_bit_mask;",[345,1528,1529],{"class":398},"          /*!\u003C GPIO pin: set with bit mask, each bit maps to a GPIO */\n",[345,1531,1532,1535,1538],{"class":347,"line":224},[345,1533,1534],{"class":351},"    gpio_mode_t",[345,1536,1537],{"class":408}," mode;",[345,1539,1540],{"class":398},"               /*!\u003C GPIO mode: set input/output mode                     */\n",[345,1542,1543,1546,1549],{"class":347,"line":253},[345,1544,1545],{"class":351},"    gpio_pullup_t",[345,1547,1548],{"class":408}," pull_up_en;",[345,1550,1551],{"class":398},"       /*!\u003C GPIO pull-up                                         */\n",[345,1553,1554,1557,1560],{"class":347,"line":481},[345,1555,1556],{"class":351},"    gpio_pulldown_t",[345,1558,1559],{"class":408}," pull_down_en;",[345,1561,1562],{"class":398},"   /*!\u003C GPIO pull-down                                       */\n",[345,1564,1565,1568,1571],{"class":347,"line":489},[345,1566,1567],{"class":351},"    gpio_int_type_t",[345,1569,1570],{"class":408}," intr_type;",[345,1572,1573],{"class":398},"      /*!\u003C GPIO interrupt type                                  */\n",[345,1575,1576,1579],{"class":347,"line":495},[345,1577,1578],{"class":404},"#if",[345,1580,1581],{"class":362}," SOC_GPIO_SUPPORT_PIN_HYS_FILTER\n",[345,1583,1584,1587,1590],{"class":347,"line":500},[345,1585,1586],{"class":351},"    gpio_hys_ctrl_mode_t",[345,1588,1589],{"class":408}," hys_ctrl_mode;",[345,1591,1592],{"class":398},"       /*!\u003C GPIO hysteresis: hysteresis filter on slope input    */\n",[345,1594,1595],{"class":347,"line":509},[345,1596,1597],{"class":404},"#endif\n",[345,1599,1600,1603,1605],{"class":347,"line":527},[345,1601,1602],{"class":408},"} ",[345,1604,1477],{"class":351},[345,1606,936],{"class":408},[10,1608,1609,1612,1613,1616,1617,1620,1621,1624,1625],{},[31,1610,1611],{},"pin_bit_mask","是用於設置你要配置的GPIO引腳,一般為",[31,1614,1615],{},"1ull \u003C\u003C x",",這裡的",[31,1618,1619],{},"x","就是你要設置的GPIO的",[31,1622,1623],{},"IOx","號.",[723,1626],{},[10,1628,1629,1632,1633,1635,1636,793,1639],{},[31,1630,1631],{},"mode","是配置輸入還是輸出的模式,你可以",[31,1634,1480],{},"看看",[31,1637,1638],{},"gpio_mode_t",[723,1640],{},[336,1642,1644],{"className":638,"code":1643,"language":640,"meta":341,"style":341},"typedef enum {\n    GPIO_MODE_DISABLE = GPIO_MODE_DEF_DISABLE,                                                         /*!\u003C GPIO mode : disable input and output             */\n    GPIO_MODE_INPUT = GPIO_MODE_DEF_INPUT,                                                             /*!\u003C GPIO mode : input only                           */\n    GPIO_MODE_OUTPUT = GPIO_MODE_DEF_OUTPUT,                                                           /*!\u003C GPIO mode : output only mode                     */\n    GPIO_MODE_OUTPUT_OD = ((GPIO_MODE_DEF_OUTPUT) | (GPIO_MODE_DEF_OD)),                               /*!\u003C GPIO mode : output only with open-drain mode     */\n    GPIO_MODE_INPUT_OUTPUT_OD = ((GPIO_MODE_DEF_INPUT) | (GPIO_MODE_DEF_OUTPUT) | (GPIO_MODE_DEF_OD)), /*!\u003C GPIO mode : output and input with open-drain mode*/\n    GPIO_MODE_INPUT_OUTPUT = ((GPIO_MODE_DEF_INPUT) | (GPIO_MODE_DEF_OUTPUT)),                         /*!\u003C GPIO mode : output and input mode                */\n} gpio_mode_t;\n",[31,1645,1646,1655,1668,1681,1694,1713,1735,1752],{"__ignoreMap":341},[345,1647,1648,1650,1653],{"class":347,"line":348},[345,1649,1512],{"class":404},[345,1651,1652],{"class":404}," enum",[345,1654,1518],{"class":408},[345,1656,1657,1660,1662,1665],{"class":347,"line":359},[345,1658,1659],{"class":408},"    GPIO_MODE_DISABLE ",[345,1661,930],{"class":404},[345,1663,1664],{"class":408}," GPIO_MODE_DEF_DISABLE,",[345,1666,1667],{"class":398},"                                                         /*!\u003C GPIO mode : disable input and output             */\n",[345,1669,1670,1673,1675,1678],{"class":347,"line":168},[345,1671,1672],{"class":408},"    GPIO_MODE_INPUT ",[345,1674,930],{"class":404},[345,1676,1677],{"class":408}," GPIO_MODE_DEF_INPUT,",[345,1679,1680],{"class":398},"                                                             /*!\u003C GPIO mode : input only                           */\n",[345,1682,1683,1686,1688,1691],{"class":347,"line":192},[345,1684,1685],{"class":408},"    GPIO_MODE_OUTPUT ",[345,1687,930],{"class":404},[345,1689,1690],{"class":408}," GPIO_MODE_DEF_OUTPUT,",[345,1692,1693],{"class":398},"                                                           /*!\u003C GPIO mode : output only mode                     */\n",[345,1695,1696,1699,1701,1704,1707,1710],{"class":347,"line":423},[345,1697,1698],{"class":408},"    GPIO_MODE_OUTPUT_OD ",[345,1700,930],{"class":404},[345,1702,1703],{"class":408}," ((GPIO_MODE_DEF_OUTPUT) ",[345,1705,1706],{"class":404},"|",[345,1708,1709],{"class":408}," (GPIO_MODE_DEF_OD)),",[345,1711,1712],{"class":398},"                               /*!\u003C GPIO mode : output only with open-drain mode     */\n",[345,1714,1715,1718,1720,1723,1725,1728,1730,1732],{"class":347,"line":224},[345,1716,1717],{"class":408},"    GPIO_MODE_INPUT_OUTPUT_OD ",[345,1719,930],{"class":404},[345,1721,1722],{"class":408}," ((GPIO_MODE_DEF_INPUT) ",[345,1724,1706],{"class":404},[345,1726,1727],{"class":408}," (GPIO_MODE_DEF_OUTPUT) ",[345,1729,1706],{"class":404},[345,1731,1709],{"class":408},[345,1733,1734],{"class":398}," /*!\u003C GPIO mode : output and input with open-drain mode*/\n",[345,1736,1737,1740,1742,1744,1746,1749],{"class":347,"line":253},[345,1738,1739],{"class":408},"    GPIO_MODE_INPUT_OUTPUT ",[345,1741,930],{"class":404},[345,1743,1722],{"class":408},[345,1745,1706],{"class":404},[345,1747,1748],{"class":408}," (GPIO_MODE_DEF_OUTPUT)),",[345,1750,1751],{"class":398},"                         /*!\u003C GPIO mode : output and input mode                */\n",[345,1753,1754,1756,1758],{"class":347,"line":481},[345,1755,1602],{"class":408},[345,1757,1638],{"class":351},[345,1759,936],{"class":408},[10,1761,1762,1763,1765],{},"其他的也一樣,你都可以",[31,1764,1480],{},"來看這個結構體到底能填什麼.",[10,1767,1768,1771,1772,1774,1777,1778],{},[31,1769,1770],{},"pull_up_en","是是否使能上拉電阻,就是講IO那條電路再並聯一條上面有一個電阻和VCC的電路.",[723,1773],{},[31,1775,1776],{},"pull_down_en","是是否使能下拉電阻,就是講IO那條電路再並聯一條上面有一個電阻和GND的電路.",[723,1779],{},[10,1781,1782,1785,1786],{},[31,1783,1784],{},"intr_type","是是否啟用中斷類型.",[723,1787],{},[95,1789,1790],{"start":359},[98,1791,1792],{},[16,1793,1794],{},"gpio_set_level",[336,1796,1798],{"className":638,"code":1797,"language":640,"meta":341,"style":341},"esp_err_t gpio_set_level(gpio_num_t gpio_num, uint32_t level)\n{\n    GPIO_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), \"GPIO output gpio_num error\", ESP_ERR_INVALID_ARG);\n    gpio_hal_set_level(gpio_context.gpio_hal, gpio_num, level);\n    return ESP_OK;\n}\n",[31,1799,1800,1826,1830,1849,1857,1865],{"__ignoreMap":341},[345,1801,1802,1804,1807,1809,1812,1815,1818,1821,1824],{"class":347,"line":348},[345,1803,1451],{"class":351},[345,1805,1806],{"class":362}," gpio_set_level",[345,1808,665],{"class":408},[345,1810,1811],{"class":351},"gpio_num_t",[345,1813,1814],{"class":1468}," gpio_num",[345,1816,1817],{"class":408},", ",[345,1819,1820],{"class":404},"uint32_t",[345,1822,1823],{"class":1468}," level",[345,1825,524],{"class":408},[345,1827,1828],{"class":347,"line":359},[345,1829,674],{"class":408},[345,1831,1832,1835,1837,1840,1843,1846],{"class":347,"line":168},[345,1833,1834],{"class":362},"    GPIO_CHECK",[345,1836,665],{"class":408},[345,1838,1839],{"class":362},"GPIO_IS_VALID_OUTPUT_GPIO",[345,1841,1842],{"class":408},"(gpio_num), ",[345,1844,1845],{"class":355},"\"GPIO output gpio_num error\"",[345,1847,1848],{"class":408},", ESP_ERR_INVALID_ARG);\n",[345,1850,1851,1854],{"class":347,"line":192},[345,1852,1853],{"class":362},"    gpio_hal_set_level",[345,1855,1856],{"class":408},"(gpio_context.gpio_hal, gpio_num, level);\n",[345,1858,1859,1862],{"class":347,"line":423},[345,1860,1861],{"class":404},"    return",[345,1863,1864],{"class":408}," ESP_OK;\n",[345,1866,1867],{"class":347,"line":224},[345,1868,698],{"class":408},[10,1870,1871,1874,1875,1877,1878,1616,1881,1883,1884,1886,1887],{},[31,1872,1873],{},"gpio_num","是選擇哪一個IO口,可以",[31,1876,1480],{},"看一看,如下面的代碼可知,他可以填",[31,1879,1880],{},"GPIO_NUM_x",[31,1882,1619],{},"就是選擇初始化",[31,1885,1623],{},"(也就是初始化哪一個引腳IO)",[723,1888],{},[10,1890,1891,1894],{},[31,1892,1893],{},"level","是輸出的電平是高還是低,填0就是低,填1就是高.",[336,1896,1898],{"className":638,"code":1897,"language":640,"meta":341,"style":341},"/**\n * @brief GPIO number\n */\ntypedef enum {\n    GPIO_NUM_NC = -1,    /*!\u003C Use to signal not connected to S/W */\n    GPIO_NUM_0 = 0,     /*!\u003C GPIO0, input and output */\n    GPIO_NUM_1 = 1,     /*!\u003C GPIO1, input and output */\n    GPIO_NUM_2 = 2,     /*!\u003C GPIO2, input and output */\n    GPIO_NUM_3 = 3,     /*!\u003C GPIO3, input and output */\n    GPIO_NUM_4 = 4,     /*!\u003C GPIO4, input and output */\n    GPIO_NUM_5 = 5,     /*!\u003C GPIO5, input and output */\n    GPIO_NUM_6 = 6,     /*!\u003C GPIO6, input and output */\n    GPIO_NUM_7 = 7,     /*!\u003C GPIO7, input and output */\n    GPIO_NUM_8 = 8,     /*!\u003C GPIO8, input and output */\n    GPIO_NUM_9 = 9,     /*!\u003C GPIO9, input and output */\n    GPIO_NUM_10 = 10,   /*!\u003C GPIO10, input and output */\n    GPIO_NUM_11 = 11,   /*!\u003C GPIO11, input and output */\n    GPIO_NUM_12 = 12,   /*!\u003C GPIO12, input and output */\n    GPIO_NUM_MAX,\n} gpio_num_t;\n",[31,1899,1900,1904,1913,1917,1925,1942,1956,1971,1986,2001,2016,2031,2046,2061,2076,2091,2106,2121,2137,2143],{"__ignoreMap":341},[345,1901,1902],{"class":347,"line":348},[345,1903,1491],{"class":398},[345,1905,1906,1908,1910],{"class":347,"line":359},[345,1907,1496],{"class":398},[345,1909,1499],{"class":404},[345,1911,1912],{"class":398}," GPIO number\n",[345,1914,1915],{"class":347,"line":168},[345,1916,1507],{"class":398},[345,1918,1919,1921,1923],{"class":347,"line":192},[345,1920,1512],{"class":404},[345,1922,1652],{"class":404},[345,1924,1518],{"class":408},[345,1926,1927,1930,1932,1935,1937,1939],{"class":347,"line":423},[345,1928,1929],{"class":408},"    GPIO_NUM_NC ",[345,1931,930],{"class":404},[345,1933,1934],{"class":404}," -",[345,1936,1205],{"class":351},[345,1938,816],{"class":408},[345,1940,1941],{"class":398},"    /*!\u003C Use to signal not connected to S/W */\n",[345,1943,1944,1947,1949,1951,1953],{"class":347,"line":224},[345,1945,1946],{"class":408},"    GPIO_NUM_0 ",[345,1948,930],{"class":404},[345,1950,933],{"class":351},[345,1952,816],{"class":408},[345,1954,1955],{"class":398},"     /*!\u003C GPIO0, input and output */\n",[345,1957,1958,1961,1963,1966,1968],{"class":347,"line":253},[345,1959,1960],{"class":408},"    GPIO_NUM_1 ",[345,1962,930],{"class":404},[345,1964,1965],{"class":351}," 1",[345,1967,816],{"class":408},[345,1969,1970],{"class":398},"     /*!\u003C GPIO1, input and output */\n",[345,1972,1973,1976,1978,1981,1983],{"class":347,"line":481},[345,1974,1975],{"class":408},"    GPIO_NUM_2 ",[345,1977,930],{"class":404},[345,1979,1980],{"class":351}," 2",[345,1982,816],{"class":408},[345,1984,1985],{"class":398},"     /*!\u003C GPIO2, input and output */\n",[345,1987,1988,1991,1993,1996,1998],{"class":347,"line":489},[345,1989,1990],{"class":408},"    GPIO_NUM_3 ",[345,1992,930],{"class":404},[345,1994,1995],{"class":351}," 3",[345,1997,816],{"class":408},[345,1999,2000],{"class":398},"     /*!\u003C GPIO3, input and output */\n",[345,2002,2003,2006,2008,2011,2013],{"class":347,"line":495},[345,2004,2005],{"class":408},"    GPIO_NUM_4 ",[345,2007,930],{"class":404},[345,2009,2010],{"class":351}," 4",[345,2012,816],{"class":408},[345,2014,2015],{"class":398},"     /*!\u003C GPIO4, input and output */\n",[345,2017,2018,2021,2023,2026,2028],{"class":347,"line":500},[345,2019,2020],{"class":408},"    GPIO_NUM_5 ",[345,2022,930],{"class":404},[345,2024,2025],{"class":351}," 5",[345,2027,816],{"class":408},[345,2029,2030],{"class":398},"     /*!\u003C GPIO5, input and output */\n",[345,2032,2033,2036,2038,2041,2043],{"class":347,"line":509},[345,2034,2035],{"class":408},"    GPIO_NUM_6 ",[345,2037,930],{"class":404},[345,2039,2040],{"class":351}," 6",[345,2042,816],{"class":408},[345,2044,2045],{"class":398},"     /*!\u003C GPIO6, input and output */\n",[345,2047,2048,2051,2053,2056,2058],{"class":347,"line":527},[345,2049,2050],{"class":408},"    GPIO_NUM_7 ",[345,2052,930],{"class":404},[345,2054,2055],{"class":351}," 7",[345,2057,816],{"class":408},[345,2059,2060],{"class":398},"     /*!\u003C GPIO7, input and output */\n",[345,2062,2063,2066,2068,2071,2073],{"class":347,"line":532},[345,2064,2065],{"class":408},"    GPIO_NUM_8 ",[345,2067,930],{"class":404},[345,2069,2070],{"class":351}," 8",[345,2072,816],{"class":408},[345,2074,2075],{"class":398},"     /*!\u003C GPIO8, input and output */\n",[345,2077,2078,2081,2083,2086,2088],{"class":347,"line":995},[345,2079,2080],{"class":408},"    GPIO_NUM_9 ",[345,2082,930],{"class":404},[345,2084,2085],{"class":351}," 9",[345,2087,816],{"class":408},[345,2089,2090],{"class":398},"     /*!\u003C GPIO9, input and output */\n",[345,2092,2093,2096,2098,2101,2103],{"class":347,"line":1015},[345,2094,2095],{"class":408},"    GPIO_NUM_10 ",[345,2097,930],{"class":404},[345,2099,2100],{"class":351}," 10",[345,2102,816],{"class":408},[345,2104,2105],{"class":398},"   /*!\u003C GPIO10, input and output */\n",[345,2107,2108,2111,2113,2116,2118],{"class":347,"line":1021},[345,2109,2110],{"class":408},"    GPIO_NUM_11 ",[345,2112,930],{"class":404},[345,2114,2115],{"class":351}," 11",[345,2117,816],{"class":408},[345,2119,2120],{"class":398},"   /*!\u003C GPIO11, input and output */\n",[345,2122,2124,2127,2129,2132,2134],{"class":347,"line":2123},18,[345,2125,2126],{"class":408},"    GPIO_NUM_12 ",[345,2128,930],{"class":404},[345,2130,2131],{"class":351}," 12",[345,2133,816],{"class":408},[345,2135,2136],{"class":398},"   /*!\u003C GPIO12, input and output */\n",[345,2138,2140],{"class":347,"line":2139},19,[345,2141,2142],{"class":408},"    GPIO_NUM_MAX,\n",[345,2144,2146,2148,2150],{"class":347,"line":2145},20,[345,2147,1602],{"class":408},[345,2149,1811],{"class":351},[345,2151,936],{"class":408},[95,2153,2154],{"start":168},[98,2155,2156],{},[16,2157,2158],{},"gpio_get_level",[336,2160,2162],{"className":638,"code":2161,"language":640,"meta":341,"style":341},"int gpio_get_level(gpio_num_t gpio_num)\n{\n    return gpio_hal_get_level(gpio_context.gpio_hal, gpio_num);\n}\n",[31,2163,2164,2180,2184,2194],{"__ignoreMap":341},[345,2165,2166,2169,2172,2174,2176,2178],{"class":347,"line":348},[345,2167,2168],{"class":404},"int",[345,2170,2171],{"class":362}," gpio_get_level",[345,2173,665],{"class":408},[345,2175,1811],{"class":351},[345,2177,1814],{"class":1468},[345,2179,524],{"class":408},[345,2181,2182],{"class":347,"line":359},[345,2183,674],{"class":408},[345,2185,2186,2188,2191],{"class":347,"line":168},[345,2187,1861],{"class":404},[345,2189,2190],{"class":362}," gpio_hal_get_level",[345,2192,2193],{"class":408},"(gpio_context.gpio_hal, gpio_num);\n",[345,2195,2196],{"class":347,"line":192},[345,2197,698],{"class":408},[10,2199,2200,1874,2202,1877,2204,1616,2206,1883,2208,1886,2210],{},[31,2201,1873],{},[31,2203,1480],{},[31,2205,1880],{},[31,2207,1619],{},[31,2209,1623],{},[723,2211],{},[10,2213,2214],{},"return返回的int的數據是讀取到的電平是高還是低,0就是低,1就是高.",[24,2216,2218],{"id":2217},"led燈實戰","LED燈實戰",[10,2220,2221,2222,2225,2226],{},"兩種LED實物:\n",[37,2223],{"alt":39,"src":2224},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768393817874.webp","\n貼片LED\n",[37,2227],{"alt":39,"src":2228},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768393873412.webp",[10,2230,2231,2232,2235,2236,2239],{},"下面這個電路中IO口端是高電平的時候LED才亮.\n",[37,2233],{"alt":39,"src":2234},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768394340551.webp","\n下面這個電路中IO口端是低電平的時候LED才亮.\n",[37,2237],{"alt":39,"src":2238},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768394377192.webp","\n上面這倆缺點是電流直接走MCU,有另一種三極管的方法更加好,可以自己搜搜,或者看一下大疆STM32C板(STM32F407IGH6)的原理圖.",[10,2241,2242,2243,2246],{},"先來編寫",[31,2244,2245],{},"led.h","的代碼,這個是最小的框架,你應該學過C語言的條件編譯,這是為了讓頭文件不會重複.",[336,2248,2250],{"className":638,"code":2249,"language":640,"meta":341,"style":341},"#ifndef __LED_H_\n#define __LED_H_\n\n\n\n#endif\n",[31,2251,2252,2260,2267,2271,2275,2279],{"__ignoreMap":341},[345,2253,2254,2257],{"class":347,"line":348},[345,2255,2256],{"class":404},"#ifndef",[345,2258,2259],{"class":362}," __LED_H_\n",[345,2261,2262,2265],{"class":347,"line":359},[345,2263,2264],{"class":404},"#define",[345,2266,2259],{"class":362},[345,2268,2269],{"class":347,"line":168},[345,2270,415],{"emptyLinePlaceholder":414},[345,2272,2273],{"class":347,"line":192},[345,2274,415],{"emptyLinePlaceholder":414},[345,2276,2277],{"class":347,"line":423},[345,2278,415],{"emptyLinePlaceholder":414},[345,2280,2281],{"class":347,"line":224},[345,2282,1597],{"class":404},[10,2284,2285,2286,2288,2289,2292,2293,2296],{},"接下來繼續完善",[31,2287,2245],{},",下面這個枚舉是為了讓代碼可讀性更高,給高低電平起了個名字,",[31,2290,2291],{},"PIN_RESET","為低電平,",[31,2294,2295],{},"PIN_SET","為高電平.",[336,2298,2300],{"className":638,"code":2299,"language":640,"meta":341,"style":341},"#ifndef __LED_H_\n#define __LED_H_\n\n//包含ESP32的gpio组件的头文件\n#include \"driver/gpio.h\"\n\ntypedef enum {\n    PIN_RESET = 0,     \n    PIN_SET      \n} gpio_output_state_t;\n\nvoid led_init(void);\n\n#endif\n",[31,2301,2302,2308,2314,2318,2323,2330,2334,2342,2354,2359,2368,2372,2385,2389],{"__ignoreMap":341},[345,2303,2304,2306],{"class":347,"line":348},[345,2305,2256],{"class":404},[345,2307,2259],{"class":362},[345,2309,2310,2312],{"class":347,"line":359},[345,2311,2264],{"class":404},[345,2313,2259],{"class":362},[345,2315,2316],{"class":347,"line":168},[345,2317,415],{"emptyLinePlaceholder":414},[345,2319,2320],{"class":347,"line":192},[345,2321,2322],{"class":398},"//包含ESP32的gpio组件的头文件\n",[345,2324,2325,2327],{"class":347,"line":423},[345,2326,647],{"class":404},[345,2328,2329],{"class":355}," \"driver/gpio.h\"\n",[345,2331,2332],{"class":347,"line":224},[345,2333,415],{"emptyLinePlaceholder":414},[345,2335,2336,2338,2340],{"class":347,"line":253},[345,2337,1512],{"class":404},[345,2339,1652],{"class":404},[345,2341,1518],{"class":408},[345,2343,2344,2347,2349,2351],{"class":347,"line":481},[345,2345,2346],{"class":408},"    PIN_RESET ",[345,2348,930],{"class":404},[345,2350,933],{"class":351},[345,2352,2353],{"class":408},",     \n",[345,2355,2356],{"class":347,"line":489},[345,2357,2358],{"class":408},"    PIN_SET      \n",[345,2360,2361,2363,2366],{"class":347,"line":495},[345,2362,1602],{"class":408},[345,2364,2365],{"class":351},"gpio_output_state_t",[345,2367,936],{"class":408},[345,2369,2370],{"class":347,"line":500},[345,2371,415],{"emptyLinePlaceholder":414},[345,2373,2374,2376,2379,2381,2383],{"class":347,"line":509},[345,2375,659],{"class":404},[345,2377,2378],{"class":362}," led_init",[345,2380,665],{"class":408},[345,2382,659],{"class":404},[345,2384,693],{"class":408},[345,2386,2387],{"class":347,"line":527},[345,2388,415],{"emptyLinePlaceholder":414},[345,2390,2391],{"class":347,"line":532},[345,2392,1597],{"class":404},[10,2394,2395,2396,2399,2400,2403,2404,2407,2408,2411],{},"接下來再編寫",[31,2397,2398],{},"led.c","的內容:\n由於看我自己板子的原理圖,我的板子的IO43是LED燈的控制引腳,所以下面我初始化IO43.(我這裡只有IO43,IO44接了個普通燈,沒辦法,只能先把",[31,2401,2402],{},"menuconfig","裡的",[31,2405,2406],{},"Channel for console output","換成",[31,2409,2410],{},"none",",而你的燈不用改這個)",[336,2413,2415],{"className":638,"code":2414,"language":640,"meta":341,"style":341},"#include \"led.h\"\n\nvoid led_init(void)\n{   \n    //给结构体清零(C语言知识,要给局部变量清零,防止未被初始化的地方出现很奇怪的事情)\n    gpio_config_t gpio_init_struct = {0}; \n\n    gpio_init_struct.pin_bit_mask = (1ULL \u003C\u003C GPIO_NUM_43);    //初始化IO43\n    gpio_init_struct.mode = GPIO_MODE_OUTPUT;                 //设置为输出模式\n    gpio_init_struct.pull_up_en = GPIO_PULLUP_DISABLE;        //禁用上拉电阻\n    gpio_init_struct.pull_down_en = GPIO_PULLDOWN_DISABLE;    //禁用下拉电阻\n    gpio_init_struct.intr_type = GPIO_INTR_DISABLE;           //禁用中断\n\n    gpio_config(&gpio_init_struct);        //配置GPIO\n\n}\n",[31,2416,2417,2424,2428,2440,2445,2450,2469,2473,2497,2510,2523,2536,2549,2553,2569,2573],{"__ignoreMap":341},[345,2418,2419,2421],{"class":347,"line":348},[345,2420,647],{"class":404},[345,2422,2423],{"class":355}," \"led.h\"\n",[345,2425,2426],{"class":347,"line":359},[345,2427,415],{"emptyLinePlaceholder":414},[345,2429,2430,2432,2434,2436,2438],{"class":347,"line":168},[345,2431,659],{"class":404},[345,2433,2378],{"class":362},[345,2435,665],{"class":408},[345,2437,659],{"class":404},[345,2439,524],{"class":408},[345,2441,2442],{"class":347,"line":192},[345,2443,2444],{"class":408},"{   \n",[345,2446,2447],{"class":347,"line":423},[345,2448,2449],{"class":398},"    //给结构体清零(C语言知识,要给局部变量清零,防止未被初始化的地方出现很奇怪的事情)\n",[345,2451,2452,2455,2458,2460,2463,2466],{"class":347,"line":224},[345,2453,2454],{"class":351},"    gpio_config_t",[345,2456,2457],{"class":408}," gpio_init_struct ",[345,2459,930],{"class":404},[345,2461,2462],{"class":408}," {",[345,2464,2465],{"class":351},"0",[345,2467,2468],{"class":408},"}; \n",[345,2470,2471],{"class":347,"line":253},[345,2472,415],{"emptyLinePlaceholder":414},[345,2474,2475,2478,2480,2483,2485,2488,2491,2494],{"class":347,"line":481},[345,2476,2477],{"class":408},"    gpio_init_struct.pin_bit_mask ",[345,2479,930],{"class":404},[345,2481,2482],{"class":408}," (",[345,2484,1205],{"class":351},[345,2486,2487],{"class":404},"ULL",[345,2489,2490],{"class":404}," \u003C\u003C",[345,2492,2493],{"class":408}," GPIO_NUM_43);",[345,2495,2496],{"class":398},"    //初始化IO43\n",[345,2498,2499,2502,2504,2507],{"class":347,"line":489},[345,2500,2501],{"class":408},"    gpio_init_struct.mode ",[345,2503,930],{"class":404},[345,2505,2506],{"class":408}," GPIO_MODE_OUTPUT;",[345,2508,2509],{"class":398},"                 //设置为输出模式\n",[345,2511,2512,2515,2517,2520],{"class":347,"line":495},[345,2513,2514],{"class":408},"    gpio_init_struct.pull_up_en ",[345,2516,930],{"class":404},[345,2518,2519],{"class":408}," GPIO_PULLUP_DISABLE;",[345,2521,2522],{"class":398},"        //禁用上拉电阻\n",[345,2524,2525,2528,2530,2533],{"class":347,"line":500},[345,2526,2527],{"class":408},"    gpio_init_struct.pull_down_en ",[345,2529,930],{"class":404},[345,2531,2532],{"class":408}," GPIO_PULLDOWN_DISABLE;",[345,2534,2535],{"class":398},"    //禁用下拉电阻\n",[345,2537,2538,2541,2543,2546],{"class":347,"line":509},[345,2539,2540],{"class":408},"    gpio_init_struct.intr_type ",[345,2542,930],{"class":404},[345,2544,2545],{"class":408}," GPIO_INTR_DISABLE;",[345,2547,2548],{"class":398},"           //禁用中断\n",[345,2550,2551],{"class":347,"line":527},[345,2552,415],{"emptyLinePlaceholder":414},[345,2554,2555,2558,2560,2563,2566],{"class":347,"line":532},[345,2556,2557],{"class":362},"    gpio_config",[345,2559,665],{"class":408},[345,2561,2562],{"class":404},"&",[345,2564,2565],{"class":408},"gpio_init_struct);",[345,2567,2568],{"class":398},"        //配置GPIO\n",[345,2570,2571],{"class":347,"line":995},[345,2572,415],{"emptyLinePlaceholder":414},[345,2574,2575],{"class":347,"line":1015},[345,2576,698],{"class":408},[10,2578,2579,2580,2582,2583],{},"上面這些參數你該填什麼,都可以通過",[31,2581,1480],{},"查詢結構體類型來得知.\n不懂的詳細看看正點原子視頻怎麼查詢結構體.",[723,2584],{},[10,2586,2587,2588,1126],{},"然後再編輯一下",[31,2589,617],{},[336,2591,2593],{"className":638,"code":2592,"language":640,"meta":341,"style":341},"//包含FreeRTOS头文件(为了用vTaskDelay)\n#include \"freertos/FreeRTOS.h\"\n#include \"freertos/task.h\"\n//包含LED头文件,为了初始化LED和使用GPIO\n#include \"led.h\"\n\nvoid app_main(void)\n{\n    //初始化led的GPIO\n    led_init();\n    //死循环,等同于while(1),但效率比while(1)更高\n    for(;;)\n    {\n        gpio_set_level(GPIO_NUM_43, PIN_SET);   //设置为高电平\n        vTaskDelay(500 / portTICK_PERIOD_MS);  //延时500ms\n        gpio_set_level(GPIO_NUM_43, PIN_RESET); //设置为低电平\n        vTaskDelay(500 / portTICK_PERIOD_MS);  //延时500ms\n    }\n}\n",[31,2594,2595,2599,2605,2611,2616,2622,2626,2638,2642,2647,2655,2659,2665,2669,2680,2694,2704,2718,2722],{"__ignoreMap":341},[345,2596,2597],{"class":347,"line":348},[345,2598,901],{"class":398},[345,2600,2601,2603],{"class":347,"line":359},[345,2602,647],{"class":404},[345,2604,908],{"class":355},[345,2606,2607,2609],{"class":347,"line":168},[345,2608,647],{"class":404},[345,2610,915],{"class":355},[345,2612,2613],{"class":347,"line":192},[345,2614,2615],{"class":398},"//包含LED头文件,为了初始化LED和使用GPIO\n",[345,2617,2618,2620],{"class":347,"line":423},[345,2619,647],{"class":404},[345,2621,2423],{"class":355},[345,2623,2624],{"class":347,"line":224},[345,2625,415],{"emptyLinePlaceholder":414},[345,2627,2628,2630,2632,2634,2636],{"class":347,"line":253},[345,2629,659],{"class":404},[345,2631,662],{"class":362},[345,2633,665],{"class":408},[345,2635,659],{"class":404},[345,2637,524],{"class":408},[345,2639,2640],{"class":347,"line":481},[345,2641,674],{"class":408},[345,2643,2644],{"class":347,"line":489},[345,2645,2646],{"class":398},"    //初始化led的GPIO\n",[345,2648,2649,2652],{"class":347,"line":495},[345,2650,2651],{"class":362},"    led_init",[345,2653,2654],{"class":408},"();\n",[345,2656,2657],{"class":347,"line":500},[345,2658,969],{"class":398},[345,2660,2661,2663],{"class":347,"line":509},[345,2662,974],{"class":404},[345,2664,977],{"class":408},[345,2666,2667],{"class":347,"line":527},[345,2668,982],{"class":408},[345,2670,2671,2674,2677],{"class":347,"line":532},[345,2672,2673],{"class":362},"        gpio_set_level",[345,2675,2676],{"class":408},"(GPIO_NUM_43, PIN_SET);",[345,2678,2679],{"class":398},"   //设置为高电平\n",[345,2681,2682,2684,2686,2688,2690,2692],{"class":347,"line":995},[345,2683,998],{"class":362},[345,2685,665],{"class":408},[345,2687,1003],{"class":351},[345,2689,1006],{"class":404},[345,2691,1009],{"class":408},[345,2693,1012],{"class":398},[345,2695,2696,2698,2701],{"class":347,"line":1015},[345,2697,2673],{"class":362},[345,2699,2700],{"class":408},"(GPIO_NUM_43, PIN_RESET);",[345,2702,2703],{"class":398}," //设置为低电平\n",[345,2705,2706,2708,2710,2712,2714,2716],{"class":347,"line":1021},[345,2707,998],{"class":362},[345,2709,665],{"class":408},[345,2711,1003],{"class":351},[345,2713,1006],{"class":404},[345,2715,1009],{"class":408},[345,2717,1012],{"class":398},[345,2719,2720],{"class":347,"line":2123},[345,2721,1018],{"class":408},[345,2723,2724],{"class":347,"line":2139},[345,2725,698],{"class":408},[10,2727,2728,2729,2732,2733,2736,2737,2739,2740,2743,2744,2746,2747],{},"以上代碼會讓LED每隔1s閃爍一次.\n這裡的\n",[31,2730,2731],{},"vTaskDelay(500 / portTICK_PERIOD_MS);","其實可以簡化為",[31,2734,2735],{},"vTaskDelay(500);",",因為咱們之前配置過",[31,2738,177],{},"為1000,這樣會導致",[31,2741,2742],{},"portTICK_PERIOD_MS","的值為1.",[723,2745],{},"\n但上面的寫法更加正規,如果其他人想用你的代碼,別人也不會讓延遲跑錯單位.還是推薦不要簡化的辦法,而正點原子是簡化後的,如果別人遷移複製你的代碼,會出大問題的.",[723,2748],{},[10,2750,2751],{},"老三樣,依次摁,然後可以看到板子上的燈會閃爍.",[10,2753,2754],{},[37,2755],{"alt":39,"src":2756},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768396481018.webp",[24,2758,2760],{"id":2759},"key實戰","KEY實戰",[10,2762,2763],{},"如下是一個KEY的電路,KEY被按下就導通了.",[10,2765,2766],{},[37,2767],{"alt":39,"src":2768},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768656614098.webp",[10,2770,2771],{},"實際上按鍵按下會導致抖動,一般是機械材料,結構,環境導致.",[10,2773,2774],{},[37,2775],{"alt":39,"src":2776},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768656707523.webp",[10,2778,2779],{},"但是中間這段是正常的,如下圖",[10,2781,2782],{},[37,2783],{"alt":39,"src":2784},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768656860971.webp",[10,2786,2787],{},"日常用軟件消抖的延時法就夠了.",[10,2789,2790],{},[37,2791],{"alt":39,"src":2792},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768657220549.webp",[10,2794,2795],{},"實際接線",[10,2797,2798],{},[37,2799],{"alt":39,"src":2800},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768657369280.webp",[10,2802,2803,2804,2807,2808,1126],{},"首先先修改",[31,2805,2806],{},"BSP","文件夾裡的",[31,2809,625],{},[336,2811,2813],{"className":389,"code":2812,"language":391,"meta":341,"style":341},"set(src_dirs\n            LED\n            KEY)\n\nset(include_dirs\n            LED\n            KEY)\n\n# GPIO的一些组件在driver里\nset(requires\n            driver)\n\nidf_component_register(SRC_DIRS ${src_dirs}\n                      INCLUDE_DIRS ${include_dirs} REQUIRES ${requires})\n\ncomponent_compile_options(-ffast-math -O3 -Wno-error=format=-Wno-format)\n\n",[31,2814,2815,2821,2826,2831,2835,2841,2845,2849,2853,2857,2863,2867,2871,2877,2889,2893],{"__ignoreMap":341},[345,2816,2817,2819],{"class":347,"line":348},[345,2818,405],{"class":404},[345,2820,449],{"class":408},[345,2822,2823],{"class":347,"line":359},[345,2824,2825],{"class":408},"            LED\n",[345,2827,2828],{"class":347,"line":168},[345,2829,2830],{"class":408},"            KEY)\n",[345,2832,2833],{"class":347,"line":192},[345,2834,415],{"emptyLinePlaceholder":414},[345,2836,2837,2839],{"class":347,"line":423},[345,2838,405],{"class":404},[345,2840,465],{"class":408},[345,2842,2843],{"class":347,"line":224},[345,2844,2825],{"class":408},[345,2846,2847],{"class":347,"line":253},[345,2848,2830],{"class":408},[345,2850,2851],{"class":347,"line":481},[345,2852,415],{"emptyLinePlaceholder":414},[345,2854,2855],{"class":347,"line":489},[345,2856,478],{"class":398},[345,2858,2859,2861],{"class":347,"line":495},[345,2860,405],{"class":404},[345,2862,486],{"class":408},[345,2864,2865],{"class":347,"line":500},[345,2866,492],{"class":408},[345,2868,2869],{"class":347,"line":509},[345,2870,415],{"emptyLinePlaceholder":414},[345,2872,2873,2875],{"class":347,"line":527},[345,2874,503],{"class":408},[345,2876,506],{"class":404},[345,2878,2879,2881,2883,2885,2887],{"class":347,"line":532},[345,2880,512],{"class":408},[345,2882,515],{"class":404},[345,2884,518],{"class":408},[345,2886,521],{"class":404},[345,2888,524],{"class":408},[345,2890,2891],{"class":347,"line":995},[345,2892,415],{"emptyLinePlaceholder":414},[345,2894,2895],{"class":347,"line":1015},[345,2896,535],{"class":408},[10,2898,2899,2900,2902,2903,2906],{},"我們打開原理圖,看看按鍵是哪個引腳?,",[723,2901],{},"\n由於我的板子沒有自定義的按鍵,所以我選擇用",[31,2904,2905],{},"BOOT","的按鍵當按鍵.",[10,2908,2909],{},[37,2910],{"alt":39,"src":2911},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768658484350.webp",[10,2913,2914,2915,2918,2919,2922,2923,2925,2926,2928,2929,2931,2932],{},"如上圖,這個按鍵一邊接的",[31,2916,2917],{},"GND","一邊接的",[31,2920,2921],{},"GPIO0",",所以剛開始",[31,2924,2921],{},"這邊必須是一個高電平狀態,等按鍵按下,整條線都會被",[31,2927,2917],{},"變成低電平,故",[31,2930,2921],{},"檢測到電平由高電平變低電平,這種叫做檢測到下降沿,反之叫上升沿.",[723,2933],{},[10,2935,2936,2937,2939,2940,2942,2943],{},"我們如何讓",[31,2938,2921],{},"剛上來是高電平呢?就是要讓",[31,2941,2921],{},"要接上拉電阻.",[723,2944],{},[10,2946,2947,2948,2950,2951,2954,2955,2957],{},"反之,如果",[31,2949,2905],{},"左邊是",[31,2952,2953],{},"VCC",",那",[31,2956,2921],{},"就要下拉電阻,並檢測上升沿.",[10,2959,2960,2961,2964],{},"首先先創建",[31,2962,2963],{},"key.h","的內容",[336,2966,2968],{"className":638,"code":2967,"language":640,"meta":341,"style":341},"#ifndef __KEY_H_\n#define __KEY_H_\n\n//包含ESP32的gpio组件的头文件\n#include \"driver/gpio.h\"\n\n#define BOOT_PRES 1\n\n#endif\n",[31,2969,2970,2977,2983,2987,2991,2997,3001,3011,3015],{"__ignoreMap":341},[345,2971,2972,2974],{"class":347,"line":348},[345,2973,2256],{"class":404},[345,2975,2976],{"class":362}," __KEY_H_\n",[345,2978,2979,2981],{"class":347,"line":359},[345,2980,2264],{"class":404},[345,2982,2976],{"class":362},[345,2984,2985],{"class":347,"line":168},[345,2986,415],{"emptyLinePlaceholder":414},[345,2988,2989],{"class":347,"line":192},[345,2990,2322],{"class":398},[345,2992,2993,2995],{"class":347,"line":423},[345,2994,647],{"class":404},[345,2996,2329],{"class":355},[345,2998,2999],{"class":347,"line":224},[345,3000,415],{"emptyLinePlaceholder":414},[345,3002,3003,3005,3008],{"class":347,"line":253},[345,3004,2264],{"class":404},[345,3006,3007],{"class":362}," BOOT_PRES",[345,3009,3010],{"class":351}," 1\n",[345,3012,3013],{"class":347,"line":481},[345,3014,415],{"emptyLinePlaceholder":414},[345,3016,3017],{"class":347,"line":489},[345,3018,1597],{"class":404},[10,3020,3021,3022,3025,3026,3028,3029,793],{},"這裡的",[31,3023,3024],{},"BOOT_PRES","是一個標識,當BOOT按鍵被按下後,就會檢測到",[31,3027,3024],{},"這個值,也就是",[31,3030,1205],{},[10,3032,3033,3034,3037,3038,3041,3042,793],{},"然後在",[31,3035,3036],{},"key.c","中,首先要初始化",[31,3039,3040],{},"gpio0","的",[31,3043,1385],{},[10,3045,3046,3047,3050],{},"與",[31,3048,3049],{},"led","的差不多.但是注意,這裡的模式為輸入模式,然後要啟用上拉電阻.",[336,3052,3054],{"className":638,"code":3053,"language":640,"meta":341,"style":341},"void key_init(void)\n{   \n    //给结构体清零(C语言知识,要给局部变量清零,防止未被初始化的地方出现很奇怪的事情)\n    gpio_config_t gpio_init_struct = {0}; \n\n    gpio_init_struct.pin_bit_mask = (1ULL \u003C\u003C GPIO_NUM_0);    //初始化IO0\n    gpio_init_struct.mode = GPIO_MODE_INPUT;                 //设置为输入模式\n    gpio_init_struct.pull_up_en = GPIO_PULLUP_ENABLE;        //启用上拉电阻\n    gpio_init_struct.pull_down_en = GPIO_PULLDOWN_DISABLE;    //禁用下拉电阻\n    gpio_init_struct.intr_type = GPIO_INTR_DISABLE;           //禁用中断\n\n    gpio_config(&gpio_init_struct);        //配置GPIO\n\n}\n",[31,3055,3056,3069,3073,3077,3091,3095,3115,3127,3139,3149,3159,3163,3175,3179],{"__ignoreMap":341},[345,3057,3058,3060,3063,3065,3067],{"class":347,"line":348},[345,3059,659],{"class":404},[345,3061,3062],{"class":362}," key_init",[345,3064,665],{"class":408},[345,3066,659],{"class":404},[345,3068,524],{"class":408},[345,3070,3071],{"class":347,"line":359},[345,3072,2444],{"class":408},[345,3074,3075],{"class":347,"line":168},[345,3076,2449],{"class":398},[345,3078,3079,3081,3083,3085,3087,3089],{"class":347,"line":192},[345,3080,2454],{"class":351},[345,3082,2457],{"class":408},[345,3084,930],{"class":404},[345,3086,2462],{"class":408},[345,3088,2465],{"class":351},[345,3090,2468],{"class":408},[345,3092,3093],{"class":347,"line":423},[345,3094,415],{"emptyLinePlaceholder":414},[345,3096,3097,3099,3101,3103,3105,3107,3109,3112],{"class":347,"line":224},[345,3098,2477],{"class":408},[345,3100,930],{"class":404},[345,3102,2482],{"class":408},[345,3104,1205],{"class":351},[345,3106,2487],{"class":404},[345,3108,2490],{"class":404},[345,3110,3111],{"class":408}," GPIO_NUM_0);",[345,3113,3114],{"class":398},"    //初始化IO0\n",[345,3116,3117,3119,3121,3124],{"class":347,"line":253},[345,3118,2501],{"class":408},[345,3120,930],{"class":404},[345,3122,3123],{"class":408}," GPIO_MODE_INPUT;",[345,3125,3126],{"class":398},"                 //设置为输入模式\n",[345,3128,3129,3131,3133,3136],{"class":347,"line":481},[345,3130,2514],{"class":408},[345,3132,930],{"class":404},[345,3134,3135],{"class":408}," GPIO_PULLUP_ENABLE;",[345,3137,3138],{"class":398},"        //启用上拉电阻\n",[345,3140,3141,3143,3145,3147],{"class":347,"line":489},[345,3142,2527],{"class":408},[345,3144,930],{"class":404},[345,3146,2532],{"class":408},[345,3148,2535],{"class":398},[345,3150,3151,3153,3155,3157],{"class":347,"line":495},[345,3152,2540],{"class":408},[345,3154,930],{"class":404},[345,3156,2545],{"class":408},[345,3158,2548],{"class":398},[345,3160,3161],{"class":347,"line":500},[345,3162,415],{"emptyLinePlaceholder":414},[345,3164,3165,3167,3169,3171,3173],{"class":347,"line":509},[345,3166,2557],{"class":362},[345,3168,665],{"class":408},[345,3170,2562],{"class":404},[345,3172,2565],{"class":408},[345,3174,2568],{"class":398},[345,3176,3177],{"class":347,"line":527},[345,3178,415],{"emptyLinePlaceholder":414},[345,3180,3181],{"class":347,"line":532},[345,3182,698],{"class":408},[10,3184,3185],{},"接下來重頭戲,按鍵掃描函數,下面註釋講的很詳細,自己可以好好分析分析代碼.",[336,3187,3189],{"className":638,"code":3188,"language":640,"meta":341,"style":341},"/**\n * @brief       按键扫描函数\n * @note        无\n * @param       mode:0 / 1, 具体含义如下:\n *   @arg       0,  不支持连续按(当按键按下不放时, 只有第一次调用会返回键值,\n *                  必须松开以后, 再次按下才会返回其他键值)\n *   @arg       1,  支持连续按(当按键按下不放时, 每次调用该函数都会返回键值)\n * @retval      键值, 定义如下:\n *              BOOT_PRES, 1, BOOT按键按下\n */\nuint8_t key_scan(uint8_t mode)\n{\n    static uint8_t key_up = 1;  /* 按键按松开标志 */\n    uint8_t keyval = 0;\n\n    if (mode)       /* 支持连按 */\n    {\n        key_up = 1;\n    }\n\n    if (key_up && (gpio_get_level(GPIO_NUM_0) == 0))  /* 按键松开标志为1, 且有任意一个按键按下了 */\n    {\n        vTaskDelay(10 / portTICK_PERIOD_MS);           /* 去抖动 */\n        key_up = 0;\n\n        if (gpio_get_level(GPIO_NUM_0) == 0)  keyval = BOOT_PRES;\n\n\n    }\n    else if (gpio_get_level(GPIO_NUM_0) == 1)         /* 没有任何按键按下, 标记按键松开 */\n    {\n        key_up = 1;\n    }\n\n    return keyval;              /* 返回键值 */\n}\n",[31,3190,3191,3195,3204,3214,3227,3238,3243,3252,3262,3267,3271,3288,3292,3313,3327,3331,3342,3346,3357,3361,3365,3394,3399,3416,3427,3432,3456,3461,3466,3471,3496,3501,3512,3517,3522,3533],{"__ignoreMap":341},[345,3192,3193],{"class":347,"line":348},[345,3194,1491],{"class":398},[345,3196,3197,3199,3201],{"class":347,"line":359},[345,3198,1496],{"class":398},[345,3200,1499],{"class":404},[345,3202,3203],{"class":398},"       按键扫描函数\n",[345,3205,3206,3208,3211],{"class":347,"line":168},[345,3207,1496],{"class":398},[345,3209,3210],{"class":404},"@note",[345,3212,3213],{"class":398},"        无\n",[345,3215,3216,3218,3221,3224],{"class":347,"line":192},[345,3217,1496],{"class":398},[345,3219,3220],{"class":404},"@param",[345,3222,3223],{"class":1468},"       mode",[345,3225,3226],{"class":398},":0 / 1, 具体含义如下:\n",[345,3228,3229,3232,3235],{"class":347,"line":423},[345,3230,3231],{"class":398}," *   ",[345,3233,3234],{"class":404},"@arg",[345,3236,3237],{"class":398},"       0,  不支持连续按(当按键按下不放时, 只有第一次调用会返回键值,\n",[345,3239,3240],{"class":347,"line":224},[345,3241,3242],{"class":398}," *                  必须松开以后, 再次按下才会返回其他键值)\n",[345,3244,3245,3247,3249],{"class":347,"line":253},[345,3246,3231],{"class":398},[345,3248,3234],{"class":404},[345,3250,3251],{"class":398},"       1,  支持连续按(当按键按下不放时, 每次调用该函数都会返回键值)\n",[345,3253,3254,3256,3259],{"class":347,"line":481},[345,3255,1496],{"class":398},[345,3257,3258],{"class":404},"@retval",[345,3260,3261],{"class":398},"      键值, 定义如下:\n",[345,3263,3264],{"class":347,"line":489},[345,3265,3266],{"class":398}," *              BOOT_PRES, 1, BOOT按键按下\n",[345,3268,3269],{"class":347,"line":495},[345,3270,1507],{"class":398},[345,3272,3273,3276,3279,3281,3283,3286],{"class":347,"line":500},[345,3274,3275],{"class":404},"uint8_t",[345,3277,3278],{"class":362}," key_scan",[345,3280,665],{"class":408},[345,3282,3275],{"class":404},[345,3284,3285],{"class":1468}," mode",[345,3287,524],{"class":408},[345,3289,3290],{"class":347,"line":509},[345,3291,674],{"class":408},[345,3293,3294,3297,3300,3303,3305,3307,3310],{"class":347,"line":527},[345,3295,3296],{"class":404},"    static",[345,3298,3299],{"class":404}," uint8_t",[345,3301,3302],{"class":408}," key_up ",[345,3304,930],{"class":404},[345,3306,1965],{"class":351},[345,3308,3309],{"class":408},";",[345,3311,3312],{"class":398},"  /* 按键按松开标志 */\n",[345,3314,3315,3318,3321,3323,3325],{"class":347,"line":532},[345,3316,3317],{"class":404},"    uint8_t",[345,3319,3320],{"class":408}," keyval ",[345,3322,930],{"class":404},[345,3324,933],{"class":351},[345,3326,936],{"class":408},[345,3328,3329],{"class":347,"line":995},[345,3330,415],{"emptyLinePlaceholder":414},[345,3332,3333,3336,3339],{"class":347,"line":1015},[345,3334,3335],{"class":404},"    if",[345,3337,3338],{"class":408}," (mode)",[345,3340,3341],{"class":398},"       /* 支持连按 */\n",[345,3343,3344],{"class":347,"line":1021},[345,3345,982],{"class":408},[345,3347,3348,3351,3353,3355],{"class":347,"line":2123},[345,3349,3350],{"class":408},"        key_up ",[345,3352,930],{"class":404},[345,3354,1965],{"class":351},[345,3356,936],{"class":408},[345,3358,3359],{"class":347,"line":2139},[345,3360,1018],{"class":408},[345,3362,3363],{"class":347,"line":2145},[345,3364,415],{"emptyLinePlaceholder":414},[345,3366,3368,3370,3373,3376,3378,3380,3383,3386,3388,3391],{"class":347,"line":3367},21,[345,3369,3335],{"class":404},[345,3371,3372],{"class":408}," (key_up ",[345,3374,3375],{"class":404},"&&",[345,3377,2482],{"class":408},[345,3379,2158],{"class":362},[345,3381,3382],{"class":408},"(GPIO_NUM_0) ",[345,3384,3385],{"class":404},"==",[345,3387,933],{"class":351},[345,3389,3390],{"class":408},"))",[345,3392,3393],{"class":398},"  /* 按键松开标志为1, 且有任意一个按键按下了 */\n",[345,3395,3397],{"class":347,"line":3396},22,[345,3398,982],{"class":408},[345,3400,3402,3404,3406,3409,3411,3413],{"class":347,"line":3401},23,[345,3403,998],{"class":362},[345,3405,665],{"class":408},[345,3407,3408],{"class":351},"10",[345,3410,1006],{"class":404},[345,3412,1009],{"class":408},[345,3414,3415],{"class":398},"           /* 去抖动 */\n",[345,3417,3419,3421,3423,3425],{"class":347,"line":3418},24,[345,3420,3350],{"class":408},[345,3422,930],{"class":404},[345,3424,933],{"class":351},[345,3426,936],{"class":408},[345,3428,3430],{"class":347,"line":3429},25,[345,3431,415],{"emptyLinePlaceholder":414},[345,3433,3435,3438,3440,3442,3444,3446,3448,3451,3453],{"class":347,"line":3434},26,[345,3436,3437],{"class":404},"        if",[345,3439,2482],{"class":408},[345,3441,2158],{"class":362},[345,3443,3382],{"class":408},[345,3445,3385],{"class":404},[345,3447,933],{"class":351},[345,3449,3450],{"class":408},")  keyval ",[345,3452,930],{"class":404},[345,3454,3455],{"class":408}," BOOT_PRES;\n",[345,3457,3459],{"class":347,"line":3458},27,[345,3460,415],{"emptyLinePlaceholder":414},[345,3462,3464],{"class":347,"line":3463},28,[345,3465,415],{"emptyLinePlaceholder":414},[345,3467,3469],{"class":347,"line":3468},29,[345,3470,1018],{"class":408},[345,3472,3474,3477,3480,3482,3484,3486,3488,3490,3493],{"class":347,"line":3473},30,[345,3475,3476],{"class":404},"    else",[345,3478,3479],{"class":404}," if",[345,3481,2482],{"class":408},[345,3483,2158],{"class":362},[345,3485,3382],{"class":408},[345,3487,3385],{"class":404},[345,3489,1965],{"class":351},[345,3491,3492],{"class":408},")",[345,3494,3495],{"class":398},"         /* 没有任何按键按下, 标记按键松开 */\n",[345,3497,3499],{"class":347,"line":3498},31,[345,3500,982],{"class":408},[345,3502,3504,3506,3508,3510],{"class":347,"line":3503},32,[345,3505,3350],{"class":408},[345,3507,930],{"class":404},[345,3509,1965],{"class":351},[345,3511,936],{"class":408},[345,3513,3515],{"class":347,"line":3514},33,[345,3516,1018],{"class":408},[345,3518,3520],{"class":347,"line":3519},34,[345,3521,415],{"emptyLinePlaceholder":414},[345,3523,3525,3527,3530],{"class":347,"line":3524},35,[345,3526,1861],{"class":404},[345,3528,3529],{"class":408}," keyval;",[345,3531,3532],{"class":398},"              /* 返回键值 */\n",[345,3534,3536],{"class":347,"line":3535},36,[345,3537,698],{"class":408},[10,3539,3540,3541,3544],{},"主要是用了",[31,3542,3543],{},"int gpio_get_level(gpio_num_t gpio_num)","這麼一個函數,在第一節裡我們講過這個api了.",[336,3546,3547],{"className":638,"code":2161,"language":640,"meta":341,"style":341},[31,3548,3549,3563,3567,3575],{"__ignoreMap":341},[345,3550,3551,3553,3555,3557,3559,3561],{"class":347,"line":348},[345,3552,2168],{"class":404},[345,3554,2171],{"class":362},[345,3556,665],{"class":408},[345,3558,1811],{"class":351},[345,3560,1814],{"class":1468},[345,3562,524],{"class":408},[345,3564,3565],{"class":347,"line":359},[345,3566,674],{"class":408},[345,3568,3569,3571,3573],{"class":347,"line":168},[345,3570,1861],{"class":404},[345,3572,2190],{"class":362},[345,3574,2193],{"class":408},[345,3576,3577],{"class":347,"line":192},[345,3578,698],{"class":408},[10,3580,3581],{},"然後還要在定義一個全局變量當作按鍵的變量,存儲按鍵的結果.",[336,3583,3585],{"className":638,"code":3584,"language":640,"meta":341,"style":341},"uint8_t key_value = 0;\n",[31,3586,3587],{"__ignoreMap":341},[345,3588,3589,3591,3594,3596,3598],{"class":347,"line":348},[345,3590,3275],{"class":404},[345,3592,3593],{"class":408}," key_value ",[345,3595,930],{"class":404},[345,3597,933],{"class":351},[345,3599,936],{"class":408},[10,3601,3602,3603,3605],{},"在",[31,3604,617],{},"裡寫主要邏輯,就是當按鍵被按下,則翻轉電平.",[336,3607,3609],{"className":638,"code":3608,"language":640,"meta":341,"style":341},"//包含FreeRTOS头文件(为了用vTaskDelay)\n#include \"freertos/FreeRTOS.h\"\n#include \"freertos/task.h\"\n//包含LED头文件,为了初始化LED和使用GPIO\n#include \"led.h\"\n//包含KEY头文件,为了初始化KEY和使用GPIO\n#include \"key.h\"\n\n//按键外部变量声明;\nextern uint8_t key_value;\n\n\nvoid app_main(void)\n{\n    //初始化led的GPIO\n    led_init();\n    //初始化key的GPIO\n    key_init();\n\n    //死循环,等同于while(1),但效率比while(1)更高\n    for(;;)\n    {\n        key_value = key_scan(0);\n\n        switch (key_value)\n        {\n        case BOOT_PRES:\n            gpio_set_level(GPIO_NUM_43, !gpio_get_level(GPIO_NUM_43));   //翻转电平\n            break;\n        \n        default:\n            break;\n        }\n\n        vTaskDelay(10 / portTICK_PERIOD_MS);  //延时10ms\n    }\n}\n",[31,3610,3611,3615,3621,3627,3631,3637,3642,3649,3653,3658,3668,3672,3676,3688,3692,3696,3702,3707,3714,3718,3722,3728,3732,3747,3751,3759,3764,3772,3790,3797,3802,3810,3816,3821,3825,3840,3844],{"__ignoreMap":341},[345,3612,3613],{"class":347,"line":348},[345,3614,901],{"class":398},[345,3616,3617,3619],{"class":347,"line":359},[345,3618,647],{"class":404},[345,3620,908],{"class":355},[345,3622,3623,3625],{"class":347,"line":168},[345,3624,647],{"class":404},[345,3626,915],{"class":355},[345,3628,3629],{"class":347,"line":192},[345,3630,2615],{"class":398},[345,3632,3633,3635],{"class":347,"line":423},[345,3634,647],{"class":404},[345,3636,2423],{"class":355},[345,3638,3639],{"class":347,"line":224},[345,3640,3641],{"class":398},"//包含KEY头文件,为了初始化KEY和使用GPIO\n",[345,3643,3644,3646],{"class":347,"line":253},[345,3645,647],{"class":404},[345,3647,3648],{"class":355}," \"key.h\"\n",[345,3650,3651],{"class":347,"line":481},[345,3652,415],{"emptyLinePlaceholder":414},[345,3654,3655],{"class":347,"line":489},[345,3656,3657],{"class":398},"//按键外部变量声明;\n",[345,3659,3660,3663,3665],{"class":347,"line":495},[345,3661,3662],{"class":404},"extern",[345,3664,3299],{"class":404},[345,3666,3667],{"class":408}," key_value;\n",[345,3669,3670],{"class":347,"line":500},[345,3671,415],{"emptyLinePlaceholder":414},[345,3673,3674],{"class":347,"line":509},[345,3675,415],{"emptyLinePlaceholder":414},[345,3677,3678,3680,3682,3684,3686],{"class":347,"line":527},[345,3679,659],{"class":404},[345,3681,662],{"class":362},[345,3683,665],{"class":408},[345,3685,659],{"class":404},[345,3687,524],{"class":408},[345,3689,3690],{"class":347,"line":532},[345,3691,674],{"class":408},[345,3693,3694],{"class":347,"line":995},[345,3695,2646],{"class":398},[345,3697,3698,3700],{"class":347,"line":1015},[345,3699,2651],{"class":362},[345,3701,2654],{"class":408},[345,3703,3704],{"class":347,"line":1021},[345,3705,3706],{"class":398},"    //初始化key的GPIO\n",[345,3708,3709,3712],{"class":347,"line":2123},[345,3710,3711],{"class":362},"    key_init",[345,3713,2654],{"class":408},[345,3715,3716],{"class":347,"line":2139},[345,3717,415],{"emptyLinePlaceholder":414},[345,3719,3720],{"class":347,"line":2145},[345,3721,969],{"class":398},[345,3723,3724,3726],{"class":347,"line":3367},[345,3725,974],{"class":404},[345,3727,977],{"class":408},[345,3729,3730],{"class":347,"line":3396},[345,3731,982],{"class":408},[345,3733,3734,3737,3739,3741,3743,3745],{"class":347,"line":3401},[345,3735,3736],{"class":408},"        key_value ",[345,3738,930],{"class":404},[345,3740,3278],{"class":362},[345,3742,665],{"class":408},[345,3744,2465],{"class":351},[345,3746,693],{"class":408},[345,3748,3749],{"class":347,"line":3418},[345,3750,415],{"emptyLinePlaceholder":414},[345,3752,3753,3756],{"class":347,"line":3429},[345,3754,3755],{"class":404},"        switch",[345,3757,3758],{"class":408}," (key_value)\n",[345,3760,3761],{"class":347,"line":3434},[345,3762,3763],{"class":408},"        {\n",[345,3765,3766,3769],{"class":347,"line":3458},[345,3767,3768],{"class":404},"        case",[345,3770,3771],{"class":408}," BOOT_PRES:\n",[345,3773,3774,3777,3780,3782,3784,3787],{"class":347,"line":3463},[345,3775,3776],{"class":362},"            gpio_set_level",[345,3778,3779],{"class":408},"(GPIO_NUM_43, ",[345,3781,1159],{"class":404},[345,3783,2158],{"class":362},[345,3785,3786],{"class":408},"(GPIO_NUM_43));",[345,3788,3789],{"class":398},"   //翻转电平\n",[345,3791,3792,3795],{"class":347,"line":3468},[345,3793,3794],{"class":404},"            break",[345,3796,936],{"class":408},[345,3798,3799],{"class":347,"line":3473},[345,3800,3801],{"class":408},"        \n",[345,3803,3804,3807],{"class":347,"line":3498},[345,3805,3806],{"class":404},"        default",[345,3808,3809],{"class":408},":\n",[345,3811,3812,3814],{"class":347,"line":3503},[345,3813,3794],{"class":404},[345,3815,936],{"class":408},[345,3817,3818],{"class":347,"line":3514},[345,3819,3820],{"class":408},"        }\n",[345,3822,3823],{"class":347,"line":3519},[345,3824,415],{"emptyLinePlaceholder":414},[345,3826,3827,3829,3831,3833,3835,3837],{"class":347,"line":3524},[345,3828,998],{"class":362},[345,3830,665],{"class":408},[345,3832,3408],{"class":351},[345,3834,1006],{"class":404},[345,3836,1009],{"class":408},[345,3838,3839],{"class":398},"  //延时10ms\n",[345,3841,3842],{"class":347,"line":3535},[345,3843,1018],{"class":408},[345,3845,3847],{"class":347,"line":3846},37,[345,3848,698],{"class":408},[10,3850,3851,3852,3854,3855,3857],{},"下面是",[31,3853,2963],{},"和",[31,3856,3036],{},"完整內容:",[336,3859,3861],{"className":638,"code":3860,"language":640,"meta":341,"style":341},"#include \"key.h\"\n\n//包含FreeRTOS头文件(为了用vTaskDelay)\n#include \"freertos/FreeRTOS.h\"\n#include \"freertos/task.h\"\n\n\nuint8_t key_value = 0;\n\nvoid key_init(void)\n{   \n    //给结构体清零(C语言知识,要给局部变量清零,防止未被初始化的地方出现很奇怪的事情)\n    gpio_config_t gpio_init_struct = {0}; \n\n    gpio_init_struct.pin_bit_mask = (1ULL \u003C\u003C GPIO_NUM_0);    //初始化IO0\n    gpio_init_struct.mode = GPIO_MODE_INPUT;                 //设置为输入模式\n    gpio_init_struct.pull_up_en = GPIO_PULLUP_ENABLE;        //启用上拉电阻\n    gpio_init_struct.pull_down_en = GPIO_PULLDOWN_DISABLE;    //禁用下拉电阻\n    gpio_init_struct.intr_type = GPIO_INTR_DISABLE;           //禁用中断\n\n    gpio_config(&gpio_init_struct);        //配置GPIO\n\n}\n\n\n/**\n * @brief       按键扫描函数\n * @note        无\n * @param       mode:0 / 1, 具体含义如下:\n *   @arg       0,  不支持连续按(当按键按下不放时, 只有第一次调用会返回键值,\n *                  必须松开以后, 再次按下才会返回其他键值)\n *   @arg       1,  支持连续按(当按键按下不放时, 每次调用该函数都会返回键值)\n * @retval      键值, 定义如下:\n *              BOOT_PRES, 1, BOOT按键按下\n */\nuint8_t key_scan(uint8_t mode)\n{\n    static uint8_t key_up = 1;  /* 按键按松开标志 */\n    uint8_t keyval = 0;\n\n    if (mode)       /* 支持连按 */\n    {\n        key_up = 1;\n    }\n\n    if (key_up && (gpio_get_level(GPIO_NUM_0) == 0))  /* 按键松开标志为1, 且有任意一个按键按下了 */\n    {\n        vTaskDelay(10 / portTICK_PERIOD_MS);           /* 去抖动 */\n        key_up = 0;\n\n        if (gpio_get_level(GPIO_NUM_0) == 0)  keyval = BOOT_PRES;\n\n\n    }\n    else if (gpio_get_level(GPIO_NUM_0) == 1)         /* 没有任何按键按下, 标记按键松开 */\n    {\n        key_up = 1;\n    }\n\n    return keyval;              /* 返回键值 */\n}\n",[31,3862,3863,3869,3873,3877,3883,3889,3893,3897,3909,3913,3925,3929,3933,3947,3951,3969,3979,3989,3999,4009,4013,4025,4029,4033,4037,4041,4045,4053,4061,4071,4079,4083,4091,4099,4103,4107,4121,4125,4142,4155,4160,4169,4174,4185,4190,4195,4218,4223,4238,4249,4254,4275,4280,4285,4290,4311,4316,4327,4332,4337,4346],{"__ignoreMap":341},[345,3864,3865,3867],{"class":347,"line":348},[345,3866,647],{"class":404},[345,3868,3648],{"class":355},[345,3870,3871],{"class":347,"line":359},[345,3872,415],{"emptyLinePlaceholder":414},[345,3874,3875],{"class":347,"line":168},[345,3876,901],{"class":398},[345,3878,3879,3881],{"class":347,"line":192},[345,3880,647],{"class":404},[345,3882,908],{"class":355},[345,3884,3885,3887],{"class":347,"line":423},[345,3886,647],{"class":404},[345,3888,915],{"class":355},[345,3890,3891],{"class":347,"line":224},[345,3892,415],{"emptyLinePlaceholder":414},[345,3894,3895],{"class":347,"line":253},[345,3896,415],{"emptyLinePlaceholder":414},[345,3898,3899,3901,3903,3905,3907],{"class":347,"line":481},[345,3900,3275],{"class":404},[345,3902,3593],{"class":408},[345,3904,930],{"class":404},[345,3906,933],{"class":351},[345,3908,936],{"class":408},[345,3910,3911],{"class":347,"line":489},[345,3912,415],{"emptyLinePlaceholder":414},[345,3914,3915,3917,3919,3921,3923],{"class":347,"line":495},[345,3916,659],{"class":404},[345,3918,3062],{"class":362},[345,3920,665],{"class":408},[345,3922,659],{"class":404},[345,3924,524],{"class":408},[345,3926,3927],{"class":347,"line":500},[345,3928,2444],{"class":408},[345,3930,3931],{"class":347,"line":509},[345,3932,2449],{"class":398},[345,3934,3935,3937,3939,3941,3943,3945],{"class":347,"line":527},[345,3936,2454],{"class":351},[345,3938,2457],{"class":408},[345,3940,930],{"class":404},[345,3942,2462],{"class":408},[345,3944,2465],{"class":351},[345,3946,2468],{"class":408},[345,3948,3949],{"class":347,"line":532},[345,3950,415],{"emptyLinePlaceholder":414},[345,3952,3953,3955,3957,3959,3961,3963,3965,3967],{"class":347,"line":995},[345,3954,2477],{"class":408},[345,3956,930],{"class":404},[345,3958,2482],{"class":408},[345,3960,1205],{"class":351},[345,3962,2487],{"class":404},[345,3964,2490],{"class":404},[345,3966,3111],{"class":408},[345,3968,3114],{"class":398},[345,3970,3971,3973,3975,3977],{"class":347,"line":1015},[345,3972,2501],{"class":408},[345,3974,930],{"class":404},[345,3976,3123],{"class":408},[345,3978,3126],{"class":398},[345,3980,3981,3983,3985,3987],{"class":347,"line":1021},[345,3982,2514],{"class":408},[345,3984,930],{"class":404},[345,3986,3135],{"class":408},[345,3988,3138],{"class":398},[345,3990,3991,3993,3995,3997],{"class":347,"line":2123},[345,3992,2527],{"class":408},[345,3994,930],{"class":404},[345,3996,2532],{"class":408},[345,3998,2535],{"class":398},[345,4000,4001,4003,4005,4007],{"class":347,"line":2139},[345,4002,2540],{"class":408},[345,4004,930],{"class":404},[345,4006,2545],{"class":408},[345,4008,2548],{"class":398},[345,4010,4011],{"class":347,"line":2145},[345,4012,415],{"emptyLinePlaceholder":414},[345,4014,4015,4017,4019,4021,4023],{"class":347,"line":3367},[345,4016,2557],{"class":362},[345,4018,665],{"class":408},[345,4020,2562],{"class":404},[345,4022,2565],{"class":408},[345,4024,2568],{"class":398},[345,4026,4027],{"class":347,"line":3396},[345,4028,415],{"emptyLinePlaceholder":414},[345,4030,4031],{"class":347,"line":3401},[345,4032,698],{"class":408},[345,4034,4035],{"class":347,"line":3418},[345,4036,415],{"emptyLinePlaceholder":414},[345,4038,4039],{"class":347,"line":3429},[345,4040,415],{"emptyLinePlaceholder":414},[345,4042,4043],{"class":347,"line":3434},[345,4044,1491],{"class":398},[345,4046,4047,4049,4051],{"class":347,"line":3458},[345,4048,1496],{"class":398},[345,4050,1499],{"class":404},[345,4052,3203],{"class":398},[345,4054,4055,4057,4059],{"class":347,"line":3463},[345,4056,1496],{"class":398},[345,4058,3210],{"class":404},[345,4060,3213],{"class":398},[345,4062,4063,4065,4067,4069],{"class":347,"line":3468},[345,4064,1496],{"class":398},[345,4066,3220],{"class":404},[345,4068,3223],{"class":1468},[345,4070,3226],{"class":398},[345,4072,4073,4075,4077],{"class":347,"line":3473},[345,4074,3231],{"class":398},[345,4076,3234],{"class":404},[345,4078,3237],{"class":398},[345,4080,4081],{"class":347,"line":3498},[345,4082,3242],{"class":398},[345,4084,4085,4087,4089],{"class":347,"line":3503},[345,4086,3231],{"class":398},[345,4088,3234],{"class":404},[345,4090,3251],{"class":398},[345,4092,4093,4095,4097],{"class":347,"line":3514},[345,4094,1496],{"class":398},[345,4096,3258],{"class":404},[345,4098,3261],{"class":398},[345,4100,4101],{"class":347,"line":3519},[345,4102,3266],{"class":398},[345,4104,4105],{"class":347,"line":3524},[345,4106,1507],{"class":398},[345,4108,4109,4111,4113,4115,4117,4119],{"class":347,"line":3535},[345,4110,3275],{"class":404},[345,4112,3278],{"class":362},[345,4114,665],{"class":408},[345,4116,3275],{"class":404},[345,4118,3285],{"class":1468},[345,4120,524],{"class":408},[345,4122,4123],{"class":347,"line":3846},[345,4124,674],{"class":408},[345,4126,4128,4130,4132,4134,4136,4138,4140],{"class":347,"line":4127},38,[345,4129,3296],{"class":404},[345,4131,3299],{"class":404},[345,4133,3302],{"class":408},[345,4135,930],{"class":404},[345,4137,1965],{"class":351},[345,4139,3309],{"class":408},[345,4141,3312],{"class":398},[345,4143,4145,4147,4149,4151,4153],{"class":347,"line":4144},39,[345,4146,3317],{"class":404},[345,4148,3320],{"class":408},[345,4150,930],{"class":404},[345,4152,933],{"class":351},[345,4154,936],{"class":408},[345,4156,4158],{"class":347,"line":4157},40,[345,4159,415],{"emptyLinePlaceholder":414},[345,4161,4163,4165,4167],{"class":347,"line":4162},41,[345,4164,3335],{"class":404},[345,4166,3338],{"class":408},[345,4168,3341],{"class":398},[345,4170,4172],{"class":347,"line":4171},42,[345,4173,982],{"class":408},[345,4175,4177,4179,4181,4183],{"class":347,"line":4176},43,[345,4178,3350],{"class":408},[345,4180,930],{"class":404},[345,4182,1965],{"class":351},[345,4184,936],{"class":408},[345,4186,4188],{"class":347,"line":4187},44,[345,4189,1018],{"class":408},[345,4191,4193],{"class":347,"line":4192},45,[345,4194,415],{"emptyLinePlaceholder":414},[345,4196,4198,4200,4202,4204,4206,4208,4210,4212,4214,4216],{"class":347,"line":4197},46,[345,4199,3335],{"class":404},[345,4201,3372],{"class":408},[345,4203,3375],{"class":404},[345,4205,2482],{"class":408},[345,4207,2158],{"class":362},[345,4209,3382],{"class":408},[345,4211,3385],{"class":404},[345,4213,933],{"class":351},[345,4215,3390],{"class":408},[345,4217,3393],{"class":398},[345,4219,4221],{"class":347,"line":4220},47,[345,4222,982],{"class":408},[345,4224,4226,4228,4230,4232,4234,4236],{"class":347,"line":4225},48,[345,4227,998],{"class":362},[345,4229,665],{"class":408},[345,4231,3408],{"class":351},[345,4233,1006],{"class":404},[345,4235,1009],{"class":408},[345,4237,3415],{"class":398},[345,4239,4241,4243,4245,4247],{"class":347,"line":4240},49,[345,4242,3350],{"class":408},[345,4244,930],{"class":404},[345,4246,933],{"class":351},[345,4248,936],{"class":408},[345,4250,4252],{"class":347,"line":4251},50,[345,4253,415],{"emptyLinePlaceholder":414},[345,4255,4257,4259,4261,4263,4265,4267,4269,4271,4273],{"class":347,"line":4256},51,[345,4258,3437],{"class":404},[345,4260,2482],{"class":408},[345,4262,2158],{"class":362},[345,4264,3382],{"class":408},[345,4266,3385],{"class":404},[345,4268,933],{"class":351},[345,4270,3450],{"class":408},[345,4272,930],{"class":404},[345,4274,3455],{"class":408},[345,4276,4278],{"class":347,"line":4277},52,[345,4279,415],{"emptyLinePlaceholder":414},[345,4281,4283],{"class":347,"line":4282},53,[345,4284,415],{"emptyLinePlaceholder":414},[345,4286,4288],{"class":347,"line":4287},54,[345,4289,1018],{"class":408},[345,4291,4293,4295,4297,4299,4301,4303,4305,4307,4309],{"class":347,"line":4292},55,[345,4294,3476],{"class":404},[345,4296,3479],{"class":404},[345,4298,2482],{"class":408},[345,4300,2158],{"class":362},[345,4302,3382],{"class":408},[345,4304,3385],{"class":404},[345,4306,1965],{"class":351},[345,4308,3492],{"class":408},[345,4310,3495],{"class":398},[345,4312,4314],{"class":347,"line":4313},56,[345,4315,982],{"class":408},[345,4317,4319,4321,4323,4325],{"class":347,"line":4318},57,[345,4320,3350],{"class":408},[345,4322,930],{"class":404},[345,4324,1965],{"class":351},[345,4326,936],{"class":408},[345,4328,4330],{"class":347,"line":4329},58,[345,4331,1018],{"class":408},[345,4333,4335],{"class":347,"line":4334},59,[345,4336,415],{"emptyLinePlaceholder":414},[345,4338,4340,4342,4344],{"class":347,"line":4339},60,[345,4341,1861],{"class":404},[345,4343,3529],{"class":408},[345,4345,3532],{"class":398},[345,4347,4349],{"class":347,"line":4348},61,[345,4350,698],{"class":408},[336,4352,4354],{"className":638,"code":4353,"language":640,"meta":341,"style":341},"#ifndef __KEY_H_\n#define __KEY_H_\n\n//包含ESP32的gpio组件的头文件\n#include \"driver/gpio.h\"\n\n#define BOOT_PRES 1\n\nvoid key_init(void);\n\nuint8_t key_scan(uint8_t mode);\n\n#endif\n",[31,4355,4356,4362,4368,4372,4376,4382,4386,4394,4398,4410,4414,4428,4432],{"__ignoreMap":341},[345,4357,4358,4360],{"class":347,"line":348},[345,4359,2256],{"class":404},[345,4361,2976],{"class":362},[345,4363,4364,4366],{"class":347,"line":359},[345,4365,2264],{"class":404},[345,4367,2976],{"class":362},[345,4369,4370],{"class":347,"line":168},[345,4371,415],{"emptyLinePlaceholder":414},[345,4373,4374],{"class":347,"line":192},[345,4375,2322],{"class":398},[345,4377,4378,4380],{"class":347,"line":423},[345,4379,647],{"class":404},[345,4381,2329],{"class":355},[345,4383,4384],{"class":347,"line":224},[345,4385,415],{"emptyLinePlaceholder":414},[345,4387,4388,4390,4392],{"class":347,"line":253},[345,4389,2264],{"class":404},[345,4391,3007],{"class":362},[345,4393,3010],{"class":351},[345,4395,4396],{"class":347,"line":481},[345,4397,415],{"emptyLinePlaceholder":414},[345,4399,4400,4402,4404,4406,4408],{"class":347,"line":489},[345,4401,659],{"class":404},[345,4403,3062],{"class":362},[345,4405,665],{"class":408},[345,4407,659],{"class":404},[345,4409,693],{"class":408},[345,4411,4412],{"class":347,"line":495},[345,4413,415],{"emptyLinePlaceholder":414},[345,4415,4416,4418,4420,4422,4424,4426],{"class":347,"line":500},[345,4417,3275],{"class":404},[345,4419,3278],{"class":362},[345,4421,665],{"class":408},[345,4423,3275],{"class":404},[345,4425,3285],{"class":1468},[345,4427,693],{"class":408},[345,4429,4430],{"class":347,"line":509},[345,4431,415],{"emptyLinePlaceholder":414},[345,4433,4434],{"class":347,"line":527},[345,4435,1597],{"class":404},[10,4437,4438],{},"編譯後無報錯",[10,4440,4441],{},[37,4442],{"alt":39,"src":4443},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768660585328.webp",[10,4445,4446],{},[37,4447],{"alt":39,"src":4448},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768660637408.webp",[10,4450,4451,4452],{},"可以測試下,當按下按鍵的時候,LED燈會翻轉電平.",[723,4453],{},[10,4455,4456,4457,4460,4461,4464,4465],{},"還有一個測試方法,可以用debug來監視",[31,4458,4459],{},"key_value","的值,但要求你把按鍵掃描模式改成支持長按,上面的代碼只需要改",[31,4462,4463],{},"key_value = key_scan(1);","這一行.",[723,4466],{},[10,4468,4469,4470],{},"你可以進入debug測試一下,\n在下圖打斷點,然後當你摁住按鍵點繼續運行的時候,他的監視值會變成1,當你鬆開的時候按繼續運行,會變成0.\n",[37,4471],{"alt":39,"src":4472},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768660931005.webp",[10,4474,4475],{},[37,4476],{"alt":39,"src":4477},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768661121990.webp",[24,4479,4480],{"id":4480},"外部中斷",[1088,4482,4483],{"id":4483},"中斷簡介",[10,4485,4486,4487,4490,4491,4494,4495,4498,4499,4502,4503,793],{},"在上一節裡,我們在",[31,4488,4489],{},"app_main","裡的死循環裡一直跑按鍵掃描函數的方式其實叫做",[31,4492,4493],{},"轮询",",這類函數叫做",[31,4496,4497],{},"阻塞式函数",",如果你學過STM32,你肯定深有體會什麼是",[31,4500,4501],{},"阻塞式",",什麼是",[31,4504,4505],{},"中断式",[10,4507,4508],{},[37,4509],{"alt":39,"src":4510},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768661633882.webp",[10,4512,4513],{},[37,4514],{"alt":39,"src":4515},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768662329097.webp",[10,4517,4518],{},"中斷運行的過程到底是什麼樣的,請看下面這個鏈接裡的介紹,看完中斷運行過程即可,其他的都是STM32的東西不用看.",[4520,4521,4523],"nuxt-link",{"to":4522},"/wiki/2023-10-09-stm32-freertos-jiao-cheng/ch4-stm32-dan-pian-ji-zhong-dian#中斷服務函數的介紹","\n中斷服務函數的介紹\n",[1088,4525,4526],{"id":4526},"外部中斷簡介",[10,4528,4529,4530],{},"由上面這個鏈接你會明白,外部中斷EXIT只是中斷IT裡的其中一種,我們這一節詳細講講外部中斷.",[723,4531],{},[10,4533,4534],{},[37,4535],{"alt":39,"src":4536},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768662540872.webp",[10,4538,4539,4540],{},"ESP32的EXIT比STM32要多一個電平觸發的模式.",[723,4541],{},[10,4543,4544,4545,4547,4548],{},"電平觸發：高、低電平觸發，要求保持中斷的電平狀態直到 CPU 響應。",[723,4546],{},"\n邊沿觸發：上升沿和下降沿觸發，這類型的中斷一旦觸發，CPU 即可響應。",[723,4549],{},[10,4551,4552],{},"ESP32S3 的外部中斷功能能夠以非常精確的方式捕捉外部事件的觸發。開發者可以通過配\n置中斷觸發方式（如上升沿、下降沿、任意電平、低電平保持、高電平保持等）來適應不同的\n外部事件，並在事件發生時立即中斷當前程序的執行，轉而執行中斷服務函數。",[1088,4554,4555],{"id":4555},"中斷優先級",[10,4557,4558,4559],{},"當多箇中斷同時觸發的時候,CPU執行中斷也是有順序的,先執行優先級高的中斷,再執行優先級低的中斷.",[723,4560],{},[10,4562,4563,4564,4567],{},"ESP32-S3 支持六級中斷，同時支持中斷嵌套，也就是優先級中斷可以被高優先級中斷打斷。\n如下表中的優先級一欄，",[16,4565,4566],{},"數字越大表明該中斷的優先級越高","。其中，NMI 中斷擁有最高\n優先級，此類中斷已經觸發，CPU 必須處理。",[10,4569,4570],{},[37,4571],{"alt":39,"src":4572},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768664741979.webp",[10,4574,4575],{},"在 ESP32S3 中，中斷系統被用於響應各種內部和外部事件。這些中斷按照其觸發方式和優\n先級進行分類。上表詳細列出了 ESP32S3 的中斷號、類別、種類以及相應的優先級。通過配置\n這些中斷，開發者可以實現對各種事件的及時響應和處理，提高系統的效率和實時性。",[95,4577,4578,4581,4584,4587],{},[98,4579,4580],{},"中斷號：每個中斷的唯一標識符，用於在程序中引用和配置特定的中斷。",[98,4582,4583],{},"類別：中斷的來源類型，分為外部中斷和內部中斷。外部中斷由外部設備或信號觸發，\n如按鍵、傳感器等；內部中斷則由微控制器內部的硬件事件觸發，如定時器溢出、軟件中斷等。",[98,4585,4586],{},"種類：中斷的觸發方式，包括電平觸發和邊沿觸發。電平觸發是在輸入信號達到特定\n電平（如高電平或低電平）時觸發中斷；邊沿觸發則是在輸入信號從一種電平狀態變化到另一\n種狀態時觸發中斷。",[98,4588,4589],{},"優先級：中斷的響應優先級。當多箇中斷同時發生時，微控制器會根據中斷的優先級\n來決定先處理哪個中斷。較高的優先級意味著中斷將優先得到處理。\n在開發過程中，開發者可以根據實際需求配置中斷的觸發方式、優先級等參數，以實現高\n效、可靠的事件處理機制。",[1088,4591,4592],{"id":4592},"外部中斷實戰",[10,4594,4595],{},[37,4596],{"alt":39,"src":4597},"https://cdn.tungchiahui.cn/tungwebsite/assets/images/2026/01/07/1768664939827.webp",[4599,4600,4601],"style",{},"html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":341,"searchDepth":359,"depth":359,"links":4603},[4604,4605,4606,4607,4608,4609],{"id":22,"depth":168,"text":22},{"id":272,"depth":168,"text":272},{"id":298,"depth":168,"text":298},{"id":628,"depth":168,"text":629},{"id":1343,"depth":168,"text":1344},{"id":1385,"depth":168,"text":1386},"/zh-tw/wiki/2026-01-07-esp32-jiao-cheng/ch4-jiao-cheng","4",4000000,"2026-01-07","wiki/2026-01-07-esp32-jiao-cheng","zh-tw:2026-01-07-esp32-jiao-cheng","/zh-tw/wiki/2026-01-07-esp32-jiao-cheng","ESP32教程","md","wiki/2026-01-07-ESP32教程/ch4-教程",false,null,"zh-TW","zh-tw",{},{"title":5,"description":12},"/wiki/2026-01-07-esp32-jiao-cheng/ch4-jiao-cheng","_i18n/zh-tw/wiki/2026-01-07-ESP32教程/ch4-教程","_KpZVEnlQLm5-4mTAgTDVwKcm9XYw4yHhg-l3W6IZXU",[4630,4635,4641,4647,4648],{"path":4631,"stem":4632,"title":4633,"date":4613,"chapter":1205,"chapterSort":4634,"docKey":4615,"docRoot":4616,"docTitle":4617,"isWikiDoc":414,"isWikiIndex":4620},"/zh-tw/wiki/2026-01-07-esp32-jiao-cheng/ch1-jian-jie","_i18n/zh-tw/wiki/2026-01-07-ESP32教程/ch1-简介","簡介",1000000,{"path":4636,"stem":4637,"title":4638,"date":4613,"chapter":4639,"chapterSort":4640,"docKey":4615,"docRoot":4616,"docTitle":4617,"isWikiDoc":414,"isWikiIndex":4620},"/zh-tw/wiki/2026-01-07-esp32-jiao-cheng/ch2-esp32-huan-jing-da-jian","_i18n/zh-tw/wiki/2026-01-07-ESP32教程/ch2-ESP32环境搭建","ESP32環境搭建","2",2000000,{"path":4642,"stem":4643,"title":4644,"date":4613,"chapter":4645,"chapterSort":4646,"docKey":4615,"docRoot":4616,"docTitle":4617,"isWikiDoc":414,"isWikiIndex":4620},"/zh-tw/wiki/2026-01-07-esp32-jiao-cheng/ch3-can-kao-shi-pin","_i18n/zh-tw/wiki/2026-01-07-ESP32教程/ch3-参考视频","參考視頻","3",3000000,{"path":4610,"stem":4627,"title":5,"date":4613,"chapter":4611,"chapterSort":4612,"docKey":4615,"docRoot":4616,"docTitle":4617,"isWikiDoc":414,"isWikiIndex":4620},{"path":4616,"stem":4649,"title":4617,"date":4613,"chapter":4621,"chapterSort":4650,"docKey":4615,"docRoot":4616,"docTitle":4617,"isWikiDoc":414,"isWikiIndex":414},"_i18n/zh-tw/wiki/2026-01-07-ESP32教程/index",0,{"variants":4652},[4653,4656,4659,4662,4663],{"path":4654,"localeSlug":4655,"i18nKey":4619},"/en-us/wiki/2026-01-07-esp32-jiao-cheng/ch4-jiao-cheng","en-us",{"path":4657,"localeSlug":4658,"i18nKey":4619},"/zh-hant/wiki/2026-01-07-esp32-jiao-cheng/ch4-jiao-cheng","zh-hant",{"path":4660,"localeSlug":4661,"i18nKey":4619},"/zh-hk/wiki/2026-01-07-esp32-jiao-cheng/ch4-jiao-cheng","zh-hk",{"path":4610,"localeSlug":4623,"i18nKey":4619},{"path":4664,"localeSlug":4665,"i18nKey":4619},"/zh-cn/wiki/2026-01-07-esp32-jiao-cheng/ch4-jiao-cheng","zh-cn",[4654,4626,4657,4626,4660,4626,4610,4626,4664,4626],1780663018805]