GPIO全称叫做General-Purpose Input/Output,即通用输入/输出口。是单片机和外界交流的重要部件,你可能看到过没有ADC的单片机、没有定时器的单片机或者没有串口的单片机,但是没有GPIO的单片机是不存在的。

本篇教程不会过多去讲解电路层面的原理,但会用实例演示GPIO的各方面特性。

首先让我们看看本篇教程用到的开发板——Bread board。

一块和面包板“天衣无缝”结合的开发板

在电路上,将一个LED的正极接到P3.7脚,负极接到GND。准备就绪后,打开之前建好的工程,接着打开gpio.h。

在控件界面里,能看到两个设置组。一个是Px口使能,推荐只有在ROM空间不够的情况才关掉不用的Px口使能。我之前遇到过,为了优化空间关掉了P2的使能,结果把模块接到P2口上死活也通信不了,卡了一天才发现P2使能没打开。二是深度优化,用于把不需要的gpio库函数优化掉,理由同第一点,没事别优化!

在上图中,我们可以看到gpio库一共有10个函数。接下来我们一一讲解。

  • gpio_write:这是一个8位IO口写函数,可以一次性写入8位数据。gpio_write(GPIO_P0,0x06);的效果其实等同P0=0x06;其实该函数的作用主要还是提供给其他并口通信的外设库使用。
  • gpio_read:这是一个8位IO口读函数,可以一次性读整个P口8个脚的数据。val=gpio_read(GPIO_P0);的效果等同于val=P0;所以就算是我,也会因为字数原因懒得用。不过它与直接用val=P0;的最大区别就是:读取的Px口作为函数的参数是可以在程序运行的时候修改的。因此在外设库使用该函数,就能在应用中切换P口而不用去改函数定义区里的代码了。
  • gpio_in/gpio_out:既然说到I/O,当然核心就是这两个函数啦。这两个函数主要用于读取某一个IO口的电平值和写某一个IO口的电平值。gpio_out(D10,1);等同于P11=1;flag=gpio_in(D10);等同于flag=P10;和上面一样,做成库函数的最大优点,便是IO作为参数,可以随意切换,甚至在单片机运行时切换都可以(具体的例子在解说外设库的复用性时详细说明)。
  • gpio_toggle:IO电平的翻转函数,假设某个IO口原来是高电平,翻转之后就变成了低电平。反之亦然。
  • gpio_in_fast/gpio_out_fast/gpio_toggle_fast:这三个函数是上面列举的那三个的快速运行版,只会用在外设库中,学习本教程的时候可以不用管他们。.

以上就是gpio的操作函数。那么究竟使用它们为了操作什么呢?这就不得不说数字电路的一个特性了(电路基础稳固的人可以跳过这一段):数字电路里只有两个明确状态——0和1。0和1是一个虚拟的概念,是我们人为定义出来的。比如TTL电平里+5V代表1,+0V代表0。而在232电平里-12V代表1,+12V代表0。在文中提到的开发板里,由于板载单片机工作在3.3V,所以1代表+3.3V,操作IO输出1就是让IO输出+3.3V的高电平;0代表+0V,操作IO输出0就是让IO输出+0V的低电平。因为数字电路就是围绕着1和0设计的,所以只要单片机按一定规律输出1或者0就能控制数字电路!

还记得文章开头的LED吗?LED点亮的条件就是正极接VCC,负极接GND,且正负极压差大于LED压降(一般LED压降为1.8V~3.0V)。那么如果你想点亮LED,在这个电路中,只要使P3.7脚输出高电平3.3V就行了。那么立刻用库函数写一遍吧:

#include "ecbm_core.h"  //加载库函数的头文件。
void main(){        //main函数,必须的。system_init();  //系统初始化函数,也是必须的。gpio_out(D37,1);//就是这一句啦,让P3.7口输出高电平3.3V。while(1){}
}

需要注意的参数的形式为Dxx型,就是说P3.7口就是D37,P2.5口就是D25。运行结果如下:

小灯已经开始发出原谅的绿光了

那如果P3.7脚输出0呢?那么P3.7脚的电压将会是0V,而LED两端都是0V,LED就不会亮了。

细心的你可能发现了,这LED的亮度根本不够看,没注意的话根本看不到它在发光(我在拍摄的时候也特意降低了曝光值才勉强让它的亮度看起来明显一些)。这就设计到IO工作模式了。当年工程师也发现了这些问题,所以为IO口在不同环境下的应用设计了不同的模式。在8051单片机中一共有4种。(为了照顾新手的理解能力,我不会去说高深的电路知识。)

  1. 弱上拉模式:这是一种最常用的模式。所谓“上拉”,就是指把IO电平“拉”到电源VCC。“下拉”当然就是指把IO电平“拉到”地GND。当IO独立的时候,一切都好理解。但是当两个IO连在一起的时候呢?如果一个IO输出高电平,另一个输出低电平,那么连起来会是什么电平呢?这种感觉就像是拔河,一个IO把电平往VCC拉,另一个IO把电平往GND拉。如果两个势均力敌的话,可能到2090年都不会有结果。所以为了让电平明确,必须让其中一个更“”一些。当初的设计者们选择了让“上拉”的能力弱一些。这样再来竞争的时候,电平会立刻被更强的“下拉”拉到低电平。所以该模式适合单片机与外界的双向通行。
  2. 推挽模式:“推挽”这个名字来源于“推挽电路”,换成我们的理解,就是“上拉”能力和“下拉”能力都强!当时的设计者也知道,弱上拉模式虽然解决了竞争问题,但是如果驱动的电路里没有竞争,又特别需要高电平驱动呢?于是推挽模式就出来了,它和弱上拉的区别就是加强了上拉能力,因此适用于驱动被动元件(就比如本篇提到的驱动LED灯)或者和外界的单向通信(只输出不输入)。
  3. 高阻模式:有些朋友可能要问了,上面两个模式都会使得IO上有一个确定的电平,那么这个电平会不会影响到我要读取的信息呢?这个确实是有可能的,如果某个电路设计不好或者导线阻值影响等因素导致了目标信号的对上拉和下拉都很敏感,那么IO的默认电平是会有影响的。又或者一个带ADC的单片机,想读目标器件输出的电压值,那么这个电压值被IO的电平这么一拉,就不是原来的值了。针对这种情况,高阻模式被设计出来。它的特点就是断开了所有上下拉电路,使得IO不输出电平值。没错,“高阻”并不是让IO输出电压为0V,那个叫输出低电平。高阻就是什么都不输出,即不输出高电平也不输出低电平。就好像IO口和电源VCC、地GND之间被什么东西“阻断”了一样。因此这个模式主要是用于输入的。同时由于它什么都不输出的特性,也会用在端口复用上,保证端口不会被上下拉影响。
  4. 开漏模式:和推挽一样,“开漏”这个名字也是来源于内部电路构造的名字。其实就是把IO的上拉能力“废掉”,只保留下拉能力。这样做的目的之一就是电压匹配,可能大家在之前都看过一些教单片机的书籍,里面用的单片机都是工作在5V的。那么5V的单片机要和我现在的3.3V单片机通信怎么办?5V单片机输出高电平的话,就是输出+5V,这都大于了3.3V单片机的工作电压了,闹不好就得烧芯片。但是如果5V单片机处于开漏模式就安全了(同时3.3V单片机使用弱上拉模式,并输出高电平),当5V单片机输出高电平的时候,由于上拉能力没有了,连线的电平会被3.3V单片机拉到+3.3V。当5V单片机输出低电平的时候,由于下拉能力还在,而3.3V单片机是弱上拉模式,那么连线电平会被拉到低电平。这样一来,连线上的电平就不会超过3.3V单片机的电源,就不会烧坏单片机了。

四种模式都讲解完了,那么能解决LED亮度的问题的办法就出来了。既然亮度低的原因是上拉能力太弱,那么只要把P3.7口切换到推挽模式就可以了。

两个参数,一个是要设置的IO口,一个是IO的模式。IO模式的定义可以参考宏定义:

所以代码更改如下:

#include "ecbm_core.h" //加载库函数的头文件。
void main(){            //main函数,必须的。system_init();      //系统初始化函数,也是必须的。gpio_mode(D37,GPIO_PP);//推挽模式。 gpio_out(D37,1);  //就是这一句啦,让P3.7口输出高电平3.3V。while(1){}
}

运行效果如下:

啊,原谅的光芒更加闪耀了呢。

最后一个函数gpio_uppull其实用处不大,仅在某些应用会用到,比如IIC通信要求IO是开漏模式同时外接上拉电阻。而STC8内置了上拉电阻,可以节省一些元件钱。该函数就是用来打开和关闭上拉电阻的。在IIC章的时候会说明它。

对于这篇文章,还有什么不懂的问题呢?欢迎留言告诉我。

预告:下一篇文章中,会讲解外部中断的应用,敬请期待。

