TMS320F28069-外部中断学习

本文介绍了TMS320x2806x微控制器的外部中断配置过程,包括中断初始化、中断使能及中断服务程序等内容。通过实例详细解析了如何设置GPIO作为中断源并实现中断触发。

下面通过官方的一个外部中断例程讲解外部中断,所参考的文档为TMS320x2806x Piccolo Technical Reference Manual (Rev. H)
在这里插入图片描述下面先通过该例程的代码进行学习探索,并且都有根据自己的理解添加了注释。


#include  "DSP28x_Project.h"

volatile  Uint32  Xint1Count;
volatile  Uint32  Xint2Count;
Uint32  LoopCount;
#define DELAY (CPU_RATE/1000*6*510)  //Qual period at 6 samples
void  External_Interrupt_Init(void)
{
 // Enable INT1 which is connected to WAKEINT:
  PieCtrlRegs.PIECTRL.bit.ENPIE=1;         //使能中断
  PieCtrlRegs.PIEIER1.bit.INTx4=1;         //使能INT1.4中断
  PieCtrlRegs.PIEIER1.bit.INTx5=1;         //使能INT1.4中断
  IER|=M_INT1;                             //使能CPU中断
  EINT;

  EALLOW;
  // GPIO32 & GPIO33 are outputs, start GPIO32 high and GPIO33 low
  GpioDataRegs.GPBSET.bit.GPIO32=1;       //初始化输出拉高
  GpioCtrlRegs.GPBMUX1.bit.GPIO32=0;      //设置为普通的IO
  GpioCtrlRegs.GPBDIR.bit.GPIO32=1;       //定义为输出

  GpioDataRegs.GPBSET.bit.GPIO33=1;       //初始化输出拉高
  GpioCtrlRegs.GPBMUX1.bit.GPIO33=0;      //设置为普通的IO
  GpioCtrlRegs.GPBDIR.bit.GPIO33=1;       //定义为输出

  GpioDataRegs.GPBSET.bit.GPIO34=1;       //初始化输出拉高
  GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0;        // GPIO
  GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1;         // output
  EDIS;

  EALLOW;

  // GPIO0 and GPIO1 are inputs
  GpioCtrlRegs.GPAMUX1.bit.GPIO0=0;      //设置普通的IO
  GpioCtrlRegs.GPADIR.bit.GPIO0=0;       //设置为输入
  GpioCtrlRegs.GPAQSEL1.bit.GPIO0=0;     //设置为与系统时钟同步

  GpioCtrlRegs.GPAMUX1.bit.GPIO1=0;      //设置普通的IO
  GpioCtrlRegs.GPADIR.bit.GPIO1=0;       //设置为输入
  GpioCtrlRegs.GPAQSEL1.bit.GPIO1=2;     //设置为6倍采样时间
  GpioCtrlRegs.GPACTRL.bit.QUALPRD0=0xff;//每倍采样时间为510*SYSCLKOUT;

  EDIS;
  // GPIO0 is XINT1, GPIO1 is XINT2
  EALLOW;
  GpioIntRegs.GPIOXINT1SEL.bit.GPIOSEL=0;     //定义GPIO为XINT1的来源
  GpioIntRegs.GPIOXINT2SEL.bit.GPIOSEL=1;     //定义GPIO1为XINT2的来源
  EDIS;


  // Configure XINT1 and XINT2
  XIntruptRegs.XINT1CR.bit.POLARITY=0;      //定义为下降沿触发
  XIntruptRegs.XINT2CR.bit.POLARITY=1;      //定义为上升沿触发
  // Enable XINT1 and XINT2
  XIntruptRegs.XINT1CR.bit.ENABLE=1;        //使能XINT1
  XIntruptRegs.XINT2CR.bit.ENABLE=1;        //使能XINT2

}

