当前位置:文档之家› GPIO

GPIO

F2812 I/O配置与应用浅析GPIO,英文全称为General-Purpose IO ports,也就是通用IO口。

嵌入式系统中常常有数量众多,但是结构却比较简单的外部设备/电路,对这些设备/电路有的需要CPU为之提供控制手段,有的则需要被CPU用作输入信号。

而且,许多这样的设备/电路只要求一位,即只要有开/关两种状态就够了,比如灯亮与灭。

对这些设备/电路的控制,使用传统的串行口或并行口都不合适。

所以在微控制器芯片上一般都会提供一个“通用可编程IO接口”,即GPIO。

接口至少有两个寄存器,即“通用IO控制寄存器”与“通用IO数据寄存器”。

数据寄存器的各位都直接引到芯片外部,而对这种寄存器中每一位的作用,即每一位的信号流通方向,则可以通过控制寄存器中对应位独立的加以设置。

这样,有无GPIO接口也就成为微控制器区别于微处理器的一个特征。

一、 F2812 I/O端口概述F2812提供了56个多功能引脚,这些引脚的第一功能是作为通用意义数字I/O口(GPIO),而第二功能则可以作为片内外设的输入/输出引脚。

F2812通过专门的多路选择器(MUX)进行引脚功能的选择。

如果作为通用数字I/O口,有专门的方向寄存器用于配置引脚作为输入还是输出,另外还有专门的数据寄存器、置位寄存器、清零寄存器以及触发寄存器用于对I/O口的状态进行读取或配置。

GPIO 引脚分配GPIO AGPIOA0 / PWM1 GPIOA1 / PWM2 GPIOA2 / PWM3 GPIOA3 / PWM4 GPIOA4 / PWM5 GPIOA5 / PWM6 GPIOA6 / T1PWM_T1CMP GPIOA7 / T2PWM_T2CMP GPIOA8 / CAP1_QEP1 GPIOA9 / CAP2_QEP2 GPIOA10 / CAP3_QEPI1 GPIOA11 / TDIRA GPIOA12 / TCLKINA GPIOA13 / C1TRIP GPIOA14 / C2TRIP GPIOA15 / C3TRIPGPIO BGPIOB0 / PWM7 GPIOB1 / PWM8 GPIOB2 / PWM9 GPIOB3 / PWM10 GPIOB4 / PWM11 GPIOB5 / PWM12 GPIOB6 / T3PWM_T3CMP GPIOB7 / T4PWM_T4CMP GPIOB8 / CAP4_QEP3 GPIOB9 / CAP5_QEP4 GPIOB10 / CAP6_QEPI2 GPIOB11 / TDIRBGPIOB12 / TCLKINBGPIOB13 / C4TRIPGPIOB14 / C5TRIPGPIOB15 / C6TRIPGPIO DGPIOD0 / T1CTRIP_PDPINTA GPIOD1 / T2CTRIP / EVASOC GPIOD5 / T3CTRIP_PDPINTB GPIOD6 / T4CTRIP / EVBSOC GPIO EGPIOE0 / XINT1_XBIO GPIOE1 / XINT2_ADCSOC GPIOE2 / XNMI_XINT13 GPIO FGPIOF0 / SPISIMOAGPIOF1 / SPISOMIAGPIOF2 / SPICLKAGPIOF3 / SPISTEAGPIOF4 / SCITXDAGPIOF5 / SCIRXDAGPIOF6 / CANTXAGPIOF7 / CANRXAGPIOF8 / MCLKXAGPIOF9 / MCLKRAGPIOF10 / MFSXAGPIOF11 / MFSRAGPIOF12 / MDXAGPIOF13 / MDRAGPIOF14 / XFGPIO GGPIOG4 / SCITXDBGPIOG5 / SCIRXDBNote: GPIO are pinfunctions at reset GPIO A, B, D, E include Input Qualification feature二、GPIO寄存器控制2、1 GPxMUX寄存器通用输入输出多路选择寄存器I/O是工作在通用数字IO还是外围IO信号引脚就有GPxMUX决定。

GPxMUX.bit.xx=0,xx通用数字IO;GPxMUX.bit.xx=1,xx外围IO引脚。

2、2 GPxDIR寄存器方向选择寄存器如果配置为通用数字IO脚,那么GPxDIR决定了该引脚是输入还是输出。

GPxDIR.bit.xx=0,xx配置为输入;GPxDIR.bitxx=1,xx配置为输出。

