HAL库 TIM计数器及中断开启过程

1、初始化TIM基本计数器参数

1void MX_TIM2_Init(void) 2{ 3 TIM_ClockConfigTypeDef sClockSourceConfig = {0}; 4 TIM_MasterConfigTypeDef sMasterConfig = {0}; 5 6 htim2.Instance = TIM2; 7 htim2.Init.Prescaler = 36000-1; 8 htim2.Init.CounterMode = TIM_COUNTERMODE_UP; 9 htim2.Init.Period = 2000-1; 10 htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; 11 htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; 12 if (HAL_TIM_Base_Init(&htim2) != HAL_OK) 13 { 14 Error_Handler(); 15 } 16 sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; 17 if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK) 18 { 19 Error_Handler(); 20 } 21 sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; 22 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; 23 if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) 24 { 25 Error_Handler(); 26 } 27 28}

2、**HAL_TIM_Base_Init(&htim2)**应用参数基本参数配置

1HAL_StatusTypeDef HAL_TIM_Base_Init(TIM_HandleTypeDef *htim) 2{ 3 /* Check the TIM handle allocation */ 4 if (htim == NULL) 5 { 6 return HAL_ERROR; 7 } 8 9 /* Check the parameters */ 10 assert_param(IS_TIM_INSTANCE(htim->Instance)); 11 assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode)); 12 assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision)); 13 assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload)); 14 15 if (htim->State == HAL_TIM_STATE_RESET) 16 { 17 /* Allocate lock resource and initialize it */ 18 htim->Lock = HAL_UNLOCKED; 19 20#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) 21 /* Reset interrupt callbacks to legacy weak callbacks */ 22 TIM_ResetCallback(htim); 23 24 if (htim->Base_MspInitCallback == NULL) 25 { 26 htim->Base_MspInitCallback = HAL_TIM_Base_MspInit; 27 } 28 /* Init the low level hardware : GPIO, CLOCK, NVIC */ 29 htim->Base_MspInitCallback(htim); 30#else 31 /* Init the low level hardware : GPIO, CLOCK, NVIC */ 32 HAL_TIM_Base_MspInit(htim); 33#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ 34 } 35 36 /* Set the TIM state */ 37 htim->State = HAL_TIM_STATE_BUSY; 38 39 /* Set the Time Base configuration */ 40 TIM_Base_SetConfig(htim->Instance, &htim->Init); 41 42 /* Initialize the TIM state*/ 43 htim->State = HAL_TIM_STATE_READY; 44 45 return HAL_OK; 46}

3、HAL_TIM_Base_MspInit(htim) 初始化中断信息(该函数需要重写,CubeMX在配置生成代码时会自动重写该函数)

1/** 2 * @brief Initializes the TIM Base MSP. 3 * @param htim TIM Base handle 4 * @retval None 5 */ 6__weak void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim) 7{ 8 /* Prevent unused argument(s) compilation warning */ 9 UNUSED(htim); 10 11 /* NOTE : This function should not be modified, when the callback is needed, 12 the HAL_TIM_Base_MspInit could be implemented in the user file 13 */ 14}

重写实现

1void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle) 2{ 3 4 if(tim_baseHandle->Instance==TIM2) 5 { 6 /* USER CODE BEGIN TIM2_MspInit 0 */ 7 8 /* USER CODE END TIM2_MspInit 0 */ 9 /* TIM2 clock enable */ 10 __HAL_RCC_TIM2_CLK_ENABLE(); 11 12 /* TIM2 interrupt Init */ 13 HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0); 14 HAL_NVIC_EnableIRQ(TIM2_IRQn); 15 /* USER CODE BEGIN TIM2_MspInit 1 */ 16 17 /* USER CODE END TIM2_MspInit 1 */ 18 } 19}

4、使能TIM中断

虽然经过以上配置,TIM的参数信息都已完整应用,但是TIM的中断并没用真正使能.这个地方困扰了我好久(运行没错误,但是计数中断就不触发, 不计数),必需调用以下函数使能中断,串口中断使能也是类似的.

HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *TIM);//开启定时器中断

该函数的调用地点只要是在 HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle) 函数之后就行,可以在main.c中也可以在上面的代码之后.

下面的代码存在一个BUG,如果 HAL_TIM_Base_Start_IT 函数调用写在下面的位置,虽然可以使能中断,但会造成MCU上电即触发中断的情况.

HAL_TIM_Base_MspInit调用之后会重新设置寄存器的值,__HAL_TIM_CLEAR_FLAG(tim_baseHandle, TIM_SR_UIF)清理的寄存器被改写.

