1.定时器的知识
2.定时器 0 和定时器1 同时计时 定时器0 控制 GPIO6 定时器1 控制GPIO7 的闪烁
代码:
//定时器 1 和定时器0 是可以同时计时的
//头文件定义
#include "DSP2833x_Device.h" // DSP2833x 头文件
#include "DSP2833x_Examples.h" // DSP2833x例程相关头文件
//全局变量定义
volatile unsigned int timer_int_cnt;
//定时器0定义
interrupt void cpu_timer0_isr(void);
//定时器1定义
interrupt void cpu_timer1_isr(void);
//GPIO设置
void Gpio_select(void);
//主函数
int main(void)
{
Uint32 i;
// 步骤 1. 初始化系统控制:
// 设置PLL, WatchDog, 使能外设时钟
InitSysCtrl();
// 初始化使用到的GPIO口;
EALLOW;
GpioCtrlRegs.GPAMUX1.bit.GPIO6 = 0;
GpioCtrlRegs.GPADIR.bit.GPIO6 = 1;
GpioCtrlRegs.GPAMUX1.bit.GPIO7 = 0;
GpioCtrlRegs.GPADIR.bit.GPIO7 = 1;
EDIS;
// 步骤 3. 清除所有中断初始化中断向量表:
// 禁止CPU全局中断
DINT;
// 初始化PIE控制寄存器到他们的默认状态.
// 这个默认状态就是禁止PIE中断及清除所有PIE中断标志
// 这个函数放在DSP2833x_PieCtrl.c源文件里
InitPieCtrl();
// 禁止CPU中断和清除所有CPU中断标志
IER = 0x0000;
IFR = 0x0000;
//初始化PIE中断向量表,并使其指向中断服务子程序(ISR)
// 这些中断服务子程序被放在了DSP280x_DefaultIsr.c源文件中
// 这个函数放在了DSP2833x_PieVect.c源文件里面.
InitPieVectTable();
//中断重定向到ISR函数
//允许对受保护的寄存器进行操作
EALLOW;
//定时器0
PieVectTable.TINT0=&cpu_timer0_isr;
//定时器1
PieVectTable.XINT13=&cpu_timer1_isr;
EDIS;
//CPU定时器初始化函数
InitCpuTimers();
//CPU定时器配置函数
ConfigCpuTimer(&CpuTimer0,150,500000);
ConfigCpuTimer(&CpuTimer1,150,500000);
//设置TIE = 1,开启定时器0中断
CpuTimer0Regs.TCR.all = 0x4000;
//设置TIE = 1,开启定时器1中断
CpuTimer1Regs.TCR.all = 0x4000;
//开启CPU中断1,这个中断连接的是CPU定时器0
IER |=M_INT1;
//开启CPU中断13,这个中断连接的是CPU定时器1
IER |= M_INT13;
//在PIE中启用TINT0(在第一组中断7中)
PieCtrlRegs.PIEIER1.bit.INTx7=1;
//INTM置0,开全局中断
EINT;
ERTM;
return 0;
}
//定时器0函数
interrupt void cpu_timer0_isr(void)
{
CpuTimer0.InterruptCount++;
GpioDataRegs.GPATOGGLE.bit.GPIO6=1;
PieCtrlRegs.PIEACK.all=PIEACK_GROUP1;
}
//定时器1函数
interrupt void cpu_timer1_isr(void)
{
CpuTimer0.InterruptCount++;
GpioDataRegs.GPATOGGLE.bit.GPIO7=1;
PieCtrlRegs.PIEACK.all=PIEACK_GROUP1;
}
3.本例程配置 CPU定时器0为500ms周期, 每次周期中断 在映射区域的LED 灯 亮一个(LED 灯有8个)
本文件需要添加一个新的文件 到res 文件夹里面
代码:
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File
/*//使一个LED 灯亮 GPIO06
// Prototype statements for functions found within this file.
interrupt void cpu_timer0_isr(void);
void main(void)
{
InitSysCtrl();
DINT;
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
//设置定时器0 的中断入口地址为中断向量表的 INTO
EALLOW;
PieVectTable.TINT0 = &cpu_timer0_isr;
EDIS;
InitCpuTimers();
#if (CPU_FRQ_150MHZ)//初始化 定时器的频率
ConfigCpuTimer(&CpuTimer0, 150, 500000);
#endif
#if (CPU_FRQ_100MHZ)
ConfigCpuTimer(&CpuTimer0, 100, 500000);
#endif
//开始定时器功能
CpuTimer0Regs.TCR.all = 0x4001;
//端口的初始化
EALLOW;
GpioCtrlRegs.GPAMUX1.bit.GPIO6 = 0;
GpioCtrlRegs.GPADIR.bit.GPIO6 = 1;
EDIS;
//开启CPU 第一组中断 并使能第一组中断的第7个小中断 ,定时器0
IER |= M_INT1;
PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
//使能中断
EINT;
ERTM;
for(;;)
{
}
}
interrupt void cpu_timer0_isr(void)
{
CpuTimer0.InterruptCount++;
GpioDataRegs.GPATOGGLE.bit.GPIO6 = 1;//翻转
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}
*/
//通过映射的作用实现流水灯的效果 ,通过定时器 实现时间的控制
#define LED *((Uint16 *)0x4600)
const Uint16 LedCode[9]={0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0xFE,0XFF};
interrupt void cpu_timer0_isr(void);
unsigned int num=0;
void main(void)
{
//在初始化系统函数
InitSysCtrl();
//禁止产生中断
DINT;
//初始化PIE控制函数
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
//PIE向量表初始化
InitPieVectTable();
//LED 灯映射 的初始化
InitXintf();
//设置定时器0 的中断入口地址为中断向量表的 INTO
EALLOW;
PieVectTable.TINT0 = &cpu_timer0_isr;//定义中断定时器
EDIS;
InitCpuTimers();
#if (CPU_FRQ_150MHZ)//初始化 定时器的频率 500ms 定时器的频率为 150HZ
ConfigCpuTimer(&CpuTimer0, 150, 100000);//最后一个参数的 为中断的时间 单位 us
#endif
#if (CPU_FRQ_100MHZ)//初始化 定时器的频率 500ms 定时器的频率为 100HZ
ConfigCpuTimer(&CpuTimer0, 100, 100000);
#endif
//开始定时器功能
CpuTimer0Regs.TCR.all = 0x4001;//TTS==0
// //端口的初始化
// EALLOW;
// GpioCtrlRegs.GPAMUX1.bit.GPIO6 = 0;
// GpioCtrlRegs.GPADIR.bit.GPIO6 = 1;
// EDIS;
//开启CPU 第一组中断 并使能第一组中断的第7个小中断 ,定时器0
IER |= M_INT1;
PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
//使能中断
//开启中断
EINT;
ERTM;
LED=0x00;//全亮
for(;;)
{
}
}
interrupt void cpu_timer0_isr(void)
{
CpuTimer0.InterruptCount++;
if(num>8)
{
num=0;
}
LED=LedCode[num++];
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}
- 定时器系统原理介绍
TMS320F28335的CPU Time有三个,分别为Timer0,Timer1,Timer2,其中Timer2是为操作系统DSP/BIOS保留的,当未移植操作系统时,可用来做普通的定时器。这三个定时器的中断信号分别为TINT0, TINT1, TINT2,分别对应于中断向量INT1,INT13,INT14。图4-2为定时器的结构框图,图中TIMH:TIM为计数寄存器,PRDH:PRD为周期寄存器,形如AH格式:A的形式表示一个32位的寄存器,是由两个16位的寄存器构成,AH是高16位,A是低16位。
CPU定时器的计数复位时,计数寄存器TIMH:TIM加载周期寄存器PRDH:PRD所设定的值,经历一个计数器时钟后,TIMH:TIM内的值就减1,一直减到0,这时产生定时器周期中断事件,并重新装载PRDH:PRD所设定的值,重新开始计数。至于每隔多少时间,计数寄存器TIMH:TIM的值才会减1则由预分频寄存器TPRH:TPR来决定。
TPRH和TPR这两个寄存器由两部分组成,高8位为定时器预分频计数器PSC,低8位是定时器分频TDDR。也即是说,TPRH是由PSCH和TDDRH构成,而TDDR由PSC和TDDR构成。且其工作的原理与51系列单片机定时器计数器类似,复位时,PSCH:PSC加载TDDRH:TDDR所设定的值,然后经过一个CPU时钟,PSCH:PSC的值减1,当PSCH:PSC的值减到0时,会再次装载TDDRH:TDDR所设定的值,并且产生一个计数器时钟,TIMH:TIM减1。CPU定时器0、1、2配置和控制寄存器如表4-1所示
定时器中断 标准格式:
//在初始化系统函数
InitSysCtrl();
//禁止产生中断
DINT;
//初始化PIE控制函数
InitPieCtrl();
//PIE向量表初始化
InitPieVectTable();
//将自定义的定时器中断函数映射到向量表中
PieVectTable.TINT0 = &cpu_timer0_isr;
//配置定时器
InitCpuTimers();
//配置定时器中断周期 参数:定时器结构体指针, 定时器频率(MHz), 目标周期时间(uS)
//T=Freq*Period/150000000(s)
ConfigCpuTimer(&CpuTimer0, 150, 500000);
//开启定时器
CpuTimer0Regs.TCR.all = 0x4001;
//使能CPU级中断:设置第一组中断源将会产生,
IER |= M_INT1;
//使能PIE级中断:第一组中断组中的第七个小中断
PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
//开启中断
EINT;
//主循环
//自定义的中断服务函数
interrupt void cpu_timer0_isr(void){
//中断次数计数器
CpuTimer0.InterruptCount++;
//中断内容
}
实验结果: