0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

可编程数字输入和输出详解

嵌入式应用开发 来源:嵌入式应用开发 作者:嵌入式应用开发 2022-06-18 19:30 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

数字型输入/输出外设仅有两种有效状态,习惯用On和Off、High和Low、打开和关闭、接通和断开等表示两种有效状态,譬如一个继电器触点的接通状态和断开状态、 一颗指示灯的on状态和off状态等。存储一个数字型输入/输出外设的状态信息仅需要一个二进制位。绝大多数MCU的可编程I/O引脚都可编程输出高电平和低电平, 这样的I/O引脚电平状态与相应接口电路即可控制数字型输出外设的状态,因此在MCU内部使用二进制位的“1”和“0”分别表示数字型输出外设的状态。 同时,通过读取MCU的I/O引脚的电平即可获取数字型输入外设的状态,并使用布尔型(Boolean)变量保存该状态。

很多编程语言都支持布尔型变量,尤其支持嵌入式系统的编程语言,譬如C/C++语言。虽然布尔型变量的有效值仅为“1”和“0”,如果目标计算机系统不支持位操作和位寻址, 布尔型变量仍占用一个字节或更多二进制位来存储一个二进制信息。现在的MCU绝大多数都支持位操作和位寻址,譬如ARM Cortex-M系列微内核支持“bit-band”操作, 允许存取指令访问单个数据位(详见 [1]_ 的6.7节)。

按钮和LED指示灯是最简单的数字型输入和输出外设,图4.1给出BlueFi上的按钮和LED指示灯的电路连接示意图。

../_images/gpio_examples_reset_di_do.jpg

图4.1 BlueFi上的按钮和LED指示灯的电路连接示意图

从上图中,我们不仅能够了解数字型输入/输出信号的电平电压、驱动电流、频率和复位期间的默认状态,还能了解如何读取数字型输入外设的状态到内部变量, 以及如何通过写外设存储区的地址单元来控制数字型输出状态。

BlueFi的主MCU(nRF52840)的外部复位信号的有效电平为低电平(详见nRF52840的产品说明文档 [2]_ ),且内部带有上电复位(即冷复位)电路(图中黄色的电阻电容), 图4.1给出最简单的外部复位电路:一个手动复位按钮,一端接地,另一端与“nRST”引脚连接。内部上电复位电路的电阻与MCU的工作电源连接,当外部手动复位按钮未被按下时保持复位引脚状态为高电平, 这个电平的电压显然与MCU的工作电压相等;当按下手动复位按钮时复位引脚的状态为低电平,这个电平的电压与电源地相同。当我们需要给nRF52840复位时,只需要按下复位按钮即可。 按下按钮时从“nRST”引脚强制施加低电平信号给MCU内核的内部复位电路单元将片上所有功能单元(含CPU)复位,当我们释放手动复位按钮后,片上的上电复位电路确保“nRST”引脚处于高电平, CPU开始工作。我们在第2.7节已经了解到MCU的多种复位源,在复位期间,nRF52840内部的“RESETREAS”寄存器(0x4000 0400地址单元)将保存本次复位的信号源, 应用程序可以根据这个寄存器的内容来识别复位源。单按一次BlueFi的复位按钮是正常的系统复位,而连续双击BlueFi的复位按钮,你会发现BlueFi进入Bootloader状态。 这个功能是使用“RESETREAS”寄存器的内容。

BlueFi的A和B按钮是可编程的,两个按钮的电路连接完全相似(除了使用不同的I/O引脚),图4.1中仅给出A按钮的电路连接。A按钮的接口电路不仅包含片外的按钮, 还包含片内的可配置上拉/下拉电阻,由于A按钮的一端与MCU工作电源连接、另一端与P1.7引脚连接,当A按钮按下时P1.7引脚被强制与电源连接;如果P1.7的内部配置为下拉电阻, 当A按钮释放时P1.7引脚被下拉到电源地。通过读取P1.7引脚的状态确定A按钮的状态,当A按钮按下时读取状态的结果为“1”(即高电平),当A按钮释放时读取状态的结果为“0”(即低电平)。 当我们将A按钮的状态保存到一个布尔型变量时,如果不采用DMA(直接存储器访问)方式,nRF52840的CPU的工作过程为:将P1.IN寄存器(即0x5000 0810地址单元)读入CPU内部某个寄存器, 然后再将D7位的值(即P1.7引脚的状态)保存到布尔型变量(即“Bit_Band”区的某个地址单元)。

