未完,待续。。。。。。

本实现是基于一个开发箱,包括:综合应用开发系统主板XT-EDU-AK   1套; 手持终端系统 XT-EDU-HK 1套;

GPIO操作

工程:

这是一个关于流水灯的程序:

我们先看主函数:

#include <stdbool.h>
#include <stdint.h>
#include "nrf_delay.h"
#include "nrf_gpio.h"      //这里面有关于gpio的操作,似乎只有.h文件,没有.c文件
#include "boards.h"       //关于板子是如何设计的,例如小灯接在哪个管脚上,都可以从这里找到。

#define LEDS_NUMBER 8  //这是一个宏定义,一般编程的思路都是这样,把一些固定值都写成define,方便以后增加或修改。

const uint8_t leds_list[LEDS_NUMBER] = { LED_1, LED_2, LED_3, LED_4, LED_5, LED_6, LED_7, LED_8 };

int main(void)
{
uint8_t i;

nrf_gpio_range_cfg_output(LED_STOP,LED_START); // Configure LED-pins as outputs.

while (true)
{
for (i = 0; i < LEDS_NUMBER; i++) //light in order in 50ms interval
{
nrf_gpio_pin_clear(leds_list[i]);//设置gpio为低电平,点亮小灯。
nrf_delay_ms(50);
nrf_gpio_pin_set(leds_list[i]); //设置gpio为高电平,熄灭小灯。
}
for (i = LEDS_NUMBER; i > 0; i--) //light in order in 50ms interval
{
nrf_gpio_pin_clear(leds_list[i-1]);
nrf_delay_ms(50);
nrf_gpio_pin_set(leds_list[i-1]);
}
}
}

//上面是主函数,下面是子函数的分析。

在main.c中,

nrf_gpio_range_cfg_output(LED_STOP,LED_START);

是主要部分 ,作用为初始化gpio为输出。也是常用的套路,

一般就是把所有的引脚放到数组里,然后依次初始化。

可以打开它的代码:

static __INLINE void nrf_gpio_range_cfg_output(uint32_t pin_range_start, uint32_t pin_range_end)
{
/*lint -e{845} // A zero has been given as right argument to operator '|'" */
for (; pin_range_start <= pin_range_end; pin_range_start++)     //这一部分没有深究
{
NRF_GPIO->PIN_CNF[pin_range_start] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos)
| (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos)
| (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos)
| (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos)
| (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
} //其实上面这些都是关于寄存器的操作。对于初学没必要掌握,只要知道如何调用函数,调用哪个函数就行。
}

在nrf_gpio.h文件中有详细的gpio操作:(可以认为是库函数都在这里面)

下面对该文件夹下的函数进行注释:

nrf_gpio_range_cfg_output(uint32_t pin_range_start, uint32_t pin_range_end)  可以设置好几个引脚

:没有电平检测;驱动能力是最低等级;没有上下拉;没有启动input buffer;输出;

nrf_gpio_range_cfg_input(uint32_t pin_range_start, uint32_t pin_range_end, nrf_gpio_pin_pull_t pull_config)  可以设置好几个引脚

:没有电平检测;驱动能力是最低等级;上下拉是根据传入的参数设定的;启动input buffer;输入;

nrf_gpio_cfg_output(uint32_t pin_number)  设置一个引脚

:没有电平检测;驱动能力是最低等级;没有上下拉;没有启动input buffer;输出;

nrf_gpio_cfg_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config)  设置一个引脚

:没有电平检测;驱动能力是最低等级;上下拉根据传入参数而定;启动input buffer;输入;

nrf_gpio_cfg_sense_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config, nrf_gpio_pin_sense_t sense_config)

:电平检测高或低由传入参数而定;驱动能力是最低等级;上下拉根据传入参数而定;启动input buffer;输入;

nrf_gpio_pin_dir_set(uint32_t pin_number, nrf_gpio_pin_dir_t direction)

:没有电平检测;驱动能力是最低等级;没有上下拉;启动input buffer;输入输出由传入参数决定;

