目录
定时器介绍
定时器工作原理:
定时器分类:
STM32F103C8T6定时器资源:
编辑
通用定时器介绍:
定时器计数模式:
定时器时钟源:
编辑 定时器溢出时间计算公式:
定时器中断实验
PWM介绍
STM32F103C8T6 PWM资源:
PWM周期与频率:
PWM实验
4. 业务代码
定时器介绍
软件定时
缺点:不精确、占用
CPU
资源
void Delay500ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
i = 4;
j = 129;
k = 119;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
定时器工作原理:
使用精准的时基,通过硬件的方式,实现定时功能。定时器核心就是计数器。
定时器分类:
- 基本定时器(TIM6~TIM7)
- 通用定时器(TIM2~TIM5)
- 高级定时器(TIM1和TIM8)
STM32F103C8T6定时器资源:
通用定时器介绍:
1 ) 16 位向上、向下、向上 / 向下自动装载计数器(TIMx_CNT )。2 ) 16 位可编程 ( 可以实时修改 ) 预分频器 ( TIMx_PSC ) ,计数器时钟频率的分频系数为 1 ~ 65535 之间的任意数值。3 ) 4 个独立通道(TIMx_CH1 ~ 4 ),这些通道可以用来作为:A .输入捕获B .输出比较C . PWM 生成 ( 边缘或中间对齐模式 )D .单脉冲模式输出4 )可使用外部信号(TIMx_ETR )控制定时器和定时器互连(可以用 1 个定时器控制另外一个定时器)的同步电路。5 )如下事件发生时产生中断 / DMA :A .更新:计数器向上溢出 / 向下溢出,计数器初始化 ( 通过软件或者内部 / 外部触发 )B .触发事件 ( 计数器启动、停止、初始化或者由内部 / 外部触发计数 )C .输入捕获D .输出比较E .支持针对定位的增量 ( 正交 ) 编码器和霍尔传感器电路F .触发输入作为外部时钟或者按周期的电流管理
定时器计数模式:
定时器时钟源:
定时器溢出时间计算公式:
例如,要定时500ms,则:PSC=7199,ARR=4999,Tclk=72M
定时器中断实验
需求:使用定时器中断方法,每
500ms
翻转一次
LED1
灯状态。
1. RCC
配置
2. LED1
灯配置
3.
时钟数配置
4. TIM2
配置
5. 工程配置
6. 重写更新中断回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM2)
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_8);
}
7. 启动定时器
在
main.c
中,在定时器初始化命令之后加入以下代码:
HAL_TIM_Base_Start_IT(&htim2);
PWM介绍
STM32F103C8T6 PWM资源:
高级定时器(
TIM1
):
7
路
通用定时器(
TIM2~TIM4
):各
4
路
PWM
输出模式:
PWM
模式
1
:在向上计数时,一旦
CNT < CCRx
时输出为有效电平,否则为无效电平;
在向
下计数时,一旦
CNT > CCRx
时输出为无效电平,否则为有效电平。
PWM
模式
2
:在向上计数时,一旦
CNT < CCRx
时输出为无效电平,否则为有效电平;
在向
下计数时,一旦
CNT > CCRx
时输出为有效电平,否则为无效电平。
PWM周期与频率:
PWM占空比:
由TIMx_CCRx寄存器决定。
PWM实验
需求:使用
PWM
点亮
LED1
实现呼吸灯效果。
LED
灯为什么可以越来越亮,越来越暗?
这是由不同的占空比决定的。
如何计算周期
/
频率?
假如频率为
2kHz
,则:
PSC=71
,
ARR=499
LED1
连接到哪个定时器的哪一路?
学会看产品手册:
1.
设置时钟
2.
设置定时器
记得把极性设置为
Low
,因为
LED
灯是低电平才亮。
3. 配置工程
4. 业务代码
/* 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 "tim.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* 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 ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
uint16_t pwmVal=0;
uint8_t dir=1;
/* 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();
MX_TIM4_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_3);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
HAL_Delay(1);
if (dir)
pwmVal++;
else
pwmVal--;
if (pwmVal > 500)
dir = 0;
if (pwmVal == 0)
dir =1;
//修改比较值,修改占空比
__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_3, pwmVal);
/* USER CODE BEGIN 3 */
}
/* 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 */
/* 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 */