2、3 GPxQUAL寄存器设置采样脉冲寄存器在配置为通用数字IO后,DSP的数字IO引脚有对输入过滤噪声的功能,即对IO输入电平采样,在采样设置的次数后都是一个电平,才会确定有效。

假如设置为输入高电平,采样10次,那么这10都为高电平才认为输入高有效,GPxDAT寄存器相应位才会改变。

它是一个16位的寄存器,低八位有效。

GPxQUAL=0;与SYSCLKOUT同步,没有限制作用GPxQUAL=1;2个SYSCLKOUT周期采样,GPxQUAL=2;4个SYSCLKOUT周期采样,GPxQUAL=0xff;510个SYSCLKOUT周期采样,2、4 GPxSET置1寄存器每个IO口有一个置1寄存器,只能写不能读,也就是只能用在输出上,写1可以使输出为1,写0没有变化。

GPxSET .bit.xx=0,被忽略;GPxSET .bit.xx=1,且引脚配置为输出,则输出变高2、5 GPxCLEAR清0寄存器每个IO口有一个清0寄存器,只能写不能读,也就是只能用在输出上,写1可以使输出清0,写0没有变化。

GPxCLEAR .bit.xx=0,被忽略;GPxCLEAR .bit.xx=1,且引脚配置为输出,则输出清02、6 GPxTOGGLE 翻转寄存器每个IO口有一个翻转寄存器,只能写不能读,也就是只能用在输出上,写1可以使输出翻转,写0没有变化。

GPxTOGGLE .bit.xx=0,被忽略;GPxTOGGLE.bit.xx=1,且引脚配置为输出,则输出翻转2、7 GPxDAT寄存器IO数据寄存器每个IO都有一个数据寄存器,当IO配置为输出时,相GPxDAT中写数据就可以决定输出状态;GPxDAT.bit.xx=0,输出变低;GPxDAT.xx=1,输出变高当IO配置为输入时,读取GPxDAT中的数据就可以决定输入状态;注意:当引脚配置为通用数字IO时,相应的外围功能必须屏蔽,否则可能会引发不必要的中断三、GPIO应用举例应用DSP的GPIO端口控制输出数据,控制8×8点阵进行图形或字符显示。

3、1硬件电路设计电路如下图所示。

74164为串行输入并行输出移位寄存器。

设计中,选择两片74164分别控制点阵模块的行和列,控制数据从DSP端口输出。

其中,GPIOF0输出数据与U1的74164的A端口相连,GPIOF1与B口连接,两个端口用来输出对点阵进行显示控制的数据,GPIOF2输出模拟时钟脉冲信号,与74164的CLK引脚相连,GPIOF3连接CLR清零端。

DSP F2812的GPIOB0---GPIOB3与另外一片74164的A、B、CLR、CLK对应相连。

如图所示。

图3.1 8×8点阵电路图3、2 8×8点阵内部电路点阵内部为排列的8×8个发光二极管,每一个二极管都在行线和列线的交点处,要同时受到行和列的控制才能点亮。

二极管阵列的正向端分别由COL1-COL8端口控制,负向端通过端口ROW1-ROW8控制。

在驱动某个点阵点点亮时,需要同时控制该发光二极管正端接高电平,负端接低电平即可。

例如:要使得COL4和ROW4交点处二极管点亮,则需要在端口COL 端输入数据:00001000(08H),在ROW端输入:00001000(08H)。

图3.2 8×8点阵内部电路3、3串行输入并行输出移位寄存器74164功能如图所示为74164的引脚图,CLEAR为清零端,CLOCK为时钟脉冲输入端,A、B端口为串行输入数据引脚, Q0—Q7为数据输出引脚。

从真值表可以看出,CLEAR为逻辑低电平时,无论其他引脚电平信号如何,从QA-QH端口输出均为低电平,实现输出清零。

A、B输入信号为相与的关系,相与后的结果送入内部RS触发器。

在CLOCK脉冲信号的上升沿,采样输入脚A、B相与后的结果,作为内部RS触发器的输入信号,根据输入数据触发输出,从QA端口输出。

在QA端口输出更新数据时,QB 端口输出数据为QA端口更新前的QAn,QC端口输出数据为QBn,依次类推。

图3.3 74164引脚图图3.4 74164内部电路以如下时序图为例说明:在图中标注的时钟脉冲1时刻,A端口输入为高电平,B端口输入为逻辑1,在CLOCK 上升沿,采样输入信号,经过内部RS触发器,在QA端口输出逻辑1,此时,QB输出为QA 更新前QAn,更新前QAn为逻辑0,因此,QB输出为0,QC输出为QBn,QD输出为QCn,依此类推,QH输出为QGn,输出均为0。

