TMS2833X之GPIO外设中断的控制

1.外设中断寄存器说明

F2833x系列可支持7个外部中断,分别是XINT1-XINT7,每个外部中断可以选择上升沿或下降沿触发,且可以被使能或禁止。
GPIO外部中断寄存器主要有选择寄存器(GPIOXINTnSEL)控制寄存器(XINTnCR)(n=1~7)

1.1 选择寄存器

选择寄存器GPIOXINTnSEL的含义如下图所示:
在这里插入图片描述在这里插入图片描述

  • GPIOXINTnSEL16位寄存器的0-4位数值表示所选择的的外部中断GPIO口
  • GPIO0-31引脚可选择的外部中断XINT1或者XINT2,GPIO32-63号引脚可选择外部中断XINT3~7
  • 选择寄存器和配置寄存器相互对应,如GPIOXINT1SEL对应XINT1CR
1.2 配置寄存器

选择寄存器XINTnCR的含义如下图所示:
在这里插入图片描述

  • XINTnCR16位寄存器的0位数值表示外部中断的使能信号,0表示不使能,1表示使能
  • XINTnCR16位寄存器的2~3位表示中断信号的极性选择,0表示下降沿触发,1表示上升沿触发
  • 配置寄存器所配置的对象为选择寄存器选择的中断,二者相互对应,如GPIOXINT1SEL对应XINT1CR

2.代码实例

下面通过外部GPIO中断触发LED灯的实例来进行说明。硬件电路如下如所示:
在这里插入图片描述在这里插入图片描述
其中:

  • TZ1连接GPIO12
  • TZ2连接GPIO13
  • EQEP1A连接GPIO50
  • LED灯组D8-D14分别对应的GPIO引脚为GPIO60/GPIO61/GPIO64~68

当按下或松开按键SW3时,EQEP1A的高低电平信号会触发TZ1有一个高低电平变化的信号,从而可以触发外部GPIO中断,操作LED灯以某种变化点亮或熄灭,同理,当按下或松开按键SW6时,EQEP1A的高低电平信号会触发TZ2有一个高低电平变化的信号。代码实现如下:

// 中断服务子程序声明
interrupt void xint1_isr(void);
interrupt void xint2_isr(void);

// 全局变量定义;
volatile Uint32 Xint1Count; //发生外部中断1的次数;
volatile Uint32 Xint2Count; //发生外部中断2的次数;
volatile Uint32 Xint2Loop;  //给外部中断2的for循环变量

#define keyon1 GpioDataRegs.GPADAT.bit.GPIO12       
#define keyon2 GpioDataRegs.GPADAT.bit.GPIO13

#define DELAY 35.700L

