| 一、GPIO 
   刚开始学习单片机时就是从点灯开始,很清晰地记得那时候还是看天翔大哥的视频来跑流水灯,那时候还是大二,现在已是研二,时间似流水。 
   要想点灯,还是要对I/O口进行控制,51好像就是直接P1^0 = 1,即可置高,而在越高级的单片机中,需要配置的东西就比较多了,我记得32中就需要配置I/O口的方向,速度,以及是否上拉等等,在DSP这么高级的东西需要配置的东西也不少。 
   首先看下GPIO的一个描述: General  purpose  input / output,即通用输入/输出。不想增加芯片的引脚数,又想增加芯片的功能,那不可避免地要用到引脚的复用功能。功能复用的引脚可以通过MUX寄存器来进行功能的选择,如果选择为普通的数字I/O功能,可以通过GPXDIR寄存器来控制引脚的方向,你也可以通过GPXQSELn 和GPACTRL 和GPBCTRL寄存器配置采样窗的宽度进而去除输入信号的一些高频噪声。28335共有3个32位的I/O接口,PortA Contain GPIO0---GPIO31;PortB contain GPIO32---GPIO63;PortC contain GPIO64---GPIO87。
  接下来看下他的一个内部结构图,每一组的内部结构图不是太一致,不过整体的结构类似。如下 
 
 
   分析这个信号的一个流向: 
   INPUT: 首先正常工作时,XRS为高电平,不影响输入输出,输入过来先经过一个GPAPUD,对其进行上拉或者不上拉,然后通过GPASEL1/2对其配置成同步或异步模式;同步模式时可以选择采样窗的大小,这样可以有效地去除干扰,然后就送到了内部,这时候通过GPAMUX1/2将其送往不同的外设模块。与此同时,GPIO0-27可以配置成外部中断1/2,从而触发中断。 
   OUTPUT: 正常工作时,XRS高电平,故输出只由GPAMUX1/2选择不同的外设模块,进而将其数据输出。 
 
   输入状态时,如何有效滤除干扰??采用采样窗,他的一个工作原理如下: 
   这个采样窗可以用在普通的I/O口和外设的输入引脚,同时外设的输入引脚也可以配置成异步输入。配置成异步输入的模块如下:SCI、SPI、eCAN、I2C、以及ePWM模块的TZ1--6信号。当采样异步输入时,此时采样窗无效。一般引脚复位后默认的量化模式是所有的引脚和SYSCLKOUT同步。 
 
 过程:首先由GPXCTRL寄存器中的QUALPRDn来决定采样周期sample period。QUALPRDn是一个八位的数据,最大可以是2^8=256。当数据为零时,此时采样周期为Tsysclkout;当数据不为零时,此时采样周期=2*GPXCTRL[QUALPRDn]*Tsysclkout。 
 接下来由GPAQSEL1/2来确定采样窗的大小,采样窗即采样几次,共三张选择,可以将图1,采样1/3/6次;当采样3次时,整个采样窗的宽度是2 × 2 × GPxCTRL[QUALPRDn] × TSYSCLKOUT。当采样6次时,采样窗的宽度是5 × 2 × GPxCTRL[QUALPRDn] × TSYSCLKOUT; 如上例,设置采样窗宽度为SYSCLKOUT cycle * 2 * QUALPRD) * 5。此时只有当六次采样都是同一电平时,此时最后才会输出这一电平,当中间有一个毛刺时,该毛刺的宽度不超过采样窗的宽度就被舍弃,认为该信号无效。那是不是这个采样窗的宽度越大越好那???个人觉得并不是,此时导致经过采样窗的信号已经滞后于原始信号采样窗宽度的时间,对于一些实时性要求比较高的系统,这个采样窗的设计一定要仔细。 这接下来就是一个gpio的一个操作步骤:1、通过GPxMUX寄存器确定引脚的功能。是作为普通I/O还是作为某种外设引脚。
 2、若是作为普通I/O,通过GPXDIR来设定引脚方向,是作为输入还是输出。 3、若是作为输入,考虑下是否需要上拉。引脚默认情况下是上拉的,除了ePWM模块未使能。 4、以及考虑采样窗的宽度。 5、最后考虑是否需要产生外部中断,注意:只有PortA 和 PortB可以产生外部中断。GPIO0--31可以产生XINT1/2以及XNMI;GPIO32--63可以产生XINT3/4/5/6/7。 程序部分:在DSP2833x_headers文件夹下的include文件下,可以看到DSP2833x_Gpio.h,在该头文件中对一些寄存器进行了定义,可以看到其实是通过结构体来对寄存器中的某些位进行索引,感觉和32的库函数有点相似,不过感觉没有32的简洁。 extern volatile struct GPIO_CTRL_REGS GpioCtrlRegs;extern volatile struct GPIO_DATA_REGS GpioDataRegs;
 extern volatile struct GPIO_INT_REGS GpioIntRegs;
 
 这是我们经常需要用到的几个  通过GpioCtrlRegs对GPIO的一些控制寄存器进行配置操作;通过GpioDataRegs对GPIO的数据寄存器操作;通过GpioIntRegs对中断寄存器进行操作。
 例如我们经常用到的一句话的解释
 GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0X00;                //GPIO功能
 他是如何实现该功能的那??其实就是层层控制,有点像中国的分封制
 其实GpioCtrlRegs代表一个结构体,如下所示:
 struct GPIO_CTRL_REGS {
 union  GPACTRL_REG  GPACTRL;   // GPIO A Control Register (GPIO0 to 31)
 
 //
 // GPIO A Qualifier Select 1 Register (GPIO0 to 15)
 //
 union  GPA1_REG     GPAQSEL1;
 
 //
 // GPIO A Qualifier Select 2 Register (GPIO16 to 31)
 //
 union  GPA2_REG     GPAQSEL2;
 
 //
 // GPIO A Mux 1 Register (GPIO0 to 15)
 //
 union  GPA1_REG     GPAMUX1;
 
 //
 // GPIO A Mux 2 Register (GPIO16 to 31)
 //
 union  GPA2_REG     GPAMUX2;
 
 union  GPADAT_REG   GPADIR;    // GPIO A Direction Register (GPIO0 to 31)
 
 //
 // GPIO A Pull Up Disable Register (GPIO0 to 31)
 //
 union  GPADAT_REG   GPAPUD;
 
 Uint32              rsvd1;
 union  GPBCTRL_REG  GPBCTRL;   // GPIO B Control Register (GPIO32 to 63)
 
 //
 // GPIO B Qualifier Select 1 Register (GPIO32 to 47)
 //
 union  GPB1_REG     GPBQSEL1;
 
 //
 // GPIO B Qualifier Select 2 Register (GPIO48 to 63)
 //
 union  GPB2_REG     GPBQSEL2;
 
 union  GPB1_REG     GPBMUX1;   // GPIO B Mux 1 Register (GPIO32 to 47)
 union  GPB2_REG     GPBMUX2;   // GPIO B Mux 2 Register (GPIO48 to 63)
 union  GPBDAT_REG   GPBDIR;    // GPIO B Direction Register (GPIO32 to 63)
 
 //
 // GPIO B Pull Up Disable Register (GPIO32 to 63)
 //
 union  GPBDAT_REG   GPBPUD;
 
 Uint16              rsvd2[8];
 union  GPC1_REG     GPCMUX1;   // GPIO C Mux 1 Register (GPIO64 to 79)
 union  GPC2_REG     GPCMUX2;   // GPIO C Mux 2 Register (GPIO80 to 95)
 union  GPCDAT_REG   GPCDIR;    // GPIO C Direction Register (GPIO64 to 95)
 
 //
 // GPIO C Pull Up Disable Register (GPIO64 to 95)
 //
 union  GPCDAT_REG   GPCPUD;
 };
 
 
 
 union GPA1_REG {Uint32              all;
 struct GPA1_BITS    bit;
 };
 
 
 
 struct GPA1_BITS {             // bits   descriptionUint16 GPIO0:2;            // 1:0    GPIO0 
    Uint16 GPIO1:2;            // 3:2    GPIO1 
    Uint16 GPIO2:2;            // 5:4    GPIO2 
    Uint16 GPIO3:2;            // 7:6    GPIO3 
    Uint16 GPIO4:2;            // 9:8    GPIO4 
    Uint16 GPIO5:2;            // 11:10  GPIO5 
    Uint16 GPIO6:2;            // 13:12  GPIO6 
    Uint16 GPIO7:2;            // 15:14  GPIO7 
    Uint16 GPIO8:2;            // 17:16  GPIO8 
    Uint16 GPIO9:2;            // 19:18  GPIO9 
    Uint16 GPIO10:2;           // 21:20  GPIO10 
    Uint16 GPIO11:2;           // 23:22  GPIO11 
    Uint16 GPIO12:2;           // 25:24  GPIO12 
    Uint16 GPIO13:2;           // 27:26  GPIO13 
    Uint16 GPIO14:2;           // 29:28  GPIO14 
    Uint16 GPIO15:2;           // 31:30  GPIO15 
};
 