在图中标注的时钟脉冲1-8时刻,从A端口串行输入的数据为1101 0000,从B端口输入数据为1111 1111逻辑1,AB相与后输入内部RS触发器的串行数据为:1101 0000。

经过8个时钟脉冲后,从第八个时钟脉冲上升沿后QA-QH引脚电平可以看出,该串行数据从QA-QH端口并行输出,即从QH-QA输出电平为:1101 0000。

从而,实现了将串行输入数据并行输出的功能。

图3.5 74164时序图3、4参考主程序:#include "DSP28_Device.h"#include "DSP28_Globalprototypes.h"/*****************************************************************************端口GPIOF0用DINA表示,“#define”为宏定义,以下程序中用字符“DINA”代表成员变量GpioDataRegs.GPFDAT.bit.GPIOF0,增加程序的可读性。

其他端口定义用法相同。

***************************************************************************/#define DINA GpioDataRegs.GPFDAT.bit.GPIOF0#define DINB GpioDataRegs.GPFDAT.bit.GPIOF1#define CLK2 GpioDataRegs.GPFDAT.bit.GPIOF2#define CLEAR2 GpioDataRegs.GPFDAT.bit.GPIOF3#define DINC GpioDataRegs.GPBDAT.bit.GPIOB0#define DIND GpioDataRegs.GPBDAT.bit.GPIOB1#define CLK1 GpioDataRegs.GPBDAT.bit.GPIOB2#define CLEAR1 GpioDataRegs.GPBDAT.bit.GPIOB3/********程序中引用的函数定义**************/void delay_loop(void); //点阵动态显示控制的延时程序void Gpio_select(void); //GPIO端口设置程序void sendto1(unsigned char kdab); //串行数据输出函数,输出行扫描数void sendto2(unsigned char dat); //串行数据输出函数,输出列扫描数void DELAY(void);/**************定义变量数组*****************/unsigned char dispdata[8]={0x10,0xFE,0x92,0xFE,0x10,0x10,0x10,0x10};//显示字符“中”字的行扫描数组unsigned char dispbit[8]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe}//显示字符“中”字的列扫描数组unsigned char kdab;unsigned char kdat;/*************************主程序************************/void main(void){ unsigned char i;InitSysCtrl(); //系统初始化函数InitPieCtrl(); //初始化PIE模块到默认状态InitPieVectTable();Gpio_select(); //设置端口函数/*************************初始化74164各控制引脚**************************/ CLEAR2=0; //74164进行清零操作CLEAR1=0; //74164进行清零操作CLEAR2=1; //74164复位CLEAR1=1; //74164复位CLK1=1; //74164的CLOCK引脚置为高电平CLK2=1; //74164的CLOCK引脚置为高电平DINA=1; //74164数据输入端口置为高电平DINB=1; //74164数据输入端口置为高电平DINC=1; //74164数据输入端口置为高电平DIND=1; //74164数据输入端口置为高电平while(1){sendto1(dispbit[0]);sendto2(dispdata[0]);DELAY();sendto1(dispbit[1]);sendto2(dispdata[1]);DELAY();sendto1(dispbit[2]);sendto2(dispdata[2]);DELAY();sendto1(dispbit[3]);sendto2(dispdata[3]);DELAY();}}/***********************GPIO端口配置函数***************************/void Gpio_select(void){ EALLOW;GpioMuxRegs.GPBMUX.all=0x0000; //设置B组端口为GPIO功能GpioMuxRegs.GPBDIR.all=0xFFFF; // 设置B组端口为输出端口GpioMuxRegs.GPFMUX.all=0x0000; //设置F组端口为GPIO功能GpioMuxRegs.GPFDIR.all=0xFFFF ; // 设置F组端口为输出端口EDIS; }/****************行扫描数据串行输出函数***************************/void sendto1(unsigned char kdab){ unsigned char i;kdab=dab;CLK1=0; //控制时钟脉冲引脚输出设置为低电平for(i=0;i<8;i++) //经过八个时钟脉冲控制将八位串行数据输出 {if((kdab&0x01) == 0x01) //判别输出数据{DINC=1; //如果输出数据为1,将数据送入DINC输出}else DINC = 0; //如果输出数据为0,将数据送入DINC输出CLK1=1; //时钟引脚设置输出高电平CLK1=0; //时钟引脚恢复为低电平,通过这两个命令,//在CLK1脚模拟输出一个时钟脉冲信号,将//串行端口数据输出一位。

相关主题