定时器&PWM应用编程

一、STM32定时器原理

1、基本概念
定时器是一种计时的工具,它具有延时、频率测量、PWM输出、电机控制及编码接口等功能.STM32F103微控制器内部集成了多个可编程定时器,可以分为基本定时器(TIM6和TIM7)、通用定时器(TIM2~TIM5)和高级定时器(TIM1、TIM8)3种类型。从功能上看,基本定时器的功能是通用定时器的子集,而通用定时器的功能又是高级定时器的一个子集。

2、工作原理

时钟源选择:首先需要选择定时器的时钟源。STM32定时器可以选择内部时钟源(如内部RC振荡器)或外部时钟源(如外部晶体振荡器)作为时钟输入。

预分频器设置:定时器的时钟源经过预分频器分频后作为计数器的时钟输入。预分频器可以将时钟源的频率降低,以适应不同的应用需求。

计数器配置:配置计数器的计数模式(向上计数、向下计数、向上/向下计数)、计数方向(递增或递减)以及计数器的初始值。

中断和事件配置:可以配置定时器的中断和事件,以便在计数器达到特定值或特定条件满足时触发中断或事件。

定时器操作:启动定时器后,计数器开始根据时钟源的输入递增或递减。可以通过读取计数器的值来获取定时器的当前计数值。
3、应用
STM32定时器广泛应用于各种领域,例如工业自动化、智能家居、医疗设备、汽车电子等。其中,常见的应用包括PWM波控制、脉冲计数、定时中断、输入捕获等。通过使用STM32定时器,可以实现对各种设备的精确控制和调节,提高系统的稳定性和可靠性

二、用定时器计数方式,控制LED以2s的频率周期性地亮-灭

1、创建工程

在这里插入图片描述
2.
在这里插入图片描述
3.在这里插入图片描述
4.在这里插入图片描述
5.在这里插入图片描述
6.在这里插入图片描述
7.在这里插入图片描述
8.在这里插入图片描述

2、代码修改

1.打开定时器

  HAL_TIM_Base_Start_IT(&htim2);   //打开定时器TIM2 

2.mian.c添加定时器中断回调函数

  void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{

	static uint32_t time_cnt =0;   //记录中断次数
	if(htim->Instance == TIM2)   
	{
		if(++time_cnt >= 40)   //判断是否已经达到两秒
		{
			time_cnt =0;       //点灯用的中断次数归零
			HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_7);    //改变LED所接引脚的电平
		}
	}
	
}

3、烧录执行结果

用定时器计数方式,控制LED以2s的频率周期性地亮-灭

三、采用定时器pwm模式,让 LED 以呼吸灯方式渐亮渐灭,周期为1~2秒

1、工程创建

以下为变动处
1.输出管脚为A1
在这里插入图片描述
2.
在这里插入图片描述
3.
在这里插入图片描述

2、代码编写

  HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2); 
  int pwm = 0;

2.主函数while循环中添加

	  while(pwm<500)
	  {
	   pwm = pwm + 10;
	   __HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_2,pwm);
	   HAL_Delay(20);//延时20毫秒
	  }
	  while(pwm>0)
	  {
	  pwm = pwm - 10;
	  __HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_2,pwm);
	  HAL_Delay(20);
	  }

3、烧录执行结果

呼吸灯

4、观察PWM输出波形

在这里插入图片描述
2.
在这里插入图片描述
3.
在这里插入图片描述
4.结果

PWM波形图

四、采用定时器的另外一个通道,编程采集上面的pwm输出信号,获得其周期和脉宽,并重定向输出到串口显示

1、工程创建

在这里插入图片描述

2、代码编写

#include "main.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
#include "string.h"
#include "stdio.h"

void SystemClock_Config(void);

uint8_t i = 0;
float Duty = 0;
float Frequency = 0;
uint16_t Cap_val1 = 0;
uint16_t Cap_val2 = 0;

int main(void)
{

  HAL_Init();

  MX_GPIO_Init();
  MX_TIM1_Init();
  MX_TIM2_Init();
  MX_TIM3_Init();
  MX_USART1_UART_Init();

  
	printf("串口通信测试\r\n");
    HAL_TIM_Base_Start_IT(&htim2); // 使能定时器及其更新中断
    HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); // 使能定时器及其PWM输出
    HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_1);       // 使能定时器及其输入捕获
    HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_2);       // 使能定时器及其输入捕获
    __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 10); // 设置一个PWM波形进行测量

  while (1)
  {
// 串口发送 频率 占空比
      	  
      printf("Cap_val1 is :%d ,  Cap_val2 is : %d \r\n", Cap_val1, Cap_val2);
        printf("Duty is :%0.2f%% Frequency is : %0.2f ms\r\n", Duty, Frequency);
	  HAL_Delay(1000);

  }
  /* USER CODE END 3 */
}

// 定时输入捕获回调函数 计算占空比和频率
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
    if (htim->Instance == TIM1)
    {
        if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
        {
            Cap_val1 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
        }
        if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
        {
            Cap_val2 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2);
            Duty = 100 - (float)Cap_val2 / (float)Cap_val1 * 100;
            Frequency = 0.001 * Cap_val1;
        }
    }
	
}

