一、工具
1、硬件:STM32L053R8单片机(HAL库)
2、编译环境:Atollic TrueSTUDIO for STM32 9.3.0
3、辅助工具:STM32CubeMX
二、单片机系统时钟配置
1、系统时钟配置(没有显示的默认),这里选择的是内部的高速时钟(HSI)作为时钟源,系统时钟频率配置到24MHz。
三、定时器配置
1、选用的定时器为TIM22,时钟源选择内部时钟,即24MHz,分频值为24(设置值为24-1),自动重装载值为1000(设置值为1000-1),得到该定时器的周期为(1000x24)/24000000 = 1ms。
2、使能定时器中断
四、生成工程并进行完善
1、工程生成设置
2、完善代码
因为用到了定时器中断,在配置完定时器后,在定时器启动之前清除一下更新事件中断以防止中断提前触发(开启定时器中断后,每隔一个周期硬件就把定时器更新事件置1)。
/** * @brief TIM22 Initialization Function * @param None * @retval None */ static void MX_TIM22_Init(void) { /* USER CODE BEGIN TIM22_Init 0 */ /* USER CODE END TIM22_Init 0 */ TIM_ClockConfigTypeDef sClockSourceConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; /* USER CODE BEGIN TIM22_Init 1 */ /* 定时器设定的是1ms延时产生一次中断 */ /* USER CODE END TIM22_Init 1 */ htim22.Instance = TIM22; htim22.Init.Prescaler = 23; htim22.Init.CounterMode = TIM_COUNTERMODE_UP; htim22.Init.Period = 999; htim22.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim22.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_Base_Init(&htim22) != HAL_OK) { Error_Handler(); } sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; if (HAL_TIM_ConfigClockSource(&htim22, &sClockSourceConfig) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim22, &sMasterConfig) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN TIM22_Init 2 */ __HAL_TIM_CLEAR_IT(&htim22, TIM_IT_UPDATE); /* USER CODE END TIM22_Init 2 */ }
定时器中断响应后会调用一个回调函数,该函数的内容可以由用户自己添加(该函数为固定写法不能随意更改)。
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if(htim->Instance == TIM22) { HAL_TIM_Base_Stop_IT(&htim22); } }
3、其它不用修改的代码
定时器时钟控制和中断设置。
/** * @brief TIM_Base MSP Initialization * This function configures the hardware resources used in this example * @param htim_base: TIM_Base handle pointer * @retval None */ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base) { if(htim_base->Instance==TIM22) { /* USER CODE BEGIN TIM22_MspInit 0 */ /* USER CODE END TIM22_MspInit 0 */ /* Peripheral clock enable */ __HAL_RCC_TIM22_CLK_ENABLE(); /* TIM22 interrupt Init */ HAL_NVIC_SetPriority(TIM22_IRQn, 0, 0); HAL_NVIC_EnableIRQ(TIM22_IRQn); /* USER CODE BEGIN TIM22_MspInit 1 */ /* USER CODE END TIM22_MspInit 1 */ } } /** * @brief TIM_Base MSP De-Initialization * This function freeze the hardware resources used in this example * @param htim_base: TIM_Base handle pointer * @retval None */ void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base) { if(htim_base->Instance==TIM22) { /* USER CODE BEGIN TIM22_MspDeInit 0 */ /* USER CODE END TIM22_MspDeInit 0 */ /* Peripheral clock disable */ __HAL_RCC_TIM22_CLK_DISABLE(); /* TIM22 interrupt DeInit */ HAL_NVIC_DisableIRQ(TIM22_IRQn); /* USER CODE BEGIN TIM22_MspDeInit 1 */ /* USER CODE END TIM22_MspDeInit 1 */ } }
定时器中断函数实现。
/** * @brief This function handles TIM22 global interrupt. */ void TIM22_IRQHandler(void) { /* USER CODE BEGIN TIM22_IRQn 0 */ /* USER CODE END TIM22_IRQn 0 */ HAL_TIM_IRQHandler(&htim22); /* USER CODE BEGIN TIM22_IRQn 1 */ /* USER CODE END TIM22_IRQn 1 */ }
4、启动定时器
在启动前清空计数器的内容,在有些情况下作用很大。
__HAL_TIM_SET_COUNTER(&htim22, 0); HAL_TIM_Base_Start_IT(&htim22);
#end