就是结构体的一个嵌套,TI把它写好了,咱们只需要进行调用就行了,但是,前提是,这个索引是没有错误的,当你用这种方法时就已经默认了TI提供的.H文件无错,不过基本不会有错的哈~~~
 
接下来就是一个控制LED的C文件以及H文件
 
void LED_Init(void) 
{ 
        EALLOW;                        //将引脚设置为通用I/O    并且设置为输出 
        GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0X00;                //GPIO功能 
        GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 0X00;                //GPIO功能 
        GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 0X00;                //GPIO功能
 
        GpioCtrlRegs.GPADIR.bit.GPIO0 = 1;                        //设置为输出 
        GpioCtrlRegs.GPADIR.bit.GPIO1 = 1;                        //设置为输出 
        GpioCtrlRegs.GPADIR.bit.GPIO2 = 1;                        //设置为输出 
        EDIS;
 
        /*初始化为高电平    即所有LED均灭*/ 
        GpioDataRegs.GPASET.bit.GPIO0 = 1;                        //置高 
        GpioDataRegs.GPASET.bit.GPIO1 = 1;                        //置高 
        GpioDataRegs.GPASET.bit.GPIO2 = 1;                        //置高
 
}
 
#ifndef LED_H 
#define LED_H
 
#define LED2_ON GpioDataRegs.GPASET.bit.GPIO0 
#define LED3_ON GpioDataRegs.GPASET.bit.GPIO1 
#define LED4_ON GpioDataRegs.GPASET.bit.GPIO2
 
#define LED2_OFF GpioDataRegs.GPACLEAR.bit.GPIO0 
#define LED3_OFF GpioDataRegs.GPACLEAR.bit.GPIO1 
#define LED4_OFF GpioDataRegs.GPACLEAR.bit.GPIO2
 
#define LED2_TOGGLE GpioDataRegs.GPATOGGLE.bit.GPIO0 
#define LED3_TOGGLE GpioDataRegs.GPATOGGLE.bit.GPIO1 
#define LED4_TOGGLE GpioDataRegs.GPATOGGLE.bit.GPIO2
 
void LED_Init(void);
 
#endif  // end of LED_H definition
                                                                                                                                                         smtudou                                                                                                                                                           2017/10/25 
 
 |