DSP2833x实验_定时器中断

1.定时器工作原理

TMS320F28335的CPU Time有三个,分别为Timer0,Timer1,Timer2,其中Timer2是为操作系统DSP/BIOS保留的,当未移植操作系统时,可用来做普通的定时器。这三个定时器的中断信号分别为TINT0, TINT1, TINT2,分别对应于中断向量INT1,INT13,INT14。

 

 

  从上图可知,定时器有一个预分频模块和一个定时/计数模块,其中预分频
模块包括一个 16 位的定时器分频寄存器(TDDRH:TDDR)和一个 16 位的预定标
计数器(PSCH:PSC);定时/计数模块包括一个 32 位的周期寄存器(PRDH:PRD)
和一个 32 位的计数寄存器(TIMH:TIM)。
  当系统时钟(SYSCLKOUT)来一个脉冲,PSCH:PSC 预定标计数器减 1,当 PSCH:
PSC 预定标计数器减到 0 的时候,预定标计数器产生下溢后向定时器的 32 位计
数器 TIMH:TIM 借位,即 TIMH:TIM 计数器减 1,同时 PSCH:PSC 可以重载定时器
分频寄存器(TDDRH:TDDR)的值;当计数寄存器 TIMH:TIM 减到 0 产生下溢的
时候,计数寄存器会重载周期寄存器(PRDH:PRD)的值,同时定时器会产生一
个中断信号给 CPU。

/*
 * time.h
 *
 *  Created on: 2021年7月12日
 *      Author: acer
 */

#ifndef TIMERS_H_
#define TIMERS_H_

#include "DSP2833x_Device.h"     // DSP2833x 头文件
#include "DSP2833x_Examples.h"   // DSP2833x 例子相关头文件

void TIM0_Init(float Freq, float Period);
interrupt void TIM0_IRQn(void);

void TIM1_Init(float Freq, float Period);
interrupt void TIM1_IRQn(void);

void TIM2_Init(float Freq, float Period);
interrupt void TIM2_IRQn(void);


#endif /* TIME_H_ */
/*
 * time0.c
 *
 *  Created on: 2021年7月12日
 *      Author: acer
 */
#include "timers.h"
#include "leds.h"

void TIM0_Init(float Freq, float Period)
{
    EALLOW;
    SysCtrlRegs.PCLKCR3.bit.CPUTIMER0ENCLK = 1; // CPU Timer 0
    EDIS;

    //设置定时器0的中断入口地址为中断向量表的INT0
    EALLOW;
    PieVectTable.TINT0 = &TIM0_IRQn;
    EDIS;

    //指向定时器0的寄存器地址
    CpuTimer0.RegsAddr = &CpuTimer0Regs;
    //设置定时器0的周期寄存器值
    CpuTimer0Regs.PRD.all  = 0xFFFFFFFF;
    //设置定时器预定标计数器值为0
    CpuTimer0Regs.TPR.all  = 0;
    CpuTimer0Regs.TPRH.all = 0;
    //确保定时器0为停止状态
    CpuTimer0Regs.TCR.bit.TSS = 1;
    //重载使能
    CpuTimer0Regs.TCR.bit.TRB = 1;
    // Reset interrupt counters:
    CpuTimer0.InterruptCount = 0;

    ConfigCpuTimer(&CpuTimer0, Freq, Period);

    //开始定时器功能
    CpuTimer0Regs.TCR.bit.TSS=0;
    //开启CPU第一组中断并使能第一组中断的第7个小中断,即定时器0
    IER |= M_INT1;
    PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
    //使能总中断
    EINT;
    ERTM;

}

interrupt void TIM0_IRQn(void)
{
    EALLOW;
    LED2_TOGGLE;
    PieCtrlRegs.PIEACK.bit.ACK1=1;  //
    EDIS;
}

