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

审核编辑:符乾江

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

    关注

    4962

    文章

    18145

    浏览量

    286510
  • i/o控制
    +关注

    关注

    1

    文章

    4

    浏览量

    912
收藏 人收藏

    评论

    相关推荐

    可编程片上系统是什么意思

    可编程片上系统(Programmable System-on-Chip,PSoC)是一种特殊的嵌入式系统。它首先是一个片上系统,这意味着整个系统的主要逻辑功能由单个芯片完成。其次,它具有可编程的特性,设计方式灵活,可裁减、可扩充、可升级,并具备软硬件在系统
    的头像 发表于 03-28 15:09 70次阅读

    可编程片上系统是什么

    到一个芯片中。这种系统不仅具有处理器内核、存储器、输入输出接口等基本元件,还包含丰富的IP Core资源、足够的片上可编程逻辑资源以及小容量的片内高速RAM资源。
    的头像 发表于 03-28 14:55 58次阅读

    现场可编程门阵列的基本结构和优缺点

    现场可编程门阵列(FPGA)的基本结构主要包括可编程输入/输出单元、基本可编程逻辑单元、嵌入式块RAM、丰富的布线资源、底层嵌入功能单元和内
    的头像 发表于 03-27 14:49 81次阅读

    现场可编程门阵列的原理和应用

    可以根据用户的设计进行配置,形成所需的逻辑功能。互连资源则是一组可编程的连接通道,用于将PLU连接在一起,以实现用户定义的电路拓扑结构。此外,FPGA还包括输入输出模块(IOB),用于与外部设备或电路进行连接。
    的头像 发表于 03-27 14:49 75次阅读

    现场可编程门阵列简介

    可编程逻辑块(CLB)和输入输出模块(IOB)。CLB是实现逻辑功能的基本单元,主要由逻辑函数发生器、触发器、数据选择器等数字逻辑电路构成。IOB则提供了芯片引脚和内部逻辑阵列之间的连接,可独立
    的头像 发表于 03-27 14:48 79次阅读

    现场可编程门阵列是什么

    现场可编程门阵列(Field Programmable Gate Array,简称FPGA)是一种超大规模可编程逻辑器件,由可编程逻辑资源、可编程互连资源和
    的头像 发表于 03-16 16:38 1546次阅读

    分享 | 可编程晶振芯片几个知识点

    什么是可编程晶振?可编程晶振多为有源晶振,由两个芯片组成;一个是全硅MEMS谐振器,一个是具有温补功能的芯片,可以启动电路锁相环CMOS
    的头像 发表于 01-09 17:51 494次阅读
    分享 | <b class='flag-5'>可编程</b>晶振芯片几个知识点

    数字可编程变频电源使用有哪些注意事项?

    数字可编程变频电源使用有哪些注意事项? 数字可编程变频电源是一种能够根据用户需求调整输出电压和频率的电源设备。它在工业生产和实验室研究等领域
    的头像 发表于 11-13 16:09 423次阅读

    可编程晶振详解「工作原理、结构、特点、应用」

    可编程晶振器是一种高级的晶体振荡器,其工作原理、结构和应用均有一定的特点。今天晶发电子对可编程晶振的详细介绍。 一、工作原理 可编程晶振器是通过数字控制方式来改变其
    发表于 10-14 17:38

    可编程电源作用原理

    可编程电源是现代电子设备测试中常见的一种设备,具有稳定性高、精度高、输出稳定等优点,为工业生产、研发及维修等领域提供了可靠的电源保障。今天我们要详细介绍一下可编程电源的工作原理,让大家了解其内部结构、电子元件及控制系统等方面的信
    的头像 发表于 10-10 16:38 490次阅读
    <b class='flag-5'>可编程</b>电源作用原理

    PLC可编程逻辑控制器的常见错误类型以及修复方法

    、指令及数据内存、输入/输出接口、电源、数字模拟转换等功能单元组成。早期的可编程逻辑控制器只有逻辑控制的功能,所以被命名为可编程逻辑控制器,
    的头像 发表于 09-07 08:08 977次阅读
    PLC<b class='flag-5'>可编程</b>逻辑控制器的常见错误类型以及修复方法

    可编程信号隔离变送器

    可编程信号隔离变送器捷晟达科技(JSD科技)的JSD TA-A1001S系列是可编程多信号输入与多信号输出的隔离变送器,是将输入
    发表于 09-02 03:21 0次下载

    什么是可编程片上系统?PSOC和FPGA的区别

    可编程片上系统(Programmable System-on-Chip,PSoC)是一种集成了数字逻辑、模拟电路和可配置模块的片上系统。它将传统的微处理器、微控制器和可编程逻辑器件等功能融合到一个芯片中,并提供了
    发表于 07-06 15:15 2416次阅读

    可编程逻辑器件测试

    可编程逻辑器件 (Programmable Loeie Device,PLD)是一种用户编程实现某种逻辑功能的逻辑器件,主要由可编程的与阵列、或阵列、门阵列等组成,可通过编程来实现一定
    发表于 06-06 15:37 412次阅读
    <b class='flag-5'>可编程</b>逻辑器件测试

    可编程逻辑器件测试方法

    可编程逻辑器件 (Programmable Loeie Device,PLD)是一种用户编程实现某种逻辑功能的逻辑器件,主要由可编程的与阵列、或阵列、门阵列等组成,可通过编程来实现一定
    的头像 发表于 06-06 15:35 677次阅读
    <b class='flag-5'>可编程</b>逻辑器件测试方法