uboot更改gpio电平_ECBM系列教程4:单片机的手和脚——GPIO相关推荐

  1. #中delay函数_ECBM系列教程3:闪烁灯——delay函数的用法。

    上一篇文章中,教大家如何点亮一个LED.这一篇文章就教大家如何让LED闪烁. LED闪烁的原理其实很简单,先让LED亮起来,延时一段时间后熄灭,然后再亮起来就可以了.就是亮--延时--灭--延时--亮 ...

  2. keil如何添加h文件_ECBM系列教程1:如何搭建ECBM库环境。

    STC8属于8051单片机,发展到现在已经是带流水线的版本了,不过依然还是支持8051的指令集.因此任何支持8051的IDE都可以用来开发STC8单片机. 不过由于ECBM库的一些特性,我们只使用KE ...

  3. 小熊派IoT开发板系列教程正式发布——免费学习

    小熊派介绍 小熊派IoT开发板一款由南京厚德物联网有限公司联合华为技术有限公司基于STM32L431RCT6设计的高性能物联网开发板.开发板充分考虑物联网感知层设备的多样性,具有强大的可扩展性,用于提 ...

  4. STM32 基础系列教程 2 - GPIO 按键输入

    前言 学习stm32 GPIO 的使用,实现简单的按键输入功能,用按键的高低来控制LED的亮灭! 示例详解 基于硬件平台: STM32F10C8T6最小系统板, MCU 的型号是 STM32F103c ...

  5. STM32 基础系列教程 1- CubeMX+GPIO

    前言 学习stm32 GPIO 的使用,设置某一GPIO引脚为输出功能,将对应引脚拉高或拉低输出,同时学会初步认识STM32最新的HAL库的使用, 用代码实现控制GPIO引脚输出产生周期出1s 占空比 ...

  6. abp更改为mysql_ABPZero系列教程之拼多多卖家工具 更改数据库为MySQL数据库

    本文主要向大家介绍了ABPZero系列教程之拼多多卖家工具 更改数据库为MySQL数据库 ,通过具体的内容向大家展现,希望对大家学习MySQL数据库有所帮助. < 因为要部署项目到云服务器,不想 ...

  7. 痞子衡嵌入式:对比恩智浦全系列MCU(包含Kinetis/LPC/i.MXRT/MCX)的GPIO电平中断设计差异...

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦全系列MCU(包含Kinetis, LPC, i.MXRT, MCX)的GPIO电平中断设计差异. 在痞子衡旧文 <以i.M ...

  8. I.MX6ULL 官方 U-Boot 移植系列教程 1 —— 前期准备

    文章目录 前言 一.搭建开发环境 二.获取官方资料 1. 获取官方开发板资料 2. 获取官方 U-Boot 源码 总结 前言 去年入手了一块正点原子的 I.MX6U-ALPHA 开发板,跟着其配套的指 ...

  9. TWEN-ASR ONE 语音识别系列教程(1)--- 运行第一个程序

    TWEN-ASR ONE 语音识别系列教程(1)- 运行第一个程序 提示:作者使用 TWEN-ASR ONE V1.0开发板进行开发学习. 文章目录 前言 一.TWEN-ASR开发板介绍 二.程序编写 ...

最新文章

  1. Xamarin.iOS提供没有匹配的配置文件
  2. 无惧秋招,您的NLP算法工程师魔鬼训练计划请查收
  3. PHP的pathinfo()
  4. 66319d电源使用说明书_蒸汽熨斗怎么用 蒸汽熨斗使用方法及注意事项【介绍】...
  5. vue设置标签自定义属性_Vue组件化开发之插槽
  6. xib 设置阴影_影响uiview阴影的约束?
  7. Vue路由 --登录状态的判断
  8. 并发视频,怎么hold住高并发
  9. Python中变量的命名以及输入输出
  10. 卷积神经网络多输入和多输出
  11. 微信支付商户平台开通流程
  12. 弹簧(压簧)力度计算与设计
  13. 计算机蓝牙快捷键,笔记本蓝牙快捷键是什么_怎么打开笔记本电脑蓝牙-win7之家...
  14. mysql constraint primary key_SQL PRIMARY KEY 约束
  15. golang并发http请求几种方式
  16. bat如何获取当前Windows系统的桌面路径
  17. 水牛城大学计算机科学,【揭秘】美国纽约州立水牛城大学计算机科学与工程专业申请条件有哪些?...
  18. [微积分笔记]第二类曲线/面积分总结
  19. IFS系统功能清单之五——制造(Manufacturing)
  20. 《PyInstaller打包实战指南》第二节 PyInstaller的两种打包模式

热门文章

  1. 解决使用CoreData时报duplicate symbol错误问题
  2. jQuery 基础总结
  3. 挖掘频繁模式、关联和相关
  4. mutt+msmtp+gmail
  5. 中国六个漂亮的古镇风景名胜区网站欣赏
  6. 如何利用jquery实现一句话全选/取消全选的实例代码
  7. PCL库VTK显示点云法向时出错:no override found for vtkActor
  8. 【题解】Luogu SP1435 PT07X - Vertex Cover
  9. NSNumber 以及NSInteger,NSNumber以及Int的区别
  10. 有关Java中json字符串与map的转换使用