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

审核编辑:符乾江

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

    关注

    5073

    文章

    19039

    浏览量

    303628
  • i/o控制
    +关注

    关注

    1

    文章

    4

    浏览量

    944
收藏 人收藏

    评论

    相关推荐

    可编程晶振的优点和缺点

    可编程晶振,近年来渐入人们眼中。什么是可编程晶振,与普通晶振有什么区别?可编程晶振的优点和缺点有哪些?1,什么是可编程晶振可编程晶振是一种可
    的头像 发表于 09-30 10:44 343次阅读
    <b class='flag-5'>可编程</b>晶振的优点和缺点

    TMP401 ±1°C可编程、远程和本地数字输出温度传感器数据表

    电子发烧友网站提供《TMP401 ±1°C可编程、远程和本地数字输出温度传感器数据表.pdf》资料免费下载
    发表于 08-13 10:17 0次下载
    TMP401 ±1°C<b class='flag-5'>可编程</b>、远程和本地<b class='flag-5'>数字</b><b class='flag-5'>输出</b>温度传感器数据表

    可编程晶振都有什么频率的呢?分享3个挑选可编程晶振的技巧

    频率范围全面覆盖,满足多样化需求: • CMOS可编程晶振:1~200MHz宽广选择,为您的基础应用提供稳定可靠的支持。 • 可编程差分晶振:高达2100MHz的卓越性能,满足高速数据传输与信号处理的高标准要求。 • 可编程压控
    的头像 发表于 07-18 18:30 1084次阅读
    <b class='flag-5'>可编程</b>晶振都有什么频率的呢?分享3个挑选<b class='flag-5'>可编程</b>晶振的技巧

    可编程电源的作用是什么

    可编程电源的作用是什么 可编程电源是一种电子设备,它可以根据用户的需求调整输出电压和电流。这种电源广泛应用于各种电子设备和系统的测试、调试和研发过程中。 ### 可编程电源的作用 ##
    的头像 发表于 06-10 15:33 622次阅读

    可编程电源使用方法

    的使用技巧。 关键词:可编程电源;使用方法;操作步骤;注意事项 1. 引言 可编程电源是一种广泛应用于电子设备测试、研发和生产领域的电源设备。它具有输出电压、电流可调,输出波形
    的头像 发表于 06-10 15:29 927次阅读

    可编程电源如何编程

    可编程电源的编程方法和步骤。 ### 1. 可编程电源的基本概念 可编程电源通常由以下几个部分组成: - **输入模块**:接收交流或直流
    的头像 发表于 06-10 15:24 1240次阅读

    ISL28633EV2Z输入/输出零漂移可编程增益仪表放大器评估板

    电子发烧友网站提供《ISL28633EV2Z输入/输出零漂移可编程增益仪表放大器评估板.rar》资料免费下载
    发表于 06-07 16:28 0次下载

    什么是现场可编程逻辑阵列?它有哪些特点和应用?

    可编程逻辑元件和可编程互连,实现逻辑电路的设计和配置。FPLA在电子系统设计、数字信号处理、网络通信等多个领域都有广泛应用。本文将对现场可编程逻辑阵列进行详细介绍,包括其定义、原理、特
    的头像 发表于 05-23 16:25 831次阅读

    可编程片上系统是什么

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

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

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

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

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

    现场可编程门阵列简介

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

    现场可编程门阵列是什么

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

    可编程控制器的组成 可编程控制器有哪些特点?

    可编程控制器(Programmable Logic Controller,PLC)是一种使用数字计算机技术和专用外设实现工业过程自动化控制的设备。它在工业生产中起到了非常重要的作用。本文将详细介绍
    的头像 发表于 01-18 11:18 1438次阅读

    FPGA现场可编程门阵列的综合指南

    现场可编程门阵列 (FPGA) 是可以在制造后进行编程和重新编程以实现数字逻辑功能的半导体器件。
    的头像 发表于 12-07 17:15 669次阅读
    FPGA现场<b class='flag-5'>可编程</b>门阵列的综合指南