一些比较好的笔记
原作者网址:https://github.com/0x1abin/MultiTimer
网上有很多教程,但是原作者已经重新开发了一套,但是博客作者没有更新
https://blog.csdn.net/qq_36075612/article/details/115636523?utm_medium=distribute.pc_relevant.none-task-blog-2
https://blog.csdn.net/qq_36075612/article/details/115636523?utm_medium=distribute.pc_relevant.none-task-blog-2
本来想去找基于HAL开发MultiTimer,却让我找到一个关于HAL库Systick-系统滴答定时器详解,文章确实写的很不错
https://blog.51cto.com/u_12968763/5078642
https://blog.51cto.com/u_12968763/5078642
找了很久才找到一个新的教程,但是这个教程乍一看有点乱,其实细看还好,结尾还说了一些实现的原理
https://blog.csdn.net/Mculover666/article/details/124359206
https://blog.csdn.net/Mculover666/article/details/124359206
接下来我将我移植的步骤记录下来,作为纯开发记录
- 移植.h 和 .c文件
这个我相信大家都是懂的,并且在你的main.c文件中include进来
- 在main函数开始后的初始化中,安装tick函数
- 在main函数前面定义的地方,获取系统 tick
- 在定义变量的地方,创建Timer对象
- 在声明函数的地方,声明Timer回调函数
- 在函数定义的地方,实现Timer回调函数功能
- 在main函数while开始前面,启动定时器
- 在主循环while中调用Timer对象处理函数
至此,函数已经分类实现完毕,接下来给一份完整main.c文件,作为参考
/* USER CODE BEGIN Header *//** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * * Copyright (c) 2023 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** *//* USER CODE END Header *//* Includes ------------------------------------------------------------------*/#include "main.h"#include "gpio.h"/* Private includes ----------------------------------------------------------*//* USER CODE BEGIN Includes */#include "MultiTimer.h"/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*//* USER CODE BEGIN PTD */#define TIMER1 2#define TIMER2 500/* USER CODE END PTD *//* Private define ------------------------------------------------------------*//* USER CODE BEGIN PD *//* USER CODE END PD *//* Private macro -------------------------------------------------------------*//* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*/MultiTimer timer1;MultiTimer timer2;/* USER CODE BEGIN PV *//* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/void SystemClock_Config(void);/* USER CODE BEGIN PFP */void timer1_callback(MultiTimer* timer, void* userData);void timer2_callback(MultiTimer* timer, void* userData);/* USER CODE END PFP *//* Private user code ---------------------------------------------------------*//* USER CODE BEGIN 0 */uint64_t PlatformTicksGetFunc(void){ return (uint64_t)HAL_GetTick();}/* USER CODE END 0 *//** * @brief The application entry point. * @retval int */int main(int argc, char *argv[]){ /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); /* USER CODE BEGIN 2 */ MultiTimerInstall(PlatformTicksGetFunc); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ MultiTimerStart(&timer1, TIMER1, timer1_callback, NULL); MultiTimerStart(&timer2, TIMER2, timer2_callback, NULL); while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ MultiTimerYield(); } /* USER CODE END 3 */}/** * @brief System Clock Configuration * @retval None */void SystemClock_Config(void){ RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { Error_Handler(); }}/* USER CODE BEGIN 4 */void timer1_callback(MultiTimer* timer, void* userData){ HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin); MultiTimerStart(&timer1, TIMER1, timer1_callback, NULL);}void timer2_callback(MultiTimer* timer, void* userData){ MultiTimerStart(&timer2, TIMER2, timer2_callback, NULL);}/* USER CODE END 4 *//** * @brief This function is executed in case of error occurrence. * @retval None */void Error_Handler(void){ /* USER CODE BEGIN Error_Handler_Debug */ /* User can add his own implementation to report the HAL error return state */ __disable_irq(); while (1) { } /* USER CODE END Error_Handler_Debug */}#ifdef USE_FULL_ASSERT/** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */void assert_failed(uint8_t *file, uint32_t line){ /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */}#endif /* USE_FULL_ASSERT */