【STM32H7教程】第33章 STM32H7的定时器应用之TIM1-TIM17的中断实现

2023-04-23  

33.1 初学者重要提示

学习本章节前,务必优先学习第32章,HAL库的几个常用API均作了讲解和举例。

STM32H7支持TIM1-TIM8,TIM12-TIM17共14个定时器,而中间的TIM9,TIM10,TIM11是不存在的,这点要注意。

STM32H7的进出中断的速度能跑到12.5MHz,所有程序在TCM和Flash运行没差别,详情可看本章2.3小节。

实际应用中,中断入口函数名称不要写错,有些中断的入口函数名称比较特殊,详情可看本章的2.2小节。

33.2 定时器中断的驱动设计

定时器中断的实现相对比较简单,仅需一个函数即可实现TIM1-TIM17定时器的中断更新配置。


33.2.1 定时器中断初始化

实现代码如下:


1.    /* 

2.    ******************************************************************************************************

3.    *    函 数 名: bsp_RCC_TIM_Enable

4.    *    功能说明: 使能TIM RCC 时钟

5.    *    形    参: 无

6.    *    返 回 值: 无

7.    ******************************************************************************************************

8.    */

9.    void bsp_RCC_TIM_Enable(TIM_TypeDef* TIMx)

10.    {

11.        if (TIMx == TIM1) __HAL_RCC_TIM1_CLK_ENABLE();

12.        else if (TIMx == TIM2) __HAL_RCC_TIM2_CLK_ENABLE();

13.        else if (TIMx == TIM3) __HAL_RCC_TIM3_CLK_ENABLE();

14.        else if (TIMx == TIM4) __HAL_RCC_TIM4_CLK_ENABLE();

15.        else if (TIMx == TIM5) __HAL_RCC_TIM5_CLK_ENABLE();

16.        else if (TIMx == TIM6) __HAL_RCC_TIM6_CLK_ENABLE();

17.        else if (TIMx == TIM7) __HAL_RCC_TIM7_CLK_ENABLE();

18.        else if (TIMx == TIM8) __HAL_RCC_TIM8_CLK_ENABLE();

19.    //    else if (TIMx == TIM9) __HAL_RCC_TIM9_CLK_ENABLE();

20.    //    else if (TIMx == TIM10) __HAL_RCC_TIM10_CLK_ENABLE();

21.    //    else if (TIMx == TIM11) __HAL_RCC_TIM11_CLK_ENABLE();

22.        else if (TIMx == TIM12) __HAL_RCC_TIM12_CLK_ENABLE();

23.        else if (TIMx == TIM13) __HAL_RCC_TIM13_CLK_ENABLE();

24.        else if (TIMx == TIM14) __HAL_RCC_TIM14_CLK_ENABLE();

25.        else if (TIMx == TIM15) __HAL_RCC_TIM15_CLK_ENABLE();

26.        else if (TIMx == TIM16) __HAL_RCC_TIM16_CLK_ENABLE();

27.        else if (TIMx == TIM17) __HAL_RCC_TIM17_CLK_ENABLE();    

28.        else

29.        {

30.            Error_Handler(__FILE__, __LINE__);

31.        }    

32.    }

33.    

34.    /*

35.    ******************************************************************************************************

36.    *    函 数 名: bsp_SetTIMforInt

37.    *    功能说明: 配置TIM和NVIC,用于简单的定时中断,开启定时中断。另外注意中断服务程序需要由用户应

38.    *              用程序实现。

39.    *    形    参: TIMx : 定时器

40.    *             _ulFreq : 定时频率 (Hz)。 0 表示关闭。

41.    *             _PreemptionPriority : 抢占优先级

42.    *             _SubPriority : 子优先级

43.    *    返 回 值: 无

44.    ******************************************************************************************************

45.    */

46.    void bsp_SetTIMforInt(TIM_TypeDef* TIMx, uint32_t _ulFreq, uint8_t _PreemptionPriority, 

47.                          uint8_t _SubPriority)