nrf_gpio_pin_set(uint32_t pin_number)  //设置某个引脚为高电平

nrf_gpio_pin_clear(uint32_t pin_number)//设置某个引脚为低电平

nrf_gpio_pin_toggle(uint32_t pin_number)//翻转某个引脚的电平

nrf_gpio_pin_write(uint32_t pin_number, uint32_t value) //写某个引脚的电平,可以写高,也可以写低

nrf_gpio_pin_read(uint32_t pin_number) //读取某个引脚的电平

nrf_gpio_word_byte_write(volatile uint32_t * word_address, uint8_t byte_no, uint8_t value) //写多个port的值

nrf_gpio_word_byte_read(const volatile uint32_t* word_address, uint8_t byte_no) //读多个port的值

nrf_gpio_port_dir_set(nrf_gpio_port_select_t port, nrf_gpio_port_dir_t dir) //Function for setting the direction of a port.

nrf_gpio_port_read(nrf_gpio_port_select_t port) //Function for reading a GPIO port.

nrf_gpio_port_write(nrf_gpio_port_select_t port, uint8_t value) //Function for writing to a GPIO port.

nrf_gpio_port_set(nrf_gpio_port_select_t port, uint8_t set_mask) //Function for setting individual pins on GPIO port.

nrf_gpio_port_clear(nrf_gpio_port_select_t port, uint8_t clr_mask) //Function for clearing individual pins on GPIO port.

下面看一个现象:

void nrf_gpio_range_cfg_input(uint32_t pin_range_start, uint32_t pin_range_end, nrf_gpio_pin_pull_t pull_config);

//上面的函数中绿色部分是个结构体,结构体的作用是保存量类似和有联系的变量,这里是输入的方式,打开该结构体

//会看到:

typedef enum
{
NRF_GPIO_PIN_NOPULL = GPIO_PIN_CNF_PULL_Disabled, ///< Pin pullup resistor disabled
NRF_GPIO_PIN_PULLDOWN = GPIO_PIN_CNF_PULL_Pulldown, ///< Pin pulldown resistor enabled
NRF_GPIO_PIN_PULLUP = GPIO_PIN_CNF_PULL_Pullup, ///< Pin pullup resistor enabled
} nrf_gpio_pin_pull_t;

//这也许是一种编程手法

关于STM32单片机的几种输入输出模式的讲解:

推挽输出模式:

可以输出高,低电平,连接数字器件; 推挽结构一般是指两个三极管分别受两互补信号的控制,总是在一个三极管导通的时候另一个截止。高低电平由IC的电源低定。

推挽电路是两个参数相同的三极管或MOSFET,以推挽方式存在于电路中,各负责正负半周的波形放大任务,电路工作时,两只对称的功率开关管每次只有一个导通,所以导通损耗小、效率高。输出既可以向负载灌电流,也可以从负载抽取电流。推拉式输出级既提高电路的负载能力,又提高开关速度。

推挽放大器的输出级有两个“臂”(两组放大元件),一个“臂”的电流增加时,另一个“臂”的电流则减小,二者的状态轮流转换。对负载而言,好像是一个“臂”在推,一个“臂”在拉,共同完成电流输出任务。当输出高电平时,也就是下级负载门输入高电平时,输出端的电流将是下级门从本级电源经VT3拉出。这样一来,输出高低电平时,VT3 一路和 VT5 一路将交替工作,从而减低了功耗,提高了每个管的承受能力。又由于不论走哪一路,管子导通电阻都很小,使RC常数很小,转变速度很快。因此,推拉式输出级既提高电路的负载能力,又提高开关速度。

开漏输出模式:

输出端相当于三极管的集电极. 要得到高电平状态需要上拉电阻才行. 适合于做电流型的驱动,其吸收电流的能力相对强(一般20ma以内).

开漏形式的电路有以下几个特点:

1.利用外部电路的驱动能力,减少IC内部的驱动。当IC内部MOSFET导通时,驱动电流是从外部的VCC流经R pull-up ,MOSFET到GND。IC内部仅需很下的栅极驱动电流。

