当前位置: 首页 > news >正文

【YFIOs】用C#开发硬件之GPIO操作

YF3300-ESP32S3 是 YF3300 系列中面向高性能边缘计算与无线物联网场景的衍生型号。设备搭载 ESP32-S3-N16R8 双核处理器,原生支持 Wi-Fi 与蓝牙通信。主板采用工业级宽压与全隔离设计,并内置高精度温湿度传感器,非常适合需要本地复杂逻辑运算、无有线网络环境以及机箱环境监测的 IoT 应用场景。

  • 深度适配 nanoFramework,完美支持使用 C# / VB.NET /进行二次开发,享受 .NET 生态的便利
  • 支持 ESP-IDF 与 MicroPython 等主流开发环境
  • 支持远程参数设置、固件 OTA 升级及在线调试
  • 多样化的设备对外接口及协议栈支持,可轻松对接各类 Modbus RTU 仪表、PLC 及智能传感器
核心参数
类别说明
MCUESP32-S3-N16R8 (双核 Xtensa LX7,主频 240MHz)
存储片内 16MB Flash,8MB PSRAM
按钮系统启动键 (Boot) ×1,硬件复位键 ×1
LED指示灯电源指示灯 (红色) ×1,通信指示灯 (黄色) ×1,用户自定义灯 (绿色) ×1
调试接口Type-C USB 接口(自带 ESD 静电保护)
无线通信Wi-Fi + 蓝牙 BLE 5.0(支持外接高增益天线)
有线通信1路 RS-485 接口
1路 RS-232 接口
I/O 接口2路 光耦隔离开关量输入
1路 继电器输出 :提供常开(NO)、常闭(NC)、公共端(COM)
环境采集内置 1 路 SHT30 温湿度传感器
电源接口1路工业接线端子 (9-24V DC)
YF3300-ESP32S3 基于 ESP32-S3-N16R8 芯片,提供 48 个 GPIO 引脚。本页列出开发板已使用的引脚功能映射,供开发时快速查阅。

引脚总览表

GPIO功能类型用途
GPIO0BOOT 按钮输入(上拉)低电平触发
GPIO9RS485 TXUART1串口通信引脚
GPIO10RS485 RXUART1串口通信引脚
GPIO11RS232 TXUART2串口通信引脚
GPIO12RS232 RXUART2串口通信引脚
GPIO17I2C SDAI2CSHT30 温湿度传感器数据线
GPIO18I2C SCLI2CSHT30 温湿度传感器时钟线
GPIO21开关量输入 I1输入光耦隔离,低电平触发
GPIO39绿色 LED输出(低有效)配网状态指示
GPIO40黄色 LED输出(低有效)网络状态指示
GPIO47开关量输入 I2输入光耦隔离,低电平触发
GPIO48继电器 Q1输出(高有效)常开/常闭/公共端

GPIO操作

GPIO(通用输入输出)是嵌入式开发中最基础也是最重要的外设之一。YF3300-ESP32S3 开发板提供了丰富的 GPIO 资源,本章节将介绍如何使用 nanoFramework 进行 GPIO 编程,包括 LED 控制和按钮输入。

所需 NuGet 包

在 nanoFramework 项目中使用 GPIO 需要引用以下包:

包名说明
nanoFramework.CoreLibrary基础类库(通常自动包含)
nanoFramework.System.Device.Gpio核心 GPIO 操作库
nanoFramework.Runtime.Events事件运行时支持(下载 GPIO 核心库时自动包含)

核心概念

GpioController

GpioController是 nanoFramework 中 GPIO 操作的核心类,负责管理所有 GPIO 引脚的初始化、读写和释放。推荐使用using语句确保资源正确释放:

