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