- 定时器系统原理介绍
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所示
定时器定时时间的公式计算
以上寄存器测值在配置函数ConfigCpuTimer(struct CPUTIMER_VARS *Timer, float Freq, float Period)中设置。形参Timer为第几位定时器,Freq为定时频率,Period为计时周期。
假若Freq为15,Period为1000000,则时间t = 1*15*1000000/150M = 0.1s (系统时钟频率为150M)。不过这个算式的成立是有条件的,这个条件就是以下两条语句:
Timer->RegsAddr->TPR.all = 0
Timer->RegsAddr->TPRH.all = 0
上文曾提及,定时器的计数时钟是有预分频寄存器TPRH:TPR决定的。CpuTimerxRegs.TPR.all = 0, CpuTimerxRegs.TPRH.all = 0这两句话决定了1个时钟源周期为定时器的时钟周期(即一个SYSCLKOUT,TIMH:TIM减1),若CpuTimerxRegs.TPR.all = y,CpuTimerxRegs.TPRH.all = 0,则计y+1个时钟周期为定时器的时钟周期。X表示0,1,2中的任意值(任意定时器)。
因此,真正的定时时间为:time =TPRH:TPR/SYSCLKOUT*Freq*Peroid。只有当TPRH:TPR=0时,SYSCLKOUT直接作为TIMH:TIM的时钟周期,time =Freq*Peroid/SYSCLKOUT。另外,在定时器配置函数中,
Timer->RegsAddr->TCR.bit.TSS = 1 表示停止定时器 ;
Timer->RegsAddr->TCR.bit.TRB = 1 表示重装定时器;
Timer->RegsAddr->TCR.bit.FREE = 1 表示定时器自由运行;
Timer->RegsAddr->TCR.bit.TIE = 1 表示使能定时器中断。
如果要利用定时器产生一定周期的时间中断,别忘了在主函数中设置响应的中断向量即可。
TI官方头文件DSP2833x_CpuTimers.h程序如下:
#ifndef DSP2833x_CPU_TIMERS_H
#define DSP2833x_CPU_TIMERS_H
#ifdef __cplusplus
extern "C" {
#endif
struct TCR_BITS {
Uint16 rsvd1:4;
Uint16 TSS:1;
Uint16 TRB:1;
Uint16 rsvd2:4;
Uint16 SOFT:1;
Uint16 FREE:1;
Uint16 rsvd3:2;
Uint16 TIE:1;
Uint16 TIF:1;
};
union TCR_REG {
Uint16 all;
struct TCR_BITS bit;
};
struct TPR_BITS {
Uint16 TDDR:8;
Uint16 PSC:8;
};
union TPR_REG {
Uint16 all;
struct TPR_BITS bit;
};
struct TPRH_BITS {
Uint16 TDDRH:8;
Uint16 PSCH:8;
};
union TPRH_REG {
Uint16 all;
struct TPRH_BITS bit;
};
struct TIM_REG {
Uint16 LSW;
Uint16 MSW;
};
union TIM_GROUP {
Uint32 all;
struct TIM_REG half;
};
struct PRD_REG {
Uint16 LSW;
Uint16 MSW;
};
union PRD_GROUP {
Uint32 all;
struct PRD_REG half;
};
struct CPUTIMER_REGS {
union TIM_GROUP TIM;
union PRD_GROUP PRD;
union TCR_REG TCR;
Uint16 rsvd1;
union TPR_REG TPR;
union TPRH_REG TPRH;
};
struct CPUTIMER_VARS {
volatile struct CPUTIMER_REGS *RegsAddr;
Uint32 InterruptCount;
float CPUFreqInMHz;
float PeriodInUSec;
};
extern void InitCpuTimers(void);
void ConfigCpuTimer(struct CPUTIMER_VARS *Timer, float Freq, float Period);
extern volatile struct CPUTIMER_REGS CpuTimer0Regs;
extern struct CPUTIMER_VARS CpuTimer0;
extern volatile struct CPUTIMER_REGS CpuTimer1Regs;
extern volatile struct CPUTIMER_REGS CpuTimer2Regs;
extern struct CPUTIMER_VARS CpuTimer1;
extern struct CPUTIMER_VARS CpuTimer2;
#define StartCpuTimer0() CpuTimer0Regs.TCR.bit.TSS = 0
#define StopCpuTimer0() CpuTimer0Regs.TCR.bit.TSS = 1
#define ReloadCpuTimer0() CpuTimer0Regs.TCR.bit.TRB = 1
#define ReadCpuTimer0Counter() CpuTimer0Regs.TIM.all
#define ReadCpuTimer0Period() CpuTimer0Regs.PRD.all
#define StartCpuTimer1() CpuTimer1Regs.TCR.bit.TSS = 0
#define StartCpuTimer2() CpuTimer2Regs.TCR.bit.TSS = 0
#define StopCpuTimer1() CpuTimer1Regs.TCR.bit.TSS = 1
#define StopCpuTimer2() CpuTimer2Regs.TCR.bit.TSS = 1
#define ReloadCpuTimer1() CpuTimer1Regs.TCR.bit.TRB = 1
#define ReloadCpuTimer2() CpuTimer2Regs.TCR.bit.TRB = 1
#define ReadCpuTimer1Counter() CpuTimer1Regs.TIM.all
#define ReadCpuTimer2Counter() CpuTimer2Regs.TIM.all
#define ReadCpuTimer1Period() CpuTimer1Regs.PRD.all
#define ReadCpuTimer2Period() CpuTimer2Regs.PRD.all
#ifdef __cplusplus
}
#endif /* extern "C" */
#endif // end of DSP2833x_CPU_TIMERS_H definition
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
其中的实例程序如下:
#include "DSP2833x_Device.h"
#include "DSP2833x_Examples.h"
struct CPUTIMER_VARS CpuTimer0;
struct CPUTIMER_VARS CpuTimer1;
struct CPUTIMER_VARS CpuTimer2;
void InitCpuTimers(void)
{
CpuTimer0.RegsAddr = &CpuTimer0Regs;
CpuTimer0Regs.PRD.all = 0xFFFFFFFF;
CpuTimer0Regs.TPR.all = 0;
CpuTimer0Regs.TPRH.all = 0;
CpuTimer0Regs.TCR.bit.TSS = 1;
CpuTimer0Regs.TCR.bit.TRB = 1;
CpuTimer0.InterruptCount = 0;
CpuTimer1.RegsAddr = &CpuTimer1Regs;
CpuTimer2.RegsAddr = &CpuTimer2Regs;
CpuTimer1Regs.PRD.all = 0xFFFFFFFF;
CpuTimer2Regs.PRD.all = 0xFFFFFFFF;
CpuTimer1Regs.TCR.bit.TSS = 1;
CpuTimer2Regs.TCR.bit.TSS = 1;
CpuTimer1Regs.TCR.bit.TRB = 1;
CpuTimer2Regs.TCR.bit.TRB = 1;
CpuTimer1.InterruptCount = 0;
CpuTimer2.InterruptCount = 0;
}
void ConfigCpuTimer(struct CPUTIMER_VARS *Timer, float Freq, float Period)
{
Uint32 temp;
Timer->CPUFreqInMHz = Freq;
Timer->PeriodInUSec = Period;
temp = (long) (Freq * Period);
Timer->RegsAddr->PRD.all = temp;
Timer->RegsAddr->TPR.all = 0;
Timer->RegsAddr->TPRH.all = 0;
Timer->RegsAddr->TCR.bit.TSS = 1;
Timer->RegsAddr->TCR.bit.TRB = 1;
Timer->RegsAddr->TCR.bit.SOFT = 1;
Timer->RegsAddr->TCR.bit.FREE = 1;
Timer->RegsAddr->TCR.bit.TIE = 1;
Timer->InterruptCount = 0;
}