2.一般来说,开漏是用来连接不同电平的器件,匹配电平用的,因为开漏引脚不连接外部的上拉电阻时,只能输出低电平,如果需要同时具备输出高电平的功能,则需要接上拉电阻,很好的一个优点是通过改变上拉电源的电压,便可以改变传输电平。比如加上上拉电阻就可以提供TTL/CMOS电平输出等。(上拉电阻的阻值决定了逻辑电平转换的沿的速度。阻值越大,速度越低功耗越小,所以负载电阻的选择要兼顾功耗和速度。)

3.OPEN-DRAIN提供了灵活的输出方式,但是也有其弱点,就是带来上升沿的延时。因为上升沿是通过外接上拉无源电阻对负载充电,所以当电阻选择小时延时就小,但功耗大;反之延时大功耗小。所以如果对延时有要求,则建议用下降沿输出。

4.可以将多个开漏输出的Pin,连接到一条线上。通过一只上拉电阻,在不增加任何器件的情况下,形成“与逻辑”关系。这也是I2C,SMBus等总线判断总线占用状态的原理。补充:什么是“线与”?:

在一个结点(线)上,连接一个上拉电阻到电源VCC或VDD和n个NPN或NMOS晶体管的集电极C或漏极D,这些晶体管的发射极E或源极S都接到地线上,只要有一个晶体管饱和,这个结点(线)就被拉到地线电平上.因为这些晶体管的基极注入电流(NPN)或栅极加上高电平(NMOS),晶体管就会饱和,所以这些基极或栅极对这个结点(线)的关系是或非NOR逻辑.如果这个结点后面加一个反相器,就是或OR逻辑.

其实可以简单的理解为:在所有引脚连在一起时,外接一上拉电阻,如果有一个引脚输出为逻辑0,相当于接地,与之并联的回路“相当于被一根导线短路”,所以外电路逻辑电平便为0,只有都为高电平时,与的结果才为逻辑1。

关于推挽输出和开漏输出   。

其中比较器输出高电平时下面的PNP三极管截止,而上面NPN三极管导通,输出电平VS+;当比较器输出低电平时则恰恰相反,PNP三极管导通,输出和地相连,为低电平。右边的则可以理解为开漏输出形式,需要接上拉。

复用开漏输出、复用推挽输出:可以理解为GPIO口被用作第二功能时的配置情况(即并非作为通用IO口使用)

浮空输入:

对于浮空输入,一直没找到很权威的解释,只好从以下图中去理解了

由于浮空输入一般多用于外部按键输入,结合图上的输入部分电路,我理解为浮空输入状态下,IO的电平状态是不确定的,完全由外部输入决定,如果在该引脚悬空的情况下,读取该端口的电平是不确定的。

上拉输入/下拉输入/模拟输入:
这几个概念很好理解,从字面便能轻易读懂。
 

硬件——nrf51822第一篇,GPIO的使用的更多相关文章

  1. 硬件——nrf51822第二篇,如何设置keil用来下载程序

    转自电子发烧友论坛 未完,待续...... 这里就是根据自己的项目了,并不一定是按照下面的图片去做.

  2. 从0开始搭建SQL Server AlwaysOn 第一篇(配置域控)

    从0开始搭建SQL Server AlwaysOn 第一篇(配置域控) 第一篇http://www.cnblogs.com/lyhabc/p/4678330.html第二篇http://www.cnb ...

  3. IIS负载均衡-Application Request Route详解第一篇: ARR介绍(转载)

    IIS负载均衡-Application Request Route详解第一篇: ARR介绍 说到负载均衡,相信大家已经不再陌生了,本系列主要介绍在IIS中可以采用的负载均衡的软件:微软的Applica ...

  4. PHP 性能分析第一篇: Xhprof & Xhgui 介绍

    [前言]这是国外知名博主 Davey Shafik所撰写的 PHP 应用性能分析系列的第一篇,阅读第二篇可深入了解 xhgui,第三篇则关注于性能调优实践. 什么是性能分析? 性能分析是衡量应用程序在 ...

  5. Core Animation 文档翻译 (第一篇)

    Core Animation 文档翻译(第一篇)   2018-01-13  星期6 前言:作为iOS 开发,官方文档的阅读是很有必要的,值此周末便写下此文.作为iOS 实际经验3年的开发,之前的应用 ...

  6. Core Animation文档翻译 (第一篇)

    Core Animation 文档翻译(第一篇) 前言 作为iOS 开发,官方文档的阅读是很有必要的,值此周末便写下此文.作为iOS 实际经验3年的开发,之前有阅读并实践过经典的<iOS核心动画 ...

  7. shell第一篇

    前两天不停的再看内核相关的内容,了解内核的形成.内核的执行流程.内核的作用,结果是舍近求远. 其实我只是想了解一下shell的工作,shell与内核有关,但并不需要我么真正去做什么,至少对于我这样额初 ...

  8. 阿里云一 第一篇:云服务器ECS

    阿里云(www.aliyun.com)创立于2009年,是全球领先的云计算及人工智能科技公司,为200多个国家和地区的企业.开发者和政府机构提供服务.截至2017年3月,阿里云付费云计算用户达87.4 ...

  9. Python编程笔记(第一篇)Python基础语法

    一.python介绍 1.编程语言排行榜 TIOBE榜 TIOBE编程语言排行榜是编程语言流行趋势的一个指标,每月更新,这份排行榜排名基于互联网有经验的程序员.课程和第三方厂商的数量. 2.pytho ...

随机推荐

  1. jquery点击弹框外层关闭弹框

    $(document).bind("click",function(e){            if($( e.target ).closest(".game-cont ...

  2. [Python] Use Python Classes

    Object oriented classes work much like classes in other languages. Learn how to create them and use ...

  3. 《SAS编程与数据挖掘商业案例》学习笔记之十六

    <SAS编程与数据挖掘商业案例>学习笔记,本次重点:sas宏变量 内容包含:宏变量.宏函数.宏參数.通配函数.字符函数.计算函数.引用函数.宏语句.宏应用 1.宏触发器: %name-to ...

  4. Reuse Is About People and Education, Not Just Architecture

     Reuse Is About People and Education, Not Just Architecture Jeremy Meyer you MigHT AdopT THE AppRoA ...

  5. OpenCV —— 图像局部与分割(二)

    分水岭算法 将图像中的边缘转化成“山脉”,将均匀区域转化为“山谷” 分水岭算法首先计算灰度图像的梯度,这对山谷或没有纹理的盆地(亮度值低的点)的形成有效,也对山头或图像中没有主导线段的山脉(山脊对应的 ...

  6. c# 装箱与拆箱的概念

    1装箱 就是将值类型的数据赋值给引用类型的实例中 比如 int类型的123赋值给Object o int i=123; Object o=(Object) i; 2拆箱 就是从引用类型的数据中提取数据 ...

  7. Centos 7 JDK验证 解决java -version 报错: bash: /home/jdk1.8.0_161/bin/java: Permission denied

    2.vim /etc/profile  编辑profile  文件,在里面添加: #set java enviroment JAVA_HOME=/usr/java/jdk1.8.0_144 JRE_H ...

  8. CSDN的个人主页如何添加微信二维码

    -–零-– 对于CSDN,这里是技术的交流的地方,有些大神,隐于此.各有各的技能,各有各的魅力. 在这里,如果有自己的能力,你想推广你个人.我想,你将你的微信二维码或者你的微信公众号的二维码放在这里, ...

  9. 【t038】&&【u214】金字塔

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 小X来到一个雄奇的金字塔挖宝,但是这是一座被诅咒的金字塔,小X必须马上逃离这里,否则小X就会被埋在金字 ...

  10. ELK+KAFKA安装部署指南

    一.ELK 背景 通常,日志被分散的储存不同的设备上.如果你管理数十上百台服务器,你还在使用依次登录每台机器的传统方法查阅日志.这样是不是感觉很繁琐和效率低下.当务之急我们使用集中化的日志管理,例如: ...