int fputc(int ch, FILE *f)
 
{
 
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
 
  return ch;
 
}

/**
  * @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();
  }
}


void Error_Handler(void)
{

  __disable_irq();
  while (1)
  {
  }

}

#ifdef  USE_FULL_ASSERT

void assert_failed(uint8_t *file, uint32_t line)
{

}
#endif /* USE_FULL_ASSERT */

3、烧录执行结果

在这里插入图片描述
参考:
1.https://blog.csdn.net/liuwei1015/article/details/134234729
2.https://blog.csdn.net/qq_64120195/article/details/134222208
3.https://blog.csdn.net/m0_63650001/article/details/134169585

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: STM32F4系列微控制器中的高级定时器,可以用来产生PWM(脉宽调制)信号。PWM信号常用于电机驱动、LED灯控制、音频信号生成等应用。 首先,我们需要选择一个高级定时器来作为PWM输出源。STM32F4系列微控制器有多个高级定时器可供选择,如定时器1(TIM1)、定时器2(TIM2)、定时器3(TIM3)等。我们可以根据具体需求选择一个合适的定时器。 然后,在初始化定时器之前,需要先对GPIO端口进行配置。设置GPIO引脚的模式为复用模式,并选择合适的引脚复用功能,以使其连接到定时器的输出通道。 接下来,我们需要初始化选定的高级定时器。通过配置定时器的时钟源、分频系数和计数模式等参数,来设置定时器的工作频率和计数范围。同时,还需要配置定时器的模式为PWM输出模式,并选择合适的通道模式和极性。 在初始化完成后,我们可以通过修改定时器的自动重载寄存器(ARR)和占空比调整寄存器(CCR)来控制PWM信号的周期和占空比。自动重载寄存器用于设置PWM信号的周期,占空比调整寄存器则用于设置PWM信号的占空比。 最后,启动定时器即可开始输出PWM信号。通过设置定时器的使能位,我们可以启动定时器开始计数,并将生成的PWM信号输出到相应的GPIO引脚。 需要注意的是,通过高级定时器输出PWM信号时,需要仔细计算和设置定时器的参数,确保生成的PWM信号满足具体应用要求。 以上就是使用STM32F4高级定时器输出PWM的基本步骤。当然,具体的实现还需要根据具体芯片型号和使用的开发环境来进行细致调整和配置。 ### 回答2: STM32F4高级定时器是一种功能强大的定时器模块,可用于输出PWM信号。以下是使用STM32F4高级定时器输出PWM的步骤: 第一步,配置定时器: 首先,选择要使用的定时器,如TIM1、TIM2等。然后,根据需要配置周期、分频系数和计数模式等参数。可通过寄存器设置或使用STM32CubeMX进行配置。 第二步,配置PWM模式: 选择PWM输出模式,例如选择PWM模式1或2。配置输出通道的极性、周期和占空比等参数。此外,还可以设置多通道的自动更新和互补输出功能。 第三步,配置GPIO引脚: 选定用于输出PWM信号的GPIO引脚,并配置为复用功能。确保GPIO引脚与定时器通道相匹配。 第四步,编程实现PWM输出: 使用适当的编程语言,例如C或汇编语言,编写程序以初始化和启动定时器。在程序中,设置PWM的周期和占空比,然后启动定时器。 第五步,输出PWM信号: 定时器开始计数后,会自动输出PWM信号。根据配置的周期和占空比参数,定时器会生成相应的PWM波形信号。 除了上述步骤外,还可以根据需要使用中断来处理定时器事件。通过配置中断服务例程,可以在定时器溢出、计数匹配等事件发生时执行特定的操作,以实现更精确的控制。 总之,STM32F4高级定时器提供了强大的PWM输出功能,通过适当的配置和编程,可以实现高精度的PWM信号输出。 ### 回答3: STM32F4系列微控制器中的高级定时器(advanced timer)可以用于输出PWM信号。以下是使用STM32CubeIDE配置高级定时器输出PWM的步骤: 1. 在STM32CubeIDE中创建一个新的工程,并选择适合的STM32F4系列微控制器型号。 2. 打开RCC配置工具,在高级定时器的时钟源中选择合适的时钟源,例如内部时钟。 3. 打开GPIO配置工具,选择需要使用的IO引脚,并将其配置为复用功能。 4. 打开定时器配置工具,选择需要使用的高级定时器(如TIM1、TIM2等)。根据需要,配置定时器的计数模式、计数频率、自动重装载值等。 5. 配置定时器通道,选择需要用于PWM输出的通道,并设置通道的输出模式为PWM模式。 6. 根据具体需求设置PWM的周期和占空比。可以通过调整自动重装载值和通道的比较值来实现。 7. 配置定时器的时钟分频系数,使其与所需的PWM频率相匹配。 8. 生成代码,并将生成的代码添加到工程中。 9. 在生成的代码中,根据需要调用HAL库提供的函数来启动和停止定时器。 通过上述步骤,就可以使用STM32F4的高级定时器输出PWM信号了。在实际应用中,还可以根据需要调整PWM的周期、占空比以及使用中断等功能来实现更复杂的PWM输出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值