通用输入/输出(GPIO)

声明:文章内容都是我在学习过程中的个人理解,然而本人水平有限,难免会存在错误,有错误还请海涵。
一、GPIO概述

        对于任何一种微处理器,我们想要它和外部的一些设备进行连接时,我们都是通过GPIO来连接的,我们可以简单的将他们理解为芯片的引脚。而对于F28335来说,它将所有的GPIO分为了A(GPIO0~GPIO31)、B(GPIO32~GPIO63)、C(GPIO64~GPIO87)三组。这些引脚的功能往往都是不止一个,因为一些外设的输入输出(例如ADC、SPI等)往往都是复用在GPIO上的。

二、GPIO输出

        这张图就是GPIO的框图,其中用蓝色笔圈出来的是GPIO的输出部分。

  1. 首先看序号1。既然每一个GPIO可以作为输入和输出,那么总得告诉芯片这个GPIO当前是作为输入还是输出吧。选择输入还是输出就是通过GPxDIR这个寄存器来决定的,当这个寄存器位0的时候表示输入,为1的时候便是输出。当然了,由于每一个GPIO都需要单独数值,因此对于A组引脚,GPIO一共有32个,所以GPADIR一共有32位,每一位分别设置对应GPIO是输出还是输出。其他组的GPIO也类似。
  2. 然后我们再来看序号2。我们在前面说了,每一个GPIO都用不止一个功能,而对于F28335来说,每一个引脚最多只能有四个功能(它们分别是普通IO、外设1、外设2、外设3)。和输入输出一样,我们也需要告诉芯片这个引脚是什么功能。因此,我们通过GPxMUX1/2这两个寄存器来告诉芯片,00表示普通IO、01表示外设1、10表示外设2、11表示外设3。为什么需要两个寄存器呢?因为每个GPIO有四个功能,那么我们至少需要2bit才能将他们表示出来(00,01,10,11),我们同样用GPIOA来举例子。GPIOA一共有32个引脚,每个引脚2bit,那么就一共需要64个bit。我们将它分成两个32bit的寄存器。GPxMUX1用来设置GPIO0~GPIO15,GPxMUX2用来设置GPIO16~GPIO31。其他组的GPIO也类似。
  3. 最后我们再来看序号3。这个表示GPIO数据寄存器GPxDAT,它的每一位表示这个引脚是高电平还是低电平。对于输出模式,我们常常对这个寄存器进行写操作。同样是通过GPxMUX1/2来选择数据来自于普通的GPIO还是另外三个外设。这里和2相同,不多赘述。而GPxSET的某一位为1的时候就表示将这个引脚设置为高电平,当它为0时表示对这个GPIO不进行操作。GPxCLEAR的某一位为1的时候就表示将这个引脚设置为低电平,当它为0时表示对这个GPIO不进行操作。GPxTOGGLE的某一位为1的时候就表示对这个引脚的电平取反(当前为高电平就将它设置为低电平,当前为低电平就将它设置为高电平),当它为0时表示对这个GPIO不进行操作。
  4. 接下来我们就通过一个GPIO来举例子,其余的GPIO类似。
    void GPIO_Init(void)
    {
    	EALLOW;//关闭写保护
    
    	SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1;    // 开启GPIO时钟
    
    
    	//GPIO68端口配置
    	GpioCtrlRegs.GPCMUX1.bit.GPIO68=0;//设置为通用GPIO功能
    //	GpioCtrlRegs.GPCMUX1.bit.GPIO68=1;//设置为外设1功能
    //	GpioCtrlRegs.GPCMUX1.bit.GPIO68=2;//设置为外设2功能
    //	GpioCtrlRegs.GPCMUX1.bit.GPIO68=3;//设置为外设3功能
    	
    	GpioCtrlRegs.GPCDIR.bit.GPIO68=1;//设置GPIO方向为输出
    //	GpioCtrlRegs.GPCDIR.bit.GPIO68=0;//设置GPIO方向为输入
    
    	GpioCtrlRegs.GPCPUD.bit.GPIO68=0;//使能GPIO上拉电阻
    //	GpioCtrlRegs.GPCPUD.bit.GPIO68=1;//失能GPIO上拉电阻
    
    
    	//对GPIO写数据1
    	GpioDataRegs.GPCSET.bit.GPIO68=1;  //设置GPIO输出高电平,写0无效
    //	GpioDataRegs.GPCCLEAR.bit.GPIO68=1;//设置GPIO输出低电平,写0无效
    //	GpioDataRegs.GPCTOGGLE.bit.GPIO68=1;//设置GPIO翻转电平,写0无效
    
    	EDIS;//开启写保护
    }

三、GPIO输入

输入相比于输出就要复杂一点,在图中,使用蓝色笔圈出来的就是GPIO的输部分。

  1. 首先来看序号1。GPIO引脚进来过后,第一个就是一个“PU”。这个PU就是是否使用上拉的意思。当这一位为0的时候表示上拉(即默认电平为高电平),为1时表示不使用上拉(默认电平未知)。
    	GpioCtrlRegs.GPCPUD.bit.GPIO68=0;//使能GPIO上拉电阻
    //	GpioCtrlRegs.GPCPUD.bit.GPIO68=1;//失能GPIO上拉电阻
  2. 然后我们再来看序号2。当引脚的电平进入到芯片过后,芯片可以对这个信号做一个预处理,也可以不做,也就是我们所说的同步(Sync)和异步(async)。我个人觉得可以简单地将同步理解为CPU当中有一个同步寄存器,这个同步寄存器存储着GPIO的数据。但是这个数据并不是随时随地都在改变的,它只有在每个系统周期内才会根据外部的实际电平来设置这个同步寄存器的数据,而且一个周期只会设置一次,因此它得到的数据是时域连续,值域离散的信号。而异步就不同了,异步可以理解为没有上述的同步寄存器,直接将当前的引脚电平传到后续电路,因此它得到的信号是模拟信号,有一些外设需要设置为异步,比如ADC。从框图我们不难看出,数据到达后面一共有四条路径选择。它们分别是default on reset(这也是当我们不做任何设置系统默认的处理方式)、3 samptes、6samptes、async。其中default on reset、3 samptes和6  samptes都是同步的方式,因此有上述说的同步寄存器。对于default on reset就是将同步寄存器的数据直接传到后续电路当中;3 samptes方式则是再次对同步寄存器进行采样,这个采样周期由GPxCTRL寄存器来设置。如果在连续的三个周期内,引脚电平持续不变,那么就认为这个电平为当前的输入电平,否则将这个信号认为是噪声,引脚电平保持之前的状态。6 samptes方式和3 samptes方式类似,唯一的区别就是引脚电平信号需要持续六个采样周期不变才不会被认为是噪声。最后,我们还需要告诉CPU我们采用的方式是同步还是异步,这个通过设置寄存器GPxQSEL1/2来实现。总结一下就是采样频率由GPxCTRL来决定,GPxQSEL1/2决定采用的是同步还是异步(00:default on reset;01:3 samptes;10:6 samptes;11:async)。
  3. 接着我们再来看3。由于某一些GPIO可以用来做中断,因此也需要对中断进行设置。序号3就是用来配置中断的。我们讨论到中断再说。
  4. 最后我们来看4。它其实就是GPIO数据寄存器,存放着经过前面一系列处理所得到的最终的数据。一般在输入情况下,我们都是对这个寄存器进行读操作,每一位表示对应GPIO的数据。

  • 13
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值