31.TIM—基本定时器¶

31.TIM—基本定时器¶

31.4.2.2. 软件分析¶

基本定时器宏定义

代码清单:基本定时器-2 宏定义¶

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18/********************基本定时器TIM参数定义,只限TIM6、7************/

#define BASIC_TIM6 // 如果使用TIM7,注释掉这个宏即可

#ifdef BASIC_TIM6 // 使用基本定时器TIM6

#define BASIC_TIM TIM6

#define BASIC_TIM_APBxClock_FUN RCC_APB1PeriphClockCmd

#define BASIC_TIM_CLK RCC_APB1Periph_TIM6

#define BASIC_TIM_IRQ TIM6_IRQn

#define BASIC_TIM_IRQHandler TIM6_IRQHandler

#else // 使用基本定时器TIM7

#define BASIC_TIM TIM7

#define BASIC_TIM_APBxClock_FUN RCC_APB1PeriphClockCmd

#define BASIC_TIM_CLK RCC_APB1Periph_TIM7

#define BASIC_TIM_IRQ TIM7_IRQn

#define BASIC_TIM_IRQHandler TIM7_IRQHandler

#endif

基本定时器有 TIM6 和 TIM7,我们可以有选择的使用,为了提高代码的可移植性,我们把当需要修改定时器时需要修改的代码定义成宏,

默认使用的是定时器 6,如果想修改成定时器 7,只需要把宏 BASIC_TIM6 注释掉即可。

基本定时器配置

代码清单:基本定时器-3 基本定时器模式配置¶

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

38void BASIC_TIM_Config(void)

{

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

// 开启定时器时钟,即内部时钟CK_INT=72M

BASIC_TIM_APBxClock_FUN(BASIC_TIM_CLK, ENABLE);

// 自动重装载寄存器周的值(计数值)

TIM_TimeBaseStructure.TIM_Period=1000;

// 累计TIM_Period个频率后产生一个更新或者中断

// 时钟预分频数为71,则驱动计数器的时钟CK_CNT = CK_INT / (71+1)=1M

TIM_TimeBaseStructure.TIM_Prescaler= 71;

// 时钟分频因子 ,基本定时器没有,不用管

//TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;

// 计数器计数模式,基本定时器只能向上计数,没有计数模式的设置

//TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;

// 重复计数器的值,基本定时器没有,不用管

//TIM_TimeBaseStructure.TIM_RepetitionCounter=0;

// 初始化定时器

TIM_TimeBaseInit(BASIC_TIM, &TIM_TimeBaseStructure);

// 清除计数器中断标志位

TIM_ClearFlag(BASIC_TIM, TIM_FLAG_Update);

// 开启计数器中断

TIM_ITConfig(BASIC_TIM,TIM_IT_Update,ENABLE);

// 使能计数器

TIM_Cmd(BASIC_TIM, ENABLE);

// 暂时关闭定时器的时钟,等待使用

BASIC_TIM_APBxClock_FUN(BASIC_TIM_CLK, DISABLE);

}

我们把定时器设置自动重装载寄存器 ARR 的值为 1000,设置时钟预分频器为 71,

则驱动计数器的时钟:CK_CNT = CK_INT / (71+1)=1M,

则计数器计数一次的时间等于:1/CK_CNT=1us,当计数器计数到 ARR 的值 1000时,

产生一次中断,则中断一次的时间为:1/CK_CNT*ARR=1ms。

在初始化定时器的时候,我们定义了一个结构体:TIM_TimeBaseInitTypeDef,

TIM_TimeBaseInitTypeDef 结构体里面有 5 个成员,

TIM6 和 TIM7 的寄存器里面只有TIM_Prescaler 和 TIM_Period,另外三个成员基本定时器是没有的,

所以使用TIM6 和TIM7 的时候只需初始化这两个成员即可, 另外三个成员是通用定时器和高级定时器才有,具体说明如下:

typedef struct {

TIM_Prescaler // 都有

TIM_CounterMode // TIMx,x[6,7]没有,其他都有

TIM_Period // 都有

TIM_ClockDivision // TIMx,x[6,7]没有,其他都有

TIM_RepetitionCounter // TIMx,x[1,8,15,16,17]才有

} TIM_TimeBaseInitTypeDef;

其中 TIM15/16/17 只存在与互联型产品中,在 F1 大/中/小容量型号中没有。

定时器中断优先级配置

// 中断优先级配置

void BASIC_TIM_NVIC_Config(void)

{

NVIC_InitTypeDef NVIC_InitStructure;

// 设置中断组为0

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

// 设置中断来源

NVIC_InitStructure.NVIC_IRQChannel = BASIC_TIM_IRQ ;

// 设置主优先级为 0

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

// 设置抢占优先级为3

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

}

我们设置中断分组为 0,主优先级为 0,抢占优先级为 3。

定时器中断服务程序

void BASIC_TIM_IRQHandler (void)

{

if ( TIM_GetITStatus( BASIC_TIM, TIM_IT_Update) != RESET ) {

time++;

TIM_ClearITPendingBit(BASIC_TIM , TIM_FLAG_Update);

}

}

定时器中断一次的时间是 1ms,我们定义一个全局变量 time,每当进一次中断的时候,让time 来记录进入中断的次数。

如果我们想实现一个 1s 的定时,我们只需要判断 time 是否等于 1000 即可,1000 个 1ms 就是 1s。

然后把 time 清0,重新计数,以此循环往复。在中断服务程序的最后,要把相应的中断标志位清除掉,切记。

主函数

int main(void)

{

/* led 端口配置 */

LED_GPIO_Config();

/* 基本定时器 TIMx,x[6,7] 定时配置 */

BASIC_TIM_Config();

/* 配置基本定时器 TIMx,x[6,7]的中断优先级 */

BASIC_TIM_NVIC_Config();

/* 基本定时器 TIMx,x[6,7] 重新开时钟,开始计时 */

BASIC_TIM_APBxClock_FUN(BASIC_TIM_CLK, ENABLE);

while (1) {

if ( time == 1000 ) { /* 1000 * 1 ms = 1s 时间到 */

time = 0;

/* LED1 取反 */

LED1_TOGGLE;

}

}

}

主函数做一些必须的初始化,然后在一个死循环中不断的判断 time 的值,time的值在定时器中断改变,

每加一次表示定时器过了 1ms,当 time 等于 1000 时,1s时间到,LED1翻转一次,并把 time 清 0。

相关推荐

完全不知道主力咋想的,一个劲的压盘
365bet娱乐场官网备用

完全不知道主力咋想的,一个劲的压盘

📅 06-30 👁️ 3754
Python教程
365bet下注

Python教程

📅 10-09 👁️ 8150
如何查看qq冻结时间
beat365体育亚洲版

如何查看qq冻结时间

📅 08-14 👁️ 8715