void TIM1_Init(float Freq, float Period)
{
    EALLOW;
    SysCtrlRegs.PCLKCR3.bit.CPUTIMER1ENCLK = 1; // CPU Timer 1
    EDIS;

    EALLOW;
    PieVectTable.XINT13 = &TIM1_IRQn;
    EDIS;

    // Initialize address pointers to respective timer registers:
    CpuTimer1.RegsAddr = &CpuTimer1Regs;
    // Initialize timer period to maximum:
    CpuTimer1Regs.PRD.all  = 0xFFFFFFFF;
    // Initialize pre-scale counter to divide by 1 (SYSCLKOUT):
    CpuTimer1Regs.TPR.all  = 0;
    CpuTimer1Regs.TPRH.all = 0;
    // Make sure timers are stopped:
    CpuTimer1Regs.TCR.bit.TSS = 1;
    // Reload all counter register with period value:
    CpuTimer1Regs.TCR.bit.TRB = 1;
    // Reset interrupt counters:
    CpuTimer1.InterruptCount = 0;

    ConfigCpuTimer(&CpuTimer1, Freq, Period);

    CpuTimer1Regs.TCR.bit.TSS=0;

    IER |= M_INT13;

    EINT;
    ERTM;

}

interrupt void TIM1_IRQn(void)
{
    EALLOW;
    LED3_TOGGLE;
    PieCtrlRegs.PIEACK.bit.ACK1=1;  //
    EDIS;
}

void TIM2_Init(float Freq, float Period)
{
    EALLOW;
    SysCtrlRegs.PCLKCR3.bit.CPUTIMER2ENCLK = 1; // CPU Timer 2
    EDIS;

    EALLOW;
    PieVectTable.TINT2 = &TIM2_IRQn;
    EDIS;

    // Initialize address pointers to respective timer registers:
    CpuTimer2.RegsAddr = &CpuTimer2Regs;
    // Initialize timer period to maximum:
    CpuTimer2Regs.PRD.all  = 0xFFFFFFFF;
    // Initialize pre-scale counter to divide by 1 (SYSCLKOUT):
    CpuTimer2Regs.TPR.all  = 0;
    CpuTimer2Regs.TPRH.all = 0;
    // Make sure timers are stopped:
    CpuTimer2Regs.TCR.bit.TSS = 1;
    // Reload all counter register with period value:
    CpuTimer2Regs.TCR.bit.TRB = 1;
    // Reset interrupt counters:
    CpuTimer2.InterruptCount = 0;

    ConfigCpuTimer(&CpuTimer2, Freq, Period);

    CpuTimer2Regs.TCR.bit.TSS=0;

    IER |= M_INT14;

    EINT;
    ERTM;

}

interrupt void TIM2_IRQn(void)
{
    EALLOW;
    LED4_TOGGLE;
    PieCtrlRegs.PIEACK.bit.ACK1=1;  //
    EDIS;
}
void main(void)
{
    int i=0;
//    char key=0;
//    short cnt=0;
//    char j=0;

    InitSysCtrl();    // 步骤 1. 初始化系统控制:

    InitPieCtrl(); //使能CPU级中断,并初始化PIE控制器寄存器和PIE中断向量表
    IER = 0x0000;
    IFR = 0X0000;
    InitPieVectTable();

    LED_Init();
    KEY_Init();
    //DC_Motor_Init();
    //Steep_Motor_Init();
    /* T = Freq * Period/150 000 000(s) (默认150Mhz)*/
    TIM0_Init(150,500000);  //500ms
    TIM1_Init(150,1000000);  //500ms
    TIM2_Init(150,1500000);  //500ms

    //EXTI1_Init();
    //EXTI2_Init();

    while(1)
    {

        i++;
        if(i%2000==0)
        {
            LED1_TOGGLE;
        }
        DELAY_US(100);
    }
}

 

posted @ 2021-07-12 11:03  百叶集  阅读(1017)  评论(0编辑  收藏  举报