最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 正文

GPIO及其应用举例

来源:动视网 责编:小OO 时间:2025-10-01 18:24:00
文档

GPIO及其应用举例

第四章GPIO多路复用器及其应用举例4.1F2812端口概述DSPF2812提供了56个多功能引脚,这些引脚像单片机的P3端口一样,具有第二功能。一方面,这些引脚作为片内某些资源的输入或输出引脚,实现片内某些外设功能。另一方面,在片内外设功能不被使能情况下,该端口又可以作为一般的输入输出端口使用,实现普通I/O口输入或输出高低电平信号的功能。以GPIOF0_GPIOF4为例,当片内SPI外设被使能时,上述引脚作为SPI接口的数据通讯引脚使用,GPIOF2作为SPICLKA,为SPI通讯的时钟脉
推荐度:
导读第四章GPIO多路复用器及其应用举例4.1F2812端口概述DSPF2812提供了56个多功能引脚,这些引脚像单片机的P3端口一样,具有第二功能。一方面,这些引脚作为片内某些资源的输入或输出引脚,实现片内某些外设功能。另一方面,在片内外设功能不被使能情况下,该端口又可以作为一般的输入输出端口使用,实现普通I/O口输入或输出高低电平信号的功能。以GPIOF0_GPIOF4为例,当片内SPI外设被使能时,上述引脚作为SPI接口的数据通讯引脚使用,GPIOF2作为SPICLKA,为SPI通讯的时钟脉
第四章   GPIO多路复用器及其应用举例

4.1   F2812端口概述

DSP F2812提供了56个多功能引脚,这些引脚像单片机的P3端口一样,具有第二功能。一方面,这些引脚作为片内某些资源的输入或输出引脚,实现片内某些外设功能。另一方面,在片内外设功能不被使能情况下,该端口又可以作为一般的输入输出端口使用,实现普通I/O口输入或输出高低电平信号的功能。以GPIOF0_GPIOF4为例,当片内SPI外设被使能时,上述引脚作为SPI接口的数据通讯引脚使用,GPIOF2作为SPICLKA,为SPI通讯的时钟脉冲信号,用来输出或输入时钟信号,GPIOF0作为SPIMOSIA,用来作为SPI口的从机输入主机输出端口。在SPI外设功能不被使能时,该四个端口作为普通的输入输出I/O口使用。

F2812的GPIO多路复用器在将有关引脚用作数字I/O时,将端口分为五组,组成两个16位的数字I/O口GPIOA和GPIOB;组成一个15位的数字I/O口GPIOF。4位的数字I/O口GPIOD;一个3位的数字I/O口GPIOE。如下图所示。

图4.1   GPIO多路复用端口

4.2 GPIO控制寄存器

F2812的多功能端口作为GPIO端口使用时,可以通过使用GPIO的有关寄存器可以选择和控制这些共享引脚的操作。例如:通过GPxMUX寄存器可以把这些引脚作为数字I/O或片内外设I/O口。如果选择某个引脚作为数字I/O口,则可以通过GPxDIR寄存器来设置引脚的方向;另外,可以通过GPxQUAL寄存器来改善输入信号,有效的消除输入信号的毛刺脉冲的干扰。

每个GPIO通过功能控制、方向、数据、设置、清除和反转触发寄存器来控制。

GPxMUX寄存器——

每个I/O口都有一个功能选择寄存器,用来配置I/O工作在外设操作模式或数字量I/O模式。例如:存储器映像寄存器GPAMUX(0x70C0,容量16位),作为GPIOA组端口的功能选择寄存器。GPBMUX(0x70C4,容量16位)为GPIOB口功能选择寄存器。

复位期间所有GPIO配置成I/O功能。

GPxMUX.bit = 0,配置成I/O功能;

GPxMUX.bit = 1,配置成外设功能;

GPxDIR寄存器——

每个I/O口都有方向控制寄存器,用来配    置I/O的方向。复位时,所有GPIO位输入。

GPxDIR.bit = 0,引脚配置为数字量输入;

GPxDIR.bit = 1,引脚配置为数字量输出;

GPxDAT寄存器——

每个I/O口都有数据寄存器,如果I/O配置为输入,反映当前经过量化后I/O口的输入信号的状态。复位时,所有GPIO位输入。

GPxDAT.bit = 0,且引脚配置输出功能,将相应的引脚拉低;

GPxDAT.bit =1,且引脚配置输出功能,将相应的引脚拉高;