48.    {

49.        TIM_HandleTypeDef   TimHandle = {0};

50.        uint16_t usPeriod;

51.        uint16_t usPrescaler;

52.        uint32_t uiTIMxCLK;

53.        

54.        /* 使能TIM时钟 */

55.        bsp_RCC_TIM_Enable(TIMx);

56.        

57.        /*-----------------------------------------------------------------------

58.            bsp.c 文件中 void SystemClock_Config(void) 函数对时钟的配置如下: 

59.    

60.            System Clock source       = PLL (HSE)

61.            SYSCLK(Hz)                = 400000000 (CPU Clock)

62.            HCLK(Hz)                  = 200000000 (AXI and AHBs Clock)

63.            AHB Prescaler             = 2

64.            D1 APB3 Prescaler         = 2 (APB3 Clock  100MHz)

65.            D2 APB1 Prescaler         = 2 (APB1 Clock  100MHz)

66.            D2 APB2 Prescaler         = 2 (APB2 Clock  100MHz)

67.            D3 APB4 Prescaler         = 2 (APB4 Clock  100MHz)

68.    

69.            因为APB1 prescaler != 1, 所以 APB1上的TIMxCLK = APB1 x 2 = 200MHz;

70.            因为APB2 prescaler != 1, 所以 APB2上的TIMxCLK = APB2 x 2 = 200MHz;

71.            APB4上面的TIMxCLK没有分频,所以就是100MHz;

72.    

73.            APB1 定时器有 TIM2, TIM3 ,TIM4, TIM5, TIM6, TIM7, TIM12, TIM13, TIM14,LPTIM1

74.            APB2 定时器有 TIM1, TIM8 , TIM15, TIM16,TIM17

75.    

76.            APB4 定时器有 LPTIM2,LPTIM3,LPTIM4,LPTIM5

77.        ----------------------------------------------------------------------- */

78.        if ((TIMx == TIM1) || (TIMx == TIM8) || (TIMx == TIM15) || (TIMx == TIM16) || (TIMx == TIM17))

79.        {

80.            /* APB2 定时器时钟 = 200M */

81.            uiTIMxCLK = SystemCoreClock / 2;

82.        }

83.        else    

84.        {

85.            /* APB1 定时器 = 200M */

86.            uiTIMxCLK = SystemCoreClock / 2;

87.        }

88.    

89.        if (_ulFreq < 100)

90.        {

91.            usPrescaler = 10000 - 1;                    /* 分频比 = 10000 */

92.            usPeriod =  (uiTIMxCLK / 10000) / _ulFreq  - 1;        /* 自动重装的值 */

93.        }

94.        else if (_ulFreq < 3000)

95.        {

96.            usPrescaler = 100 - 1;                    /* 分频比 = 100 */

97.            usPeriod =  (uiTIMxCLK / 100) / _ulFreq  - 1;        /* 自动重装的值 */

98.        }

99.        else    /* 大于4K的频率,无需分频 */

100.        {

101.            usPrescaler = 0;                    /* 分频比 = 1 */

102.            usPeriod = uiTIMxCLK / _ulFreq - 1;    /* 自动重装的值 */

103.        }

104.    

105.        /* 

106.           定时器中断更新周期 = TIMxCLK / usPrescaler + 1)/usPeriod + 1)

107.        */

108.        TimHandle.Instance = TIMx;

109.        TimHandle.Init.Prescaler         = usPrescaler;

110.        TimHandle.Init.Period            = usPeriod;    

111.        TimHandle.Init.ClockDivision     = 0;

112.        TimHandle.Init.CounterMode       = TIM_COUNTERMODE_UP;

113.        TimHandle.Init.RepetitionCounter = 0;

114.        TimHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;

115.        if (HAL_TIM_Base_Init(&TimHandle) != HAL_OK)

116.        {

117.            Error_Handler(__FILE__, __LINE__);

118.        }

119.    

120.        /* 使能定时器中断  */

121.        __HAL_TIM_ENABLE_IT(&TimHandle, TIM_IT_UPDATE);

122.        

123.    

124.        /* 配置TIM定时更新中断 (Update) */

125.        {

126.            uint8_t irq = 0;    /* 中断号, 定义在 stm32h7xx.h */

127.            

128.            if (TIMx == TIM1) irq = TIM1_UP_IRQn;

129.            else if (TIMx == TIM2) irq = TIM2_IRQn;

130.            else if (TIMx == TIM3) irq = TIM3_IRQn;

131.            else if (TIMx == TIM4) irq = TIM4_IRQn;

132.            else if (TIMx == TIM5) irq = TIM5_IRQn;

133.            else if (TIMx == TIM6) irq = TIM6_DAC_IRQn;

134.            else if (TIMx == TIM7) irq = TIM7_IRQn;

135.            else if (TIMx == TIM8) irq = TIM8_UP_TIM13_IRQn;

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。