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