GPxQUAL寄存器

从GPxDAT寄存器读取的相应引脚状态,通过量化寄存器GPxQUAL量化输入信号,消除外部噪声。

GPxQUAL寄存器用来量化采样周期;

采样窗口是6个采样周期宽度,只有当所有采样的数据相同时,输出才会改变。

这个功能可以有效地消除输入信号的毛刺脉冲的干扰。

图4.2  GPxQUAL寄存器量化采样

4.3 GPIO应用举例——8×8LED点阵控制

应用DSP的GPIO端口控制输出数据,控制8×8点阵进行图形或字符显示。

4.3.1 硬件电路设计

电路如下图所示。741为串行输入并行输出移位寄存器。设计中,选择两片741分别控制点阵模块的行和列,控制数据从DSP端口输出。其中,GPIOF0输出数据与U1的741的A端口相连,GPIOF1与B口连接,两个端口用来输出对点阵进行显示控制的数据,GPIOF2输出模拟时钟脉冲信号,与741的CLK引脚相连,GPIOF3连接CLR清零端。DSP F2812的GPIOB0---GPIOB3与另外一片741的A、B、CLR、CLK对应相连。如图所示。

图4.3  8×8点阵电路图

4.3.1.1  8×8点阵内部电路

点阵内部为排列的8×8个发光二极管,每一个二极管都在行线和列线的交点处,要同时受到行和列的控制才能点亮。二极管阵列的正向端分别由COL1-COL8端口控制,负向端通过端口ROW1-ROW8控制。在驱动某个点阵点点亮时,需要同时控制该发光二极管正端接高电平,负端接低电平即可。例如:要使得COL4和ROW4交点处二极管点亮,则需要在端口COL端输入数据:00001000(08H),在ROW端输入:00001000(08H)。

图4.4   8×8点阵内部电路

4.3.1.2 串行输入并行输出移位寄存器741功能

如图所示为741的引脚图,CLEAR为清零端,CLOCK为时钟脉冲输入端,A、B端口为串行输入数据引脚, Q0—Q7为数据输出引脚。

从真值表可以看出,CLEAR为逻辑低电平时,无论其他引脚电平信号如何,从QA-QH端口输出均为低电平,实现输出清零。 A、B输入信号为相与的关系,相与后的结果送入内部RS触发器。在CLOCK脉冲信号的上升沿,采样输入脚A、B相与后的结果,作为内部RS触发器的输入信号,根据输入数据触发输出,从QA端口输出。在QA端口输出更新数据时,QB端口输出数据为QA端口更新前的QAn,QC端口输出数据为QBn,依次类推。

图4.5  741引脚图

图4.6  741内部电路

以如下时序图为例说明:

    在图中标注的时钟脉冲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。从而,实现了将串行输入数据并行输出的功能。

图4.7   741时序图

4.3.2 程序分析

    主程序主要包括系统初始化、中断向量初始化、设置GPIO端口、控制数据传输几个步骤。

4.3.2.1 设置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;   }

需要注意:

EALLOW——

在DSP28_Device.h头文件中,通过“#define     EALLOW    asm(" EALLOW")”在C语言主函数中嵌入汇编语言指令,汇编指令“EALLOW”其含义为开放存储器映像寄存器,设置该命令后,可以对MMR内容进行修改。当需要配置或修改MMR内容时,必须先写入EALLOW汇编指令。反之,如果不首先写入EALLOW汇编指令,无法完成对相应MMR内容的修改。

EDIS:为结束修改MMR的汇编命令。当MMR配置完成后,需要写入该命令。

4.3.2.2  控制数据串行输出函数

void sendto1(unsigned char kdab)

{    unsigned char i;

     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脚模拟输出一个时钟脉冲信号,将

                                    //串行端口数据输出一位。

kdab=kdab>>1; //数据右移,提取下一位串行数据

     }     

}

    741为串行输入/并行输出移位寄存器,控制点阵的数据需要从DSP的gpio端口串行输出。为满足741工作时序,采用GPIO端口模拟741的工作时序。从DINC输出串行输出数据,同时,在CLK1脚模拟控制脉冲信号。 

图4.8  串行数据输出控制

    串行数据传输函数如上所示。函数变量dab为需要传输的串行数据。例如:需要传输的数据dab为1111 0011(F3H),如下图所示。通过变量dab同二进制数0x01相与,将要传输数据的最低位取出。kdab&0x01结果为1时,则表示传输数据的最低位1。然后,将判别后的数据送入DINC即GPIOF0端口,经过硬件电路连接,从而传到U1的741的A端口。然后,在程序中应用“CLK1=1; CLK1=0;”命令, 将CLK1即GPIOF2模拟产生时钟脉冲信号,根据741时序图,在时钟上升沿将送到A端口的数据移位输出。之后,将传输数据右移位,判别次低位数据,kdab&0x01结果为1时,则表示传输数据的最低位1, kdab&0x01结果为0时,则表示传输数据的最低位0。模拟产生脉冲,控制数据移入741。经过8次循环,则将8位数据串行输出到741的端口,并行输出到输出端口。

4.3.2.3 输出字符与字模阵列

图4.9  字模提取软件

     在点阵模块中字符的显示,应用字模生成软件获得显示字符的字模,采用动态扫描的控制方式显示。

以在点阵模块显示字符“中”为例,首先采用字模提取软件获得字符的字模。“中”字的字模组合为“10H,FEH,92H,FEH,10H,10H,10H,10H”。

     在控制显示时,采用动态扫描的显示方式。首先将字模中二进制数10H送入点阵模块的行扫描数据输入端口,然后在列扫描线上输出控制第一行点阵二极管点亮的数据“0111 1111”,则点阵中第一行的第四个二极管点亮,显示“中”字上面的一点。接下来,将“FEH” 送入点阵模块的行扫描数据输入端口,然后在列扫描线上输出控制第二行点阵二极管点亮的数据“1011 1111”,此时,第二行的1-7二极管点亮,显示出“中”字的上面一横,之前第一行的第四个二极管灭。继续,行端口输入“92H”,列端口输入控制第三行二极管点亮的控制信号“1101 1111”,于是,在第三行上1、4、7二极管亮,其他行灭。依次类推,直到第八行显示。

     在控制显示中,每一行逐次轮回显示,由于人本身有的视觉暂留效应,我们只要适当控制每一行的显示延时,就可以将要显示的字符“中”字动态的显示在点阵模块中。

在编写程序中,我们采用数组数组dispdata[]存放行值,用数组dispbit[]存放列值。dispdata[8]={0x10,0xFE,0x92,0xFE,0x10,0x10,0x10,0x10}, dispbit[8]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe},用两个函数sendto1(dispbit[])和sendto2(dispdata[])分别发送数据,由此显示出字模。

调整延时程序——

void DELAY()

{    unsigned long k,j;

for(k=0;k<10;k++)

for(j=0;j<100;j++);

}

由于扫描速度很快,扫描8列的数据在人眼看来是同时的,所以就可以看到8_8LED字模中显示的字模。

4.3.3 参考主程序:

#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();                 //设置端口函数

    

    /*************************初始化741各控制引脚**************************/

CLEAR2=0;        //741进行清零操作

    CLEAR1=0;        //741进行清零操作

    CLEAR2=1;        //741复位

    CLEAR1=1;        //741复位

CLK1=1;           //741的CLOCK引脚置为高电平

CLK2=1;           //741的CLOCK引脚置为高电平

    DINA=1;           //741数据输入端口置为高电平

    DINB=1;           //741数据输入端口置为高电平

    DINC=1;           //741数据输入端口置为高电平

    DIND=1;           //741数据输入端口置为高电平

    

    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脚模拟输出一个时钟脉冲信号,将

                                    //串行端口数据输出一位。

kdab=kdab>>1; //数据右移,提取下一位串行数据

     }     

}

/****************列扫描数据串行输出函数***************************/

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脚模拟输出一个时钟脉冲信号,将

                                    //串行端口数据输出一位。

kdab=kdab>>1; //数据右移,提取下一位串行数据

     }     

}

 

=====================================================================

======================================================================

文档

GPIO及其应用举例

第四章GPIO多路复用器及其应用举例4.1F2812端口概述DSPF2812提供了56个多功能引脚,这些引脚像单片机的P3端口一样,具有第二功能。一方面,这些引脚作为片内某些资源的输入或输出引脚,实现片内某些外设功能。另一方面,在片内外设功能不被使能情况下,该端口又可以作为一般的输入输出端口使用,实现普通I/O口输入或输出高低电平信号的功能。以GPIOF0_GPIOF4为例,当片内SPI外设被使能时,上述引脚作为SPI接口的数据通讯引脚使用,GPIOF2作为SPICLKA,为SPI通讯的时钟脉
推荐度:
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top