DSP28335学习笔记:定时器中断详解
F28335学习笔记:定时器中断(定时器0、1、2 *注重使用)
F28335的CPU定时器有3个且均为32位,分别是Timer0、Timer1、Timer2, 其中 Timer2 是为操作系统 DSP/BIOS 保留的,当未移植操作系统时,可用来做普 通的定时器。这三个定时器的中断信号分别为 TINT0,TINT1,TINT2,分别对应于中断向量 INT1,INT13,INT14。
一、F28335定时器介绍(CPU定时器)
TMS320F28335 的 CPU Time 有三个,分别为 Timer0,Timer1,Timer2,其中Timer2 是为操作系统 DSP/BIOS 保留的,当未移植操作系统时,可用来做普通的定时器。这三个定时器的中断信号分别为 TINT0, TINT1, TINT2,分别对应于中断向量 INT1,INT13,INT14。
Timer0:使用PIE中断
Timer1:直接连接到内核 INT13
Timer1:直接连接到内核 INT14
二、定时时间公式

三、定时器0配置步骤
定时器1、定时器2在中断服务函数略有不同
1.配置void TIM0_Init(float Freq, float Period)函数
(1) 中断控制配置函数(适用所有中断)
//==========1.中断控制配置函数(适用所有中断)==========//
InitPieCtrl(); //初始化PIE控制寄存器
IER = 0x0000; //失能全部CPU中断
IFR = 0x0000; //清除CPU中断标志
InitPieVectTable(); //初始化PIE中断向量表
(2)使能定时器时钟
//=================2.使能定时器时钟==================//
EALLOW;
SysCtrlRegs.PCLKCR3.bit.CPUTIMER0ENCLK = 1; // CPU Timer 0
EDIS;
(3) 设置定时器0的中断入口地址为中断向量表的INT0
//=================3.设置定时器0的中断入口地址为中断向量表的INT0==================//
EALLOW;
PieVectTable.TINT0 = &TIM0_IRQn;
EDIS;
(4) 初始化定时器参数
//=================4.初始化定时器参数====================//
//指向定时器0的寄存器地址
CpuTimer0.RegsAddr = &CpuTimer0Regs;
//设置定时器0的周期寄存器值
CpuTimer0Regs.PRD.all = 0xFFFFFFFF; //设置为最大
//设置定时器预定标计数器值为0
CpuTimer0Regs.TPR.all = 0; //低位
CpuTimer0Regs.TPRH.all = 0; //高位
//确保定时器0为停止状态
CpuTimer0Regs.TCR.bit.TSS = 1; //1停止 0开始
//重载使能
CpuTimer0Regs.TCR.bit.TRB = 1;
// Reset interrupt counters:
CpuTimer0.InterruptCount = 0; //这个变量用来累计中断计数的次数,TI公司给的
(5) 定时器设置
//=================5.定时器设置====================//
ConfigCpuTimer(&CpuTimer0, Freq, Period);
(6) 开启定时器中断功能,并使能定时器
//=================6.开启定时器中断功能,并使能定时器====================//
//开始定时器功能
CpuTimer0Regs.TCR.bit.TSS=0;
//开启CPU第一组中断并使能第一组中断的第7个小中断,即定时器0
IER |= M_INT1;
PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
//使能总中断
EINT;
ERTM;
(7)完整函数
void TIM0_Init(float Freq, float Period)
{
//=================2.使能定时器时钟==================//
EALLOW;
SysCtrlRegs.PCLKCR3.bit.CPUTIMER0ENCLK = 1; // CPU Timer 0
EDIS;
//=================3.设置定时器0的中断入口地址为中断向量表的INT0==================//
EALLOW;
PieVectTable.TINT0 = &TIM0_IRQn;
EDIS;
//=================4.初始化定时器参数====================//
//指向定时器0的寄存器地址
CpuTimer0.RegsAddr = &CpuTimer0Regs;
//设置定时器0的周期寄存器值
CpuTimer0Regs.PRD.all = 0xFFFFFFFF; //设置为最大
//设置定时器预定标计数器值为0
CpuTimer0Regs.TPR.all = 0; //低位
CpuTimer0Regs.TPRH.all = 0; //高位
//确保定时器0为停止状态
CpuTimer0Regs.TCR.bit.TSS = 1; //1停止 0开始
//重载使能
CpuTimer0Regs.TCR.bit.TRB = 1;
// Reset interrupt counters:
CpuTimer0.InterruptCount = 0; //这个变量用来累计中断计数的次数,TI公司给的
//=================5.定时器设置====================//
ConfigCpuTimer(&CpuTimer0, Freq, Period);
//=================6.开启定时器中断功能,并使能定时器====================//
//开始定时器功能
CpuTimer0Regs.TCR.bit.TSS=0;
//开启CPU第一组中断并使能第一组中断的第7个小中断,即定时器0
IER |= M_INT1;
PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
//使能总中断
EINT;
ERTM;
}
2.配置interrupt void TIM0_IRQn(void)函数
因为定时器0是在PIE中断中,所以对 PIE 等寄存器操作需要关闭写保护,因此将该语句放在 EALLOW…EDIS 中。
然后再在中断函数结束前将 PIEACKx 相应的标志清零,即写 1 清零。
interrupt void TIM0_IRQn(void)
{
EALLOW;
......定时器功能
PieCtrlRegs.PIEACK.bit.ACK1=1; //只有定时器0需要,因为是对应在PIE中断当中
EDIS;
}
四、定时器1配置步骤
因为详细讲述了定时器0的配置,故直接上代码
1.配置void TIM1_Init(float Freq, float Period)函数
//定时器1初始化函数
//Freq:CPU时钟频率(150MHz)
//Period:定时周期值,单位us
//公式:T = Freq*Period/150 000 000(s)
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;
}
2.配置interrupt void TIM1_IRQn(void)函数
interrupt void TIM1_IRQn(void)
{
EALLOW;
......定时器1功能
EDIS;
}
五、定时器2配置步骤
1.配置void TIM2_Init(float Freq, float Period)函数
//定时器2初始化函数
//Freq:CPU时钟频率(150MHz)
//Period:定时周期值,单位us
//公式:T = Freq*Period/150 000 000(s)
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;
}
2.配置interrupt void TIM2_IRQn(void)函数
interrupt void TIM2_IRQn(void)
{
EALLOW;
......定时器功能
EDIS;
}
六、timer.h文件
/* * time.h * * Created on: 2018-1-24 * Author: Administrator */ #ifndef TIME_H_ #define TIME_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_ */
七、main()函数
#include "DSP2833x_Device.h"
#include "DSP2833x_Examples.h"
#include <string.h>
#include "stdio.h"
#include "leds.h"
#include "time.h"
unsigned char i=66;
unsigned char T=0;
void main()
{
InitSysCtrl();
//==========1.中断控制配置函数(适用所有中断)==========//
InitPieCtrl(); //初始化PIE控制寄存器
IER = 0x0000; //失能全部CPU中断
IFR = 0x0000; //清除CPU中断标志
InitPieVectTable(); //初始化PIE中断向量表
//==========下载Flash==========//
MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);
InitFlash();
//TIM0_Init(150,500000); //0.5s
//TIM1_Init(150,1000000); //1s
TIM2_Init(150,1000000); //1s
while(1)
{
}
}
作者:木子枫铃