void main(void)
{
// 步骤 1. 初始化系统控制:
// 设置PLL, WatchDog, 使能外设时钟
 InitSysCtrl();
 
 EALLOW;
        //初始化GPIO50
        GpioCtrlRegs.GPBPUD.bit.GPIO50 = 0;   		// 使能 GPIO50 引脚上拉
        GpioDataRegs.GPBCLEAR.bit.GPIO50 = 1;           // GPIO50引脚复位
        GpioCtrlRegs.GPBMUX2.bit.GPIO50 = 0;  		// GPIO50定义为输入输出
        GpioCtrlRegs.GPBDIR.bit.GPIO50 = 1;   	        // GPIO50 用于输出
 EDIS;


 DINT;                                // 禁止CPU全局中断

// 初始化PIE控制寄存器到他们的默认状态,禁止PIE中断及清除所有PIE中断标志 
 InitPieCtrl();

// 禁止CPU中断和清除所有CPU中断标志 
 IER = 0x0000;
 IFR = 0x0000;

// 初始化PIE中断向量表,并使其指向中断服务子程序(ISR)
 InitPieVectTable();

// 用到的中断重新映射到定义的中断服务子程序; 
 EALLOW;	 // 修改被保护的寄存器,修改前应添加EALLOW语句
 PieVectTable.XINT1 = &xint1_isr;
 PieVectTable.XINT2 = &xint2_isr;
 EDIS;           // EDIS的意思是不允许修改被保护的寄存器

// 清除计数器
 Xint1Count = 0; // 计数外部中断1(XINT1)
 Xint2Count = 0; // 计数外部中断2(XINT2) 

// 在外设中断扩展模块中断使能寄存器中允许XINT1和XINT2: (PIE组1中断4 & 5)
// 使能CPU中断1(INT1):
 PieCtrlRegs.PIECTRL.bit.ENPIE = 1;          // 使能外设中断扩展PIE模块
 PieCtrlRegs.PIEIER1.bit.INTx4 = 1;          // 使能PIE组1的INT4
 PieCtrlRegs.PIEIER1.bit.INTx5 = 1;          // 使能PIE组1的INT5   
 IER |= M_INT1;                              // 使能CPU中断1(INT1)
 EINT;                                       // 开全局中断

// GPIO60-61,GPIO64-68 功能选择为通用I/O口,并输出高电;
 EALLOW;
 GpioDataRegs.GPBSET.bit.GPIO60 = 1;         // 输出高电平
 GpioCtrlRegs.GPBMUX2.bit.GPIO60 = 0;        // 选择为通用I/O口
 GpioCtrlRegs.GPBDIR.bit.GPIO60 = 1;         // 方向定义为输出

 GpioDataRegs.GPBSET.bit.GPIO61 = 1;         // 输出高电平
 GpioCtrlRegs.GPBMUX2.bit.GPIO61 = 0;        // 选择为通用I/O口
 GpioCtrlRegs.GPBDIR.bit.GPIO61 = 1;         // 方向定义为输出

 GpioDataRegs.GPCSET.all = 0x001F;          // GPIO64-66输出高电平
 GpioCtrlRegs.GPCMUX1.all = 0x0000;         // GPIO64-68选择为通用I/O口
 GpioCtrlRegs.GPCDIR.all = 0x0001F;         // GPIO64-68方向定义为输出
 EDIS;
 
// GPIO12和GPIO13配置为输入引脚通用I/O口
 EALLOW;
 GpioCtrlRegs.GPAMUX1.bit.GPIO12 = 0;         // 选择为通用I/O口
 GpioCtrlRegs.GPADIR.bit.GPIO12 = 0;          // 方向定义为输入
 GpioCtrlRegs.GPAQSEL1.bit.GPIO12 = 0;        // 外部中断1(XINT1)与系统时钟SYSCLKOUT同步

 GpioCtrlRegs.GPAMUX1.bit.GPIO13 = 0;         // 选择为通用I/O口
 GpioCtrlRegs.GPADIR.bit.GPIO13 = 0;          // 方向定义为输入
 GpioCtrlRegs.GPAQSEL1.bit.GPIO13 = 2;        // 外部中断2(XINT2)输入限定6个采样窗口
 GpioCtrlRegs.GPACTRL.bit.QUALPRD1 = 0xFF;    // 每个采样窗口的周期为510*SYSCLKOUT 
 EDIS;

// 通过GPIO外部中断选择寄存器,选择GPIO10为外部中断1,选择GPIO11为外部中断2
 EALLOW;
 GpioIntRegs.GPIOXINT1SEL.bit.GPIOSEL = 0x0C;   // XINT1是GPIO12
 GpioIntRegs.GPIOXINT2SEL.bit.GPIOSEL = 0x0D;   // XINT2是GPIO13
 EDIS;

// 配置外部中断1和2的中断控制寄存器
 XIntruptRegs.XINT1CR.bit.POLARITY = 0;      // 下降沿触发中断
 XIntruptRegs.XINT2CR.bit.POLARITY = 0;      // 下降沿触发中断
 
// 使能外部中断1和外部中断2
 XIntruptRegs.XINT1CR.bit.ENABLE = 1;        // 使能XINT1
 XIntruptRegs.XINT2CR.bit.ENABLE = 1;        // 使能XINT2
 
// 步骤6. 无限循环:	
 for(;;);
  
} 	

//步骤7.在这里插入中断服务子程序,如果需要使用中断服务子程序,必须在步骤5中重新定义中断
//向量表中对应地地址
interrupt void xint1_isr(void)
{
  Uint32 i;
  for(i=0;i<1000000;i++);    //键盘消抖动
  while(keyon1==0);
  GpioDataRegs.GPBTOGGLE.all = 0x30000000;   // GPIO60-GPIO61输出电平取反
  GpioDataRegs.GPCTOGGLE.all = 0x001F;       // GPIO64-GPIO68输出电平取反
  Xint1Count++;
  	
  // 应答寄存器的位1清0,以响应同组内其他中断;
  PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}

interrupt void xint2_isr(void)
{
  Uint32 i;
  for(Xint2Loop=1;Xint2Loop<=8;Xint2Loop++)
  {
    GpioDataRegs.GPBTOGGLE.all = 0x30000000;   // GPIO60-GPIO61输出电平取反
    GpioDataRegs.GPCTOGGLE.all = 0x001F;   // GPIO64-GPIO68输出电平取反
    DELAY_US(100000);  //延时0.1s
  }

  Xint2Count++;
  	for(i=0;i<1000000;i++);    //键盘消抖动
  while(keyon2==0);
  
  // 应答寄存器的位1清0,以响应同组内其他中断;
  PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}
  • 从子程序实例可以看出,当按下按键SW3时,LED灯不变化,灯松开时,灯由亮变灭,或由灭变亮,当按下按键SW4时,LED灯立即以较快的频率反复亮灭几次。

最后,附上一张2812中的外部中断在PIE中的分组表,其他相关知识,可参考DSP2812之中断系统
在这里插入图片描述

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值