对于P1.7内部可配置的上拉/下拉电阻的使用,需要在BlueFi初始化期间根据A按钮的电路进行编程配置。按照图4.1,使用Arduino IDE平台,A按钮的初始化和使用代码参考如下:

void setup() {
  // put your setup code here, to run once:
  pinMode(PIN_BUTTON1, INPUT_PULLDOWN);
}

void loop() {
  // put your main code here, to run repeatedly:
  bool state_aBtn = digitalRead(PIN_BUTTON1);
  if (state_aBtn == HIGH) {
    // A button be pressed
  } else {
    // A button be released
  }
}

第3行代码是调用Arduino内部函数“pinMode(PIN_BUTTON1, INPUT_PULLDOWN)”将P1.7引脚(即与A按钮连接的I/O引脚)配置为输入模式且使用内部下拉电阻。在Arduin IDE平台, 有三种输入配置:浮空输入(INPUT)、上拉输入(INPUT_PULLUP)和下拉输入(INPUT_PULLDOWN)。第8行调用Arduino内部函数“digitalRead(PIN_BUTTON1)”读取A按钮的状态, 由于按钮的状态为二进制型信息,所以将A按钮的当前状态暂存在布尔型变量“state_aBtn”中。根据图4.1的电路结构,当A按钮被按下时布尔型变量“state_aBtn”的值为“true”或“HIGH”。 注意,“HIGH”是Arduino平台的布尔型常量,“true”是C/C++编程语言的标准常量。

BlueFi有两颗亮起时颜色分别为红色和白色的LED指示灯,他们的连接电路如图4.1所示,两颗LED分别受P1.12和P1.14引脚控制。当程序将P1.OUT寄存器(即0x5000 0804地址单元) 的D12位置位时,P1.12引脚将输“1”(即高电平),红色LED指示灯将亮起;当程序将P1.OUT寄存器的D12位清零时,P1.12引脚输入“0”(即低电平),红色LED指示灯将熄灭。 BlueFi与其他数字电路采用相同的设计习惯,I/O引脚为高电平时对应的电压等于MCU的I/O工作电压,低电平对应的电压等于电源地,按照前一章的BlueFi电路原理介绍, nRF52840使用3.3V作为I/O引脚电压。根据红色LED的正向压降、串联电阻的阻值和高电平的电压,我们可以计算出红色LED亮起时的电流(简称on电流),这个电流的大小决定指示灯的亮度。

根据A按钮的状态控制红色LED指示灯亮和灭的代码如下:

oid setup() {
  // put your setup code here, to run once:
  pinMode(PIN_BUTTON1, INPUT_PULLDOWN);
  pinMode(LED_RED, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  bool state_aBtn = digitalRead(PIN_BUTTON1);
  if (state_aBtn == HIGH) {
    // A button be pressed
    digitalWrite(LED_RED, HIGH);
  } else {
    // A button be released
    digitalWrite(LED_RED, LOW);
  }
}

按照“..Arduino15packagesadafruithardwarenrf520.20.5variantsbluefi_nrf52840variant.h“头文件中对BlueFi的I/O引脚用法的定义, 只需要将上述代码中的“LED_RED”引脚名称替换为“LED_WHITE”,然后编译并下载修改后的代码到BlueFi,可以使用A按钮控制白色LED的亮和灭。

与红色LED相比,你也许已经发现BlueFi的白色LED更亮一些。这说明,白色LED指示灯on电流大于红色LED。如果使用I/O引脚输出的高电平电压直接驱动LED,并不断地减小LED的串联电阻阻值, LED的亮度将会不断地增加吗?如果假设I/O引脚输出的高电平电压是理想的(即内阻为0且功率足够大),这个问题的答案是肯定的。事实上,所有MCU的I/O引脚的驱动能力都是有限的, 按拉电流和灌电流两种指标分别指定每一个I/O引脚的驱动能力。当I/O引脚的驱动能力无法满足LED指示灯on电流时,我们自然会想到外部驱动,如图4.1中使用外部NPN三极管驱动白色LED指示灯, 此时I/O引脚输出的拉电流被三极管放大数十倍(即三极管的放大倍数)作为白色LED指示灯on电流。当外部数字型输出外设需要更大的负载电流时,或许需要多级结构(如达林顿结构)的三极管提高放大倍数。

对于MCU的可编程I/O引脚,除了可配置的上拉/下拉电阻、可编程为输入/输出模式等,还有更多可配置的结构。以nRF52840为例,我们需要进一步了解其内部的结构,如图4.2所示。

../_images/nrf52840_gpio_pin_details_pin0.jpg

图4.2 nRF52840可编程I/O引脚的内部结构

在上图中,我们可以找到一个可编程输入/输出引脚的所有配置选项、输入通道、输出通道等。除了数字I/O功能之外,一个可编程输入/输出引脚也可以当作模拟I/O功能引脚使用, 图4.2中的“ANAEN”是编程配置一个引脚当作数字I/O或模拟I/O的控制位。关于模拟输入/输出的功能,详见下一节。在nRF52840的手册中,我们可以找到每一个可编程输入/输出引脚的 配置和控制相关的存储器地址和有效的控制位,“pinMode(pin,mode)”、“digitalRead(pin)”和“digitalWrite(pin,value)”等基本数字型I/O接口都是通过编程这些存储单元而实现的。

已经了解数字型I/O的电路和软件接口之后,我们可以接着第3章最后一节的任务:为BlueFi设计BSP,现在只涉及BlueFi的数字I/O相关的部分,即两个输入按钮和两个LED指示灯的BSP。 如果你是BlueFi的二次开发(编程应用)用户,你将会如何使用按钮和LED指示灯呢?BSP的目的是根据特定硬件电路封装API并加快二次用户开发的工作效率,譬如BlueFi的两个按钮的配置 (需根据按钮的电路结构)等,用户只需调用BSP封装的API即可得到“按钮被按下/释放/长按“,或直接控制“红色LED亮/灭/切换”等。

为了了解BSP的基本结构,我们首先来实现LED控制的API

审核编辑:符乾江

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式
    +关注

    关注

    5186

    文章

    20155

    浏览量

    328969
  • i/o控制
    +关注

    关注

    1

    文章

    3

    浏览量

    1131
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    新品 | Chain DualKey,可编程双按键输入开发板

    ChainDualKey是一款可编程双按键输入开发板,搭载ESP32-S3FN8主控芯片。正面集成2个支持热插拔的青轴机械键盘按键及2个可编程RGBLED,交互反馈优异;内置350mAh锂电池,结合
    的头像 发表于 10-31 16:31 1495次阅读
    新品 | Chain DualKey,<b class='flag-5'>可编程</b>双按键<b class='flag-5'>输入</b>开发板

    CDCE913 可编程1PLL VCXO时钟合成器技术手册

    CDCE913和CDCEL913器件是基于PLL的模块化、低成本、高性能、可编程时钟合成器。这些器件从单个输入频率产生多达三个输出时钟。每个输出都可以使用集成的可配置PLL在系统内针对
    的头像 发表于 09-18 15:12 547次阅读
    CDCE913 <b class='flag-5'>可编程</b>1PLL VCXO时钟合成器技术手册

    PGA855可编程增益仪表放大器技术解析与应用指南

    Texas Instrument PGA855可编程增益仪表放大器是一款具有全差分输出的高带宽可编程增益仪表放大器。PGA855有八个二进制增益设置,衰减增益范围为0.125V/V到16V/V,使用三个
    的头像 发表于 08-08 14:53 991次阅读
    PGA855<b class='flag-5'>可编程</b>增益仪表放大器技术解析与应用指南

    可编程SLIC语音芯片哪家好?

    在当今数字化快速发展的时代,语音芯片的应用越来越广泛,而可编程SLIC(用户线路接口电路)语音芯片更是凭借其独特的优势,受到众多行业的青睐。那么,面对众多的选择,哪家的可编程SLIC语音芯片更胜一筹
    的头像 发表于 06-12 13:55 547次阅读
    <b class='flag-5'>可编程</b>SLIC语音芯片哪家好?

    AD5930可编程频率扫描及输出突发波形发生器技术手册

    AD5930是一款支持可编程频率扫描和输出突发功能的波形发生器。这款器件采用支持增强型频率控制的嵌入式数字处理技术,能够生成合成的模拟或数字频率步进波形。采用预先
    的头像 发表于 05-06 14:23 821次阅读
    AD5930<b class='flag-5'>可编程</b>频率扫描及<b class='flag-5'>输出</b>突发波形发生器技术手册

    LMH32401-Q1 汽车级可编程增益差分输出高速跨阻放大器技术手册

    LMH32401-Q1 器件是一款汽车类、可编程增益、单端输入转差分输出跨阻放大器,适用于光检测和测距(激光雷达)应用。
    的头像 发表于 03-21 10:42 952次阅读
    LMH32401-Q1 汽车级<b class='flag-5'>可编程</b>增益差分<b class='flag-5'>输出</b>高速跨阻放大器技术手册

    可编程电子负载的原理及主要应用

    可编程电子负载是电源测试领域的关键设备,能够模拟真实负载条件并动态调整参数,为电源、电池、新能源设备等提供性能验证。源仪电子基于20年行业经验,开发了可编程直流电子负载系列,涵盖高精度测试、动态响应及多通道控制功能,满足从研发到量产的全流程测试需求。
    的头像 发表于 03-15 10:38 1437次阅读
    <b class='flag-5'>可编程</b>电子负载的原理及主要应用

    可编程大功率直流电源有哪些

    在现代科技不断进步的背景下,可编程大功率直流电源作为一种先进且关键的电子测试设备,已经在多个领域内得到了广泛的应用。可编程大功率直流电源主要指的是能够根据不同的需求,通过程序控制其输出的电压和电流
    的头像 发表于 02-14 17:12 974次阅读

    参考设计#60 W 可编程电源 具有零电压开关 (ZVS) 和 5-20 V 可变输出

    电源,具有 ZVS 和 5-20 V 可编程输出.pdf *附件:60 W 可编程电源_gerber.zip InnoSwitch4-Pro 数字可控零电压开关反激式开关 IC 75
    的头像 发表于 01-23 15:22 1050次阅读
    参考设计#60 W <b class='flag-5'>可编程</b>电源 具有零电压开关 (ZVS) 和 5-20 V 可变<b class='flag-5'>输出</b>

    可编程电压范围指的是输入到ADS828芯片的电压范围吗

    ADS828, THS4503用的是ADS828,在数据手册上看到可编程电压范围,我想问的是,可编程电压范围指的是输入到ADS828芯片的电压范围吗? 关于ADS828还有一点不明白,ADS828
    发表于 01-20 06:40

    可编程交流负载标准

    标准通常具有高精度和高稳定性的特点,在测试过程中,负载需要提供稳定的电压和电流输出,以确保测试结果的准确性。因此,可编程交流负载设备通常会采用先进的控制技术和高精度的传感器,以保证输出的稳定性和精度
    发表于 01-15 13:53

    爱普生(EPSON) 常规可编程晶振

    常规可编程晶振主要用来替换一般用途的中低频四脚有源晶振,可以满足大多数用途有源晶振的快速交付。爱普生(Epson)作为全球领先的晶体产品供应商,提供了一系列可编程晶振,可以与基波正常振荡器相同
    的头像 发表于 01-13 15:24 1040次阅读
    爱普生(EPSON) 常规<b class='flag-5'>可编程</b>晶振

    AN-953: 具可编程模数的直接数字频率合成器(DDS)

    电子发烧友网站提供《AN-953: 具可编程模数的直接数字频率合成器(DDS).pdf》资料免费下载
    发表于 01-13 14:13 0次下载
    AN-953: 具<b class='flag-5'>可编程</b>模数的直接<b class='flag-5'>数字</b>频率合成器(DDS)

    可编程晶振的锁相环原理

    (Phase-LockedLoop,PLL)技术在可编程晶振中扮演着关键角色,以下是对可编程晶振中锁相环技术的详细讲解:一、锁相环技术的基本原理1、锁相环是一种利用相位同步产生
    的头像 发表于 01-08 17:39 980次阅读
    <b class='flag-5'>可编程</b>晶振的锁相环原理

    PLC可编程控制器的简介

    PLC的英文全称为Programmable Logic Controller,也就是可编程序控制器。它是一种将计算机技术与继电器技术结合起来的现代化自动控制装置,1969年,美国数字化设备公司研制出
    的头像 发表于 12-23 09:09 2090次阅读