在这里大家需要注意后面那两个TPR/TPRH寄存器,由于TDDRH:TDDR和PSCH:PSC寄存器是16位寄存器,每段是8位,现在是PSCH和TDDRH的值储存在TPRH中,PSC和TDDR的值储存在TPR中,跟前面几个32位寄存器不一样。
现在寄存器也讲完了,现在到我们最刺激的开发环节。
首先,还是要讲流程,有了流程,有了规划,才好做事。我来大概说下定时器使用流程:
1、规划。这个规划既包括PRDH/PRD/TDDRH/TDDR的规划,也包括定时器和时钟的规划;
2、编写定时中断函数,并将该函数指向中断矢量表,这里要注意清楚中断标识PIEACK对应的位,这个是CPU不能自动清除的想;
3、相应的中断设置;
4、启动定时器,装载定时器的值,并开始计数;
5、打开中断组开关和总开关,开始程序的运行。
好了,思路也理清楚了,现在开始准备写程序,先准备本次需要的文件,既然是定时器,那我们就需要把TI提供的F2802x_CpuTimers.c文件从C: icontrolSUITEdevice_supportf2802xv200f2802x_commonsource路径拷贝到D:studyday002projectsrc目录下,其他所有的文件,跟昨天一样,新建工程和工程设置这一步我们就直接跳过了。
由于我们还是使用昨天的Proteus仿真文件,端口也不变,所以GPIO.c文件今天就不动了,跟昨天保持一样。
至于定时周期,我还是想跟昨天延时函数时间一致,都是1ms,那我们现在就来算一下。
公式是T=(TIMH:TIM+1)(PRDH:PRD+1)定时器的输入时钟,现在T=0.001,时钟跟系统时钟一致60MHZ,也就是1/60000000,所以(TIMH:TIM+1)*(PRDH:PRD+1)=60000,而PRD寄存器是16位,TIM是32位,所以(PRDH:PRD+1)设为60,(TIMH:TIM+1)设为1000。好了,可以开始写程序了。
void InitCpuTimers(void)
{
// CPU Timer 0
// Initialize address pointers to respective timer registers:
CpuTimer0.RegsAddr = &CpuTimer0Regs;
// Initialize timer period to maximum:
CpuTimer0Regs.PRD.all = 999;
// Initialize pre-scale counter to divide by 1 (SYSCLKOUT):
CpuTimer0Regs.TPR.bit.TDDR = 59;
CpuTimer0Regs.TPRH.bit.TDDRH = 0;
// Make sure timer is stopped:
CpuTimer0Regs.TCR.bit.TSS = 1;
// Reload all counter register with period value:
CpuTimer0Regs.TCR.bit.TRB = 1;
// Reset interrupt counters:
CpuTimer0.InterruptCount = 0;
// CpuTimer 1and CpuTimer2 are reserved for DSP BIOS & other RTOS
// Do not use these two timers if you ever plan on integrating
// DSP-BIOS or another realtime OS.
//
// Initialize address pointers to respective timer registers:
CpuTimer1.RegsAddr = &CpuTimer1Regs;
CpuTimer2.RegsAddr = &CpuTimer2Regs;
// Initialize timer period to maximum:
CpuTimer1Regs.PRD.all = 0xFFFFFFFF;
CpuTimer2Regs.PRD.all = 0xFFFFFFFF;
// Initialize pre-scale counter to divide by 1 (SYSCLKOUT):
CpuTimer1Regs.TPR.all = 0;
CpuTimer1Regs.TPRH.all = 0;
CpuTimer2Regs.TPR.all = 0;
CpuTimer2Regs.TPRH.all = 0;
// Make sure timers are stopped:
CpuTimer1Regs.TCR.bit.TSS = 1;
CpuTimer2Regs.TCR.bit.TSS = 1;
// Reload all counter register with period value:
CpuTimer1Regs.TCR.bit.TRB = 1;
CpuTimer2Regs.TCR.bit.TRB = 1;
// Reset interrupt counters:
CpuTimer1.InterruptCount = 0;
CpuTimer2.InterruptCount = 0;
}
定时器初始化函数如上所示,现在开始写中断了,回顾下,大家还记得定时中断0 TINT0在哪个PIE中断组吗
看到了吧,TINT0在第一个中断组的第七位,也就是INT1.7位
现在先去写中断函数,中断函数直接去TI提供的F2802x_DefaultIsr.c文件修改就行了,修改后如图:
interrupt void TINT0_ISR(void) // CPU-Timer 0
{
// Insert ISR Code here
GpioDataRegs.GPATOGGLE.all=0x000000ff;
// To receive more interrupts from this PIE group, acknowledge this interrupt
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
// Next two lines for debug only to halt the processor here// Remove after inserting ISR Code//asm (" ESTOP0");//for(;;);
}
编写主函数:
void main(void)
{
// Step 1. Initialize System Control:// PLL, WatchDog, enable Peripheral Clocks// This example function is found in the DSP2802x_SysCtrl.c file.
InitSysCtrl();
// Step 2. Initalize GPIO:// This example function is found in the DSP2802x_Gpio.c file and// illustrates how to set the GPIO to it's default state.
InitGpio();
// Step 3. Clear all interrupts and initialize PIE vector table:// Disable CPU interrupts
DINT;
// Initialize PIE control registers to their default state.// The default state is all PIE interrupts disabled and flags// are cleared.// This function is found in the DSP2802x_PieCtrl.c file.
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).// This will populate the entire table, even if the interrupt// is not used in this example. This is useful for debug purposes.// The shell ISR routines are found in DSP2802x_DefaultIsr.c.// This function is found in DSP2802x_PieVect.c.
InitPieVectTable();
// Step 4. Initialize all the Device Peripherals:// This function is found in DSP2802x_InitPeripherals.c// InitPeripherals(); // Not required for this example// Step 5. User specific code:
GpioDataRegs.GPADAT.all=0x00000000; //GPIO0-GPIO31 initial value are 0
CpuTimer0Regs.TCR.bit.TIE=1;
StartCpuTimer0();
EALLOW;
PieCtrlRegs.PIEIER1.bit.INTx7 =1;
PieCtrlRegs.PIECTRL.bit.ENPIE =1;
IER =0x0001;
EINT;
EDIS;
while(1)
{
// GpioDataRegs.GPATOGGLE.all=0x000000ff;// DELAY_US(1000);
}
}
OK,写完了,导入Proteus测试下。测试结果OK,达到预期效果。