未完,待续。。。。。。

本实现是基于一个开发箱,包括:综合应用开发系统主板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. Spring MVC学习总结(5)——SpringMVC项目关于安全的一些配置与实现方式

    目前越来越多的应用和网站,开始注重安全性的问题,关于我们的web项目的几个安全知识点,不得不讲解一下,这里我主要讲述关于tomcat如何支持HTTPS连接访问,RSA公钥和私钥的制作.这个对于我们整个 ...

  2. The incident LOST_EVENTS occured on the master. Message: error writing to the binary log, Error_code

    1 mysq error日志报错例如以下: 2014-05-12 11:29:54 22977 [ERROR] Slave SQL: The incident LOST_EVENTS occured ...

  3. C#定义变量

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  4. Onvif开发之服务端成功对接Rtsp视频流篇

    前面篇介绍onvif服务端的发现功能,继续在之前的代码基础上完成一个RTSP流的工作,也就是客户端通过ONVIF协议来预览设备端在这个之前必须确定几个简单的条件1 设备端能被发现2 设备端支持RTSP ...

  5. vue 打包成 apk 文件(修改路径)

    第一个坑:文件引用路径 现在项目我们什么都没动,是初始化之后直接打包的状态,打开dist/index.htmnl文件整个网页都是一片空白的. 爬坑: 打开 config文件夹/index.js文件 a ...

  6. ElasticSearch概述和定义

    福利 => 每天都推送 欢迎大家,关注微信扫码并加入我的4个微信公众号:   大数据躺过的坑      Java从入门到架构师      人工智能躺过的坑         Java全栈大联盟   ...

  7. javafx image zoom

    public class EffectTest extends Application { private final ImageView imageView = new ImageView(); p ...

  8. Exercise: PCA in 2D

    Step 0: Load data The starter code contains code to load 45 2D data points. When plotted using the s ...

  9. sessionStorage的使用方法

    本篇是关于sessionStorage的使用方法的介绍,简单几行代码,实现sessionStorage,请大家查阅 (1)在需要设置sessionStorage的页面写如下代码可以存入sessionS ...

  10. opencv标定程序(改动)

    转载请注明来自:http://blog.csdn.net/zhouyelihua/article/details/38421377 资源下载见:点击打开链接 百度云盘免积分下载:https://pan ...