硬件——nrf51822第一篇,GPIO的使用
未完,待续。。。。。。
本实现是基于一个开发箱,包括:综合应用开发系统主板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的使用的更多相关文章
- 硬件——nrf51822第二篇,如何设置keil用来下载程序
		转自电子发烧友论坛 未完,待续...... 这里就是根据自己的项目了,并不一定是按照下面的图片去做. 
- 从0开始搭建SQL Server AlwaysOn 第一篇(配置域控)
		从0开始搭建SQL Server AlwaysOn 第一篇(配置域控) 第一篇http://www.cnblogs.com/lyhabc/p/4678330.html第二篇http://www.cnb ... 
- IIS负载均衡-Application Request Route详解第一篇: ARR介绍(转载)
		IIS负载均衡-Application Request Route详解第一篇: ARR介绍 说到负载均衡,相信大家已经不再陌生了,本系列主要介绍在IIS中可以采用的负载均衡的软件:微软的Applica ... 
- PHP 性能分析第一篇: Xhprof & Xhgui 介绍
		[前言]这是国外知名博主 Davey Shafik所撰写的 PHP 应用性能分析系列的第一篇,阅读第二篇可深入了解 xhgui,第三篇则关注于性能调优实践. 什么是性能分析? 性能分析是衡量应用程序在 ... 
- Core Animation 文档翻译 (第一篇)
		Core Animation 文档翻译(第一篇) 2018-01-13 星期6 前言:作为iOS 开发,官方文档的阅读是很有必要的,值此周末便写下此文.作为iOS 实际经验3年的开发,之前的应用 ... 
- Core Animation文档翻译 (第一篇)
		Core Animation 文档翻译(第一篇) 前言 作为iOS 开发,官方文档的阅读是很有必要的,值此周末便写下此文.作为iOS 实际经验3年的开发,之前有阅读并实践过经典的<iOS核心动画 ... 
- shell第一篇
		前两天不停的再看内核相关的内容,了解内核的形成.内核的执行流程.内核的作用,结果是舍近求远. 其实我只是想了解一下shell的工作,shell与内核有关,但并不需要我么真正去做什么,至少对于我这样额初 ... 
- 阿里云一 第一篇:云服务器ECS
		阿里云(www.aliyun.com)创立于2009年,是全球领先的云计算及人工智能科技公司,为200多个国家和地区的企业.开发者和政府机构提供服务.截至2017年3月,阿里云付费云计算用户达87.4 ... 
- Python编程笔记(第一篇)Python基础语法
		一.python介绍 1.编程语言排行榜 TIOBE榜 TIOBE编程语言排行榜是编程语言流行趋势的一个指标,每月更新,这份排行榜排名基于互联网有经验的程序员.课程和第三方厂商的数量. 2.pytho ... 
随机推荐
- jquery点击弹框外层关闭弹框
			$(document).bind("click",function(e){ if($( e.target ).closest(".game-cont ... 
- [Python] Use Python Classes
			Object oriented classes work much like classes in other languages. Learn how to create them and use ... 
- 《SAS编程与数据挖掘商业案例》学习笔记之十六
			<SAS编程与数据挖掘商业案例>学习笔记,本次重点:sas宏变量 内容包含:宏变量.宏函数.宏參数.通配函数.字符函数.计算函数.引用函数.宏语句.宏应用 1.宏触发器: %name-to ... 
- 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 ... 
- OpenCV —— 图像局部与分割(二)
			分水岭算法 将图像中的边缘转化成“山脉”,将均匀区域转化为“山谷” 分水岭算法首先计算灰度图像的梯度,这对山谷或没有纹理的盆地(亮度值低的点)的形成有效,也对山头或图像中没有主导线段的山脉(山脊对应的 ... 
- c# 装箱与拆箱的概念
			1装箱 就是将值类型的数据赋值给引用类型的实例中 比如 int类型的123赋值给Object o int i=123; Object o=(Object) i; 2拆箱 就是从引用类型的数据中提取数据 ... 
- 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 ... 
- CSDN的个人主页如何添加微信二维码
			-–零-– 对于CSDN,这里是技术的交流的地方,有些大神,隐于此.各有各的技能,各有各的魅力. 在这里,如果有自己的能力,你想推广你个人.我想,你将你的微信二维码或者你的微信公众号的二维码放在这里, ... 
- 【t038】&&【u214】金字塔
			Time Limit: 1 second Memory Limit: 128 MB [问题描述] 小X来到一个雄奇的金字塔挖宝,但是这是一座被诅咒的金字塔,小X必须马上逃离这里,否则小X就会被埋在金字 ... 
- ELK+KAFKA安装部署指南
			一.ELK 背景 通常,日志被分散的储存不同的设备上.如果你管理数十上百台服务器,你还在使用依次登录每台机器的传统方法查阅日志.这样是不是感觉很繁琐和效率低下.当务之急我们使用集中化的日志管理,例如: ... 