void External_Control(void)
{
    Uint32  TempX1Count=0;
    Uint32  TempX2Count=0;
    TempX1Count=Xint1Count;
    TempX2Count=Xint2Count;

    // Trigger both XINT1
    GpioDataRegs.GPBSET.bit.GPIO34=1;      //把GPIO拉高
    GpioDataRegs.GPBCLEAR.bit.GPIO32=1;    //拉低GPIO32,触发XINT1
    while(Xint1Count==TempX1Count){}

    // Trigger both XINT2
    GpioDataRegs.GPBSET.bit.GPIO34=1;      //把GPIO拉高
    DELAY_US(DELAY);
    GpioDataRegs.GPBSET.bit.GPIO33=1;    //拉高GPIO33,触发XINT2
    while(Xint2Count==TempX2Count){}

    if(Xint1Count==TempX1Count+1&&Xint2Count==TempX2Count)
    {
     LoopCount++;
     GpioDataRegs.GPBCLEAR.bit.GPIO33=1;    //拉低GPIO33,停止触发XINT2
     GpioDataRegs.GPBSET.bit.GPIO32=1;    //拉高GPIO32,停止触发XINT1
    }
    else
    {
        __asm("    ESTOP0");//停止到这里
    }
}

__interrupt  void  xint1_isr(void)
{
    GpioDataRegs.GPBCLEAR.all=0x4;    //GPIO34拉低
    Xint1Count++;
    // Acknowledge this interrupt to get more from group 1
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}

__interrupt  void  xint2_isr(void)
{
    GpioDataRegs.GPBCLEAR.all=0x4;    //GPIO34拉低
    Xint2Count++;
    // Acknowledge this interrupt to get more from group 1
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}

mian.c

void main(void)
{

    InitSysCtrl();  //Step1
   // GPIO_Init();     //step2
    External_Interrupt_Init();
    // step3;Disable CPU interrupts
    DINT;
    // Initialize the PIE control registers to their default state.
    // The default state is all PIE interrupts disabled and flags
    InitPieCtrl();     //中断初始化
    // Disable CPU interrupts and clear all CPU interrupt flags:
    IER = 0x0000;
    IFR = 0x0000;
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    InitPieVectTable();    //中断向量表
    // Interrupt that is used in this example is re-mapped to
    // ISR function found within this file.

    EALLOW;
   // PieVectTable.EPWM1_INT=&epwm1_timer_isr;        //把中断服务程序映射到中断向量表中
    PieVectTable.XINT1=&xint1_isr;
    PieVectTable.XINT2=&xint2_isr;
    EDIS;

    while(1)
    {
        External_Control();
    }

}

在这里插入图片描述根据文档可得,外部中断有96个独立的中断,分为了8个组,每个组分为12中断线。
下面进行具体的讲解:
主函数中
step1:
InitSysCtrl();该函数是使能外设时钟
step2:
External_Interrupt_Init();该函数就是自己编写的外部中断初始化函数
step3:
DINT; 这里是失能CPU中断
step4:
InitPieCtrl();进行中断初始化
step5:
IER = 0x0000;
IFR = 0x0000; 先关闭中断,清除中断标志位
step6:
InitPieVectTable(); //初始化中断向量表
step7:
PieVectTable.XINT1=&xint1_isr;
PieVectTable.XINT2=&xint2_isr; 把中断服务程序映射到中断向量表中
void External_Interrupt_Init(void)
该函数首先以来就进行使能中断:

 PieCtrlRegs.PIECTRL.bit.ENPIE=1;         //使能中断
 PieCtrlRegs.PIEIER1.bit.INTx4=1;         //使能INT1.4中断INT1
 PieCtrlRegs.PIEIER1.bit.INTx5=1;         //使能INT1.5中断INT2
 IER|=M_INT1;                             //使能CPU中断
 EINT;

在这里插入图片描述
PIECTRL中的ENPIE设置为1,使能PIE.
在这里插入图片描述
PIEIER1使能中断。
在这里插入图片描述
PIEIER1,PIEIFR1,是INT1组的使能寄存器
在这里插入图片描述
根据这个表,看出XINT2,XINT1分别对应INTx.5,INTx.4
在这里插入图片描述置1使能INT1

GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0;         // GPIO
GpioCtrlRegs.GPADIR.bit.GPIO0 = 0;          // input
GpioCtrlRegs.GPAQSEL1.bit.GPIO0 = 0;        // XINT1 Synch to SYSCLKOUT only

GpioCtrlRegs.GPAMUX1.bit.GPIO1=0;      //设置普通的IO
 GpioCtrlRegs.GPADIR.bit.GPIO1=0;       //设置为输入
 GpioCtrlRegs.GPAQSEL1.bit.GPIO1=2;     //设置为6倍采样时间
 GpioCtrlRegs.GPACTRL.bit.QUALPRD0=0xff;//每倍采样时间为510*SYSCLKOUT;

这里对GPIO0进行操作,是因为后面需要将GPIO0作为INT1的中断源。
先将GPIO0设置为普通IO,且设置为输入模式,其次使其时钟
在这里插入图片描述
GPIO1和GPIO2在GPAQSEL1,当为0设置0是,使其采样率为系统时钟,但是设为2时,设置采样率为六倍时钟。
在这里插入图片描述

GpioIntRegs.GPIOXINT1SEL.bit.GPIOSEL=0;     //定义GPIO为XINT1的来源
GpioIntRegs.GPIOXINT2SEL.bit.GPIOSEL=1;     //定义GPIO1为XINT2的来源

在这里插入图片描述
在这里插入图片描述
可以得出GPIO0为XINT1的中断来源,GPIO1为XINT2的时钟来源

// Configure XINT1 and XINT2
  XIntruptRegs.XINT1CR.bit.POLARITY=0;      //定义为下降沿触发
  XIntruptRegs.XINT2CR.bit.POLARITY=1;      //定义为上升沿触发
  // Enable XINT1 and XINT2
  XIntruptRegs.XINT1CR.bit.ENABLE=1;        //使能XINT1
  XIntruptRegs.XINT2CR.bit.ENABLE=1;        //使能XINT2

在这里插入图片描述
以上为内容为外部中断初始化代码
下面

void External_Control(void)
{
    Uint32  TempX1Count=0;
    Uint32  TempX2Count=0;
    TempX1Count=Xint1Count;
    TempX2Count=Xint2Count;

    // Trigger both XINT1
    GpioDataRegs.GPBSET.bit.GPIO34=1;      //把GPIO拉高
    GpioDataRegs.GPBCLEAR.bit.GPIO32=1;    //拉低GPIO32,触发XINT1
    while(Xint1Count==TempX1Count){}

    // Trigger both XINT2
    GpioDataRegs.GPBSET.bit.GPIO34=1;      //把GPIO拉高
    DELAY_US(DELAY);
    GpioDataRegs.GPBSET.bit.GPIO33=1;    //拉高GPIO33,触发XINT2
    while(Xint2Count==TempX2Count){}

    if(Xint1Count==TempX1Count+1&&Xint2Count==TempX2Count)
    {
     LoopCount++;
     GpioDataRegs.GPBCLEAR.bit.GPIO33=1;    //拉低GPIO33,停止触发XINT2
     GpioDataRegs.GPBSET.bit.GPIO32=1;    //拉高GPIO32,停止触发XINT1
    }
    else
    {
        __asm("    ESTOP0");//停止到这里
    }

这个为外部中断测试函数,用GPIO34连接的LED灯进行指示外部中断的进程。GPIO33和GPIO32分别产生上升沿和下降沿
输入给GPIO1,GPIO0,从而触发XINT1,XINT2中断。

__interrupt  void  xint1_isr(void)
{
    GpioDataRegs.GPBCLEAR.all=0x4;    //GPIO34拉低
    Xint1Count++;
    // Acknowledge this interrupt to get more from group 1
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}

__interrupt  void  xint2_isr(void)
{
    GpioDataRegs.GPBCLEAR.all=0x4;    //GPIO34拉低
    Xint2Count++;
    // Acknowledge this interrupt to get more from group 1
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}

上述两段程序时中断服务程序,
在这里插入图片描述
完毕

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值