using(vargpio=newGpioController()){// 使用 GPIO 控制器进行引脚操作}

PinMode(引脚模式)

nanoFramework 的System.Device.Gpio模块支持8 种 GPIO 模式,分为输入模式和输出模式两大类:

输入模式(3种)
模式说明适用场景
PinMode.Input浮空输入(高阻态)外部已接上拉/下拉电阻的输入场景
PinMode.InputPullUp内部上拉输入按钮、开关,未按下时为高电平
PinMode.InputPullDown内部下拉输入按钮、开关,未按下时为低电平
输出模式(5种)
模式说明适用场景
PinMode.Output推挽输出LED、继电器等需要较强驱动能力的场景
PinMode.OutputOpenDrain开漏输出I2C 总线、漏极开路通信协议
PinMode.OutputOpenDrainPullUp开漏+内部上拉需要上拉电阻的开漏总线
PinMode.OutputOpenSource开极输出(推挽互补)需要低侧驱动的场景
PinMode.OutputOpenSourcePullDown开极+内部下拉需要下拉电阻的推挽总线

关于模拟输入(ADC):nanoFramework 并未省略 ADC 功能,而是将其独立为System.Device.Adc模块。System.Device.Gpio专门处理数字信号(开关量),而模拟信号读取需要使用System.Device.Adc模块。

PinValue(引脚值)

说明电压范围(典型)
PinValue.High高电平接近 VCC(3.3V)
PinValue.Low低电平接近 GND(0V)

PinEventTypes(中断事件类型)

用于检测引脚电平变化的中断事件:

事件类型说明
PinEventTypes.None无事件
PinEventTypes.Rising上升沿(低→高)
PinEventTypes.Falling下降沿(高→低)

注意:.NET nanoFramework 官方定义的 PinEventTypes 枚举中没有提供“双边沿触发
(Both)”选项。但双边沿触发可通过Rising | PinEventTypes.Falling位运算实现。

综合示例:LED 与按钮控制

硬件连接说明

LED

YF3300-ESP32S3 开发板板载2 个 LED,均采用低电平点亮方式:

LED 名称颜色GPIO 引脚功能说明
通信指示灯黄色GPIO40网络状态指示(CommLED)
用户指示灯绿色GPIO39用户自定义(UserLED)
按钮

YF3300-ESP32S3 开发板板载1 个 BOOT 按钮,采用上拉输入方式:

按钮名称GPIO 引脚连接方式功能说明
BOOT 按钮GPIO0上拉输入系统启动/配网触发

注意:未按下时引脚为高电平,按下时为低电平。

代码示例

Led.cs
usingSystem;usingSystem.Device.Gpio;usingSystem.Threading;namespaceGPIOTest.Drivers{publicclassLed:IDisposable{privatereadonlyGpioPin_pin;// GPIO引脚privatereadonlybool_activeLow;// 是否低电平点亮(true:低电平点亮,false:高电平点亮)privateTimer_blinkTimer;// 闪烁定时器privatebool_disposed;// 是否已释放资源privateint_onDurationMs=500;// 亮灯时间(毫秒)privateint_offDurationMs=500;// 熄灯时间(毫秒)publicintPinNumber=>_pin.PinNumber;// 获取LED引脚编号publicintOnDurationMs{get=>_onDurationMs;set=>_onDurationMs=value;}// 亮灯时间publicintOffDurationMs{get=>_offDurationMs;set=>_offDurationMs=value;}// 熄灯时间// 构造函数,初始化LED实例publicLed(GpioControllercontroller,intpinNumber,boolactiveLow=true){_activeLow=activeLow;_pin=controller.OpenPin(pinNumber,PinMode.Output);Off();}// 打开LED灯publicvoidOn(){_pin.Write(_activeLow?PinValue.Low:PinValue.High);}// 关闭LED灯publicvoidOff(){_pin.Write(_activeLow?PinValue.High:PinValue.Low);}// 切换LED灯状态publicvoidToggleLED(){_pin.Write(_pin.Read()==PinValue.High?PinValue.Low:PinValue.High);}// 闪烁LED灯(使用默认时间)publicvoidBlinkLED(){BlinkLED(_onDurationMs,_offDurationMs);}// 闪烁LED灯(指定亮/灭时间)publicvoidBlinkLED(intonMs,intoffMs){StopBlink();boolisOn=false;_blinkTimer=newTimer(_=>{if(isOn){Off();if(_blinkTimer!=null)_blinkTimer.Change(offMs,Timeout.Infinite);}else{On();if(_blinkTimer!=null)_blinkTimer.Change(onMs,Timeout.Infinite);}isOn=!isOn;},null,0,Timeout.Infinite);// 立即开始闪烁}// 停止闪烁LED灯publicvoidStopBlink(){if(_blinkTimer!=null){_blinkTimer.Dispose();_blinkTimer=null;}}// 释放资源publicvoidDispose(){if(!_disposed){StopBlink();if(_pin!=null){_pin.Dispose();}_disposed=true;}}}}
Button.cs
usingSystem;usingSystem.Device.Gpio;usingSystem.Threading;namespaceGPIOTest.Drivers{// 按钮回调委托publicdelegatevoidButtonCallback(intpinNumber,boolisPressed);publicclassButton:IDisposable{privatereadonlyGpioPin_pin;// GPIO引脚privatereadonlybool_activeLow;// 是否低电平有效(true:按下低电平,false:释放高电平)privatebool_disposed;// 是否已释放资源privateTimer_initTimer;// 初始化延迟定时器privateButtonCallback_callback;// 按钮状态变化回调publicintPinNumber=>_pin.PinNumber;// 获取按钮引脚编号publicboolIsPressed=>_activeLow?_pin.Read()==PinValue.Low:_pin.Read()==PinValue.High;// 获取按钮当前状态// 构造函数,初始化按钮实例publicButton(GpioControllercontroller,intpinNumber,ButtonCallbackcallback,boolactiveLow=true,PinModepinMode=PinMode.InputPullUp){_activeLow=activeLow;_callback=callback;_pin=controller.OpenPin(pinNumber,pinMode);// 延迟订阅事件,等待引脚状态稳定_initTimer=newTimer(InitCallback,null,100,Timeout.Infinite);}// 延迟初始化回调privatevoidInitCallback(objectstate){if(_disposed)return;_pin.ValueChanged+=OnPinValueChanged;_initTimer.Dispose();_initTimer=null;}// GPIO引脚值变化事件处理privatevoidOnPinValueChanged(objectsender,PinValueChangedEventArgse){if(_disposed)return;// 低电平有效:Falling=按下,Rising=释放;高电平有效:相反boolisPressed=_activeLow?(e.ChangeType==PinEventTypes.Falling):(e.ChangeType==PinEventTypes.Rising);_callback?.Invoke(PinNumber,isPressed);}// 释放资源publicvoidDispose(){if(_disposed)return;_disposed=true;if(_initTimer!=null){_initTimer.Dispose();}_pin.ValueChanged-=OnPinValueChanged;_pin.Dispose();}}}
Program.cs
usingSystem;usingSystem.Device.Gpio;usingSystem.Diagnostics;usingSystem.Threading;usingGPIOTest.Drivers;namespaceGPIOTest{publicclassProgram{// 硬件引脚定义(参考YF3300_ESP32S3硬件配置)privateconstintYellowLEDPin=40;// 黄色LED - 网络状态指示privateconstintGreenLEDPin=39;// 绿色LED - 配网状态指示privateconstintButtonPin=0;// 按钮引脚publicstaticvoidMain(){Debug.WriteLine("=== LED双闪测试开始 ===");using(vargpio=newGpioController()){// 初始化黄色LED(快闪:亮500ms,熄灭1500ms)varyellowLed=newLed(gpio,YellowLEDPin,activeLow:true);Debug.WriteLine($"黄色LED (GPIO{YellowLEDPin}) - 快闪模式");yellowLed.BlinkLED(onMs:500,offMs:1500);// 初始化绿色LED(慢闪:亮200ms,灭200ms)vargreenLed=newLed(gpio,GreenLEDPin,activeLow:true);Debug.WriteLine($"绿色LED (GPIO{GreenLEDPin}) - 慢闪模式");greenLed.BlinkLED(onMs:200,offMs:200);// 初始化按钮,控制LED开关varbutton=newButton(gpio,ButtonPin,OnButtonChanged);Debug.WriteLine($"按钮 (GPIO{ButtonPin}) - 就绪");Thread.Sleep(Timeout.Infinite);}}// 按钮状态变化回调privatestaticvoidOnButtonChanged(intpinNumber,boolisPressed){if(isPressed){Debug.WriteLine($"按钮按下 - 引脚{pinNumber}");}else{Debug.WriteLine($"按钮释放 - 引脚{pinNumber}");}}}}

YFESP32开发板详细开发文档 https://docs.yfios.net/docs/sdk/yfesp32s3-sdk

http://www.jsqmd.com/news/908378/

相关文章:

  • 基于Whisper、Llama 2与Bark构建本地离线语音助手实战指南
  • AI应用的用户体验设计:从用户研究到迭代
  • 术语俗话 --- 什么是类C代码
  • Uber 4 个月烧光 2026 全年 AI 预算:人均月账单 $500-$2000,企业 token 计费失控的第一个公开样本
  • 如何用 ChatGPT 提升学习指导效率?完整实现指南
  • 体育科技革命:从数据采集到AI分析,技术如何重塑竞技体育
  • Gemini多语言翻译质量深度拆解(中/日/阿/印地语实测盲区大曝光)
  • NVIDIA Profile Inspector终极指南:5个步骤解决显卡驱动兼容性难题
  • 微服务间的远程接口调用:OpenFeign 的使用
  • GAMP程序太老了?手把手教你修改源码,让北斗三号PPP定位精度起飞
  • 华硕笔记本终极优化指南:5个G-Helper核心功能让电脑重获新生
  • 量化投资基石:10大机器学习股票数据集选型与实战指南
  • ESPI协议详解:单线、双线、四线模式怎么选?服务器BMC带外管理实战
  • 鸿蒙数学 108 篇 第二十八篇:计数体系完整推演
  • ArcSWAT建模新手避坑指南:你的土壤参数SOL_AWC算对了吗?从SPAW计算到模型验证
  • 别再瞎猜了!用SystemView透视你的FreeRTOS任务调度,解决实际卡顿问题
  • 2026年|知网AIGC查重原理与降AI实用技巧 - 降AI实验室
  • 3分钟快速上手:手机号码定位工具location-to-phone-number完全指南
  • 2025-2026年一起装修网电话查询。装修前请核实资质与合同条款 - 品牌推荐
  • 告别MPU6050磁干扰漂移:手把手教你用STM32CubeMX HAL库驱动IM948陀螺仪(附完整源码)
  • 别再只调sklearn的KMeans了!手把手教你用NumPy从零实现K-means聚类(附鸢尾花数据集实战代码)
  • 告别Cloud Sync!用Docker版aliyundrive-webdav为群晖打造更稳定的阿里云盘备份方案
  • 从零搭建自动化天文台:圆顶同步、PLC控制与远程观测实践
  • RoboTron-Sim:自动驾驶长尾场景模拟数据解决方案
  • 低预算先跑测试:投流公司常用小步快跑打法
  • JavaScript中Emoji长度计算的陷阱与精准解决方案
  • FineReport连接TDengine 3.x踩坑实录:驱动版本、时区问题与客户端安装的终极解决方案
  • 别再死磕Q-learning了!用Sarsa算法搞定你的第一个强化学习智能体(附Python代码)
  • 2025-2026年北京京云律师事务所电话查询:委托前请核实资质与合同条款 - 品牌推荐
  • MATLAB配电网状态估计算法包:最小二乘+解耦双模型,改参数就能跑不同拓扑