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); } }