1void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle) 2{ 3 4 if(tim_baseHandle->Instance==TIM2) 5 { 6 /* USER CODE BEGIN TIM2_MspInit 0 */ 7 8 /* USER CODE END TIM2_MspInit 0 */ 9 /* TIM2 clock enable */ 10 __HAL_RCC_TIM2_CLK_ENABLE(); 11 12 /* TIM2 interrupt Init */ 13 HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0); 14 HAL_NVIC_EnableIRQ(TIM2_IRQn); 15 /* USER CODE BEGIN TIM2_MspInit 1 */ 16 //清理TIM开启时的中断标识 17 __HAL_TIM_CLEAR_FLAG(tim_baseHandle, TIM_SR_UIF);//添加这条语句解决问题 18 //htim2.Instance->SR = 0; //这是另一种解决办法 19 //使能TIM中断 20 HAL_TIM_Base_Start_IT(tim_baseHandle); 21 /* USER CODE END TIM2_MspInit 1 */ 22 } 23}

正确的做法是在 HAL_TIM_Base_Init(&htim2) 之后使能TIM中断,并清理TIM的更新中断寄存器

1void MX_TIM2_Init(void) 2{ 3 TIM_ClockConfigTypeDef sClockSourceConfig = {0}; 4 TIM_MasterConfigTypeDef sMasterConfig = {0}; 5 6 htim2.Instance = TIM2; 7 htim2.Init.Prescaler = 36000-1; 8 htim2.Init.CounterMode = TIM_COUNTERMODE_UP; 9 htim2.Init.Period = 10000-1; 10 htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; 11 htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; 12 if (HAL_TIM_Base_Init(&htim2) != HAL_OK) 13 { 14 Error_Handler(); 15 } 16 sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; 17 if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK) 18 { 19 Error_Handler(); 20 } 21 sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; 22 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; 23 if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) 24 { 25 Error_Handler(); 26 } 27 28 //清理TIM开启时的中断标识 29 __HAL_TIM_CLEAR_IT(&htim2, TIM_IT_UPDATE); 30 //使能TIM中断 31 HAL_TIM_Base_Start_IT(&htim2); 32}

5、计数中断处理

1/** 2 * @brief This function handles TIM2 global interrupt. 3 */ 4void TIM2_IRQHandler(void) 5{ 6 /* USER CODE BEGIN TIM2_IRQn 0 */ 7 8 /* USER CODE END TIM2_IRQn 0 */ 9 HAL_TIM_IRQHandler(&htim2); 10 /* USER CODE BEGIN TIM2_IRQn 1 */ 11 12 /* USER CODE END TIM2_IRQn 1 */ 13} 14 15HAL_TIM_IRQHandler(&htim2)中断函数处理 16 17/** 18 * @brief This function handles TIM interrupts requests. 19 * @param htim TIM handle 20 * @retval None 21 */ 22void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim) 23{ 24 /* Capture compare 1 event */ 25 if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC1) != RESET) 26 { 27 if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC1) != RESET) 28 { 29 { 30 __HAL_TIM_CLEAR_IT(htim, TIM_IT_CC1); 31 htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1; 32 33 /* Input capture event */ 34 if ((htim->Instance->CCMR1 & TIM_CCMR1_CC1S) != 0x00U) 35 { 36#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) 37 htim->IC_CaptureCallback(htim); 38#else 39 HAL_TIM_IC_CaptureCallback(htim); 40#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ 41 } 42 /* Output compare event */ 43 else 44 { 45#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) 46 htim->OC_DelayElapsedCallback(htim); 47 htim->PWM_PulseFinishedCallback(htim); 48#else 49 HAL_TIM_OC_DelayElapsedCallback(htim); 50 HAL_TIM_PWM_PulseFinishedCallback(htim); 51#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ 52 } 53 htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; 54 } 55 } 56 } 57........................ 58........................ 59 /* TIM Update event */ 60 if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_UPDATE) != RESET) 61 { 62 if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_UPDATE) != RESET) 63 { 64 __HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE); 65#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) 66 htim->PeriodElapsedCallback(htim); 67#else 68 HAL_TIM_PeriodElapsedCallback(htim); 69#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ 70 } 71 } 72........................ 73........................ 74 75} 76 77HAL_TIM_PeriodElapsedCallback(htim);当计数溢出时调用的回调函数,需要用户根据实际需求具体实现 78 79/** 80 * @brief Period elapsed callback in non-blocking mode 81 * @param htim TIM handle 82 * @retval None 83 */ 84__weak void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) 85{ 86 /* Prevent unused argument(s) compilation warning */ 87 UNUSED(htim); 88 89 /* NOTE : This function should not be modified, when the callback is needed, 90 the HAL_TIM_PeriodElapsedCallback could be implemented in the user file 91 */ 92}

6、实现计数完成回调函数,调试代码,查看计数器中断效果.

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )