stm32通用定时器互补输出

stm32通用定时器

框图

stm32通用定时器互补输出_第1张图片

时钟源

stm32通用定时器互补输出_第2张图片

控制器ddd

时基单元

输入捕获

输出比较

框图

stm32通用定时器互补输出_第3张图片
只看白色部分分析:在捕获/比较预装载寄存器中写入CCR1的值(ARR),在写的过程中SR输出为1反向为零右侧三输入与门输出为0不想影子寄存器中写值,当捕获/比较预装载寄存器中写入CCR1的值(CCR1)写完则SR输出为0反向1右侧。CC1S两个为00时或非门输出为1。OC1PE预装载使能为1反向为0,即只有来自时钟源的基准时基产生U事件(溢出记满ARR或减为零)为1,或 上0输出为1。三个条件同时满足时向影子寄存器写入值。然后通过比较器比较CCR1和当前值。控制输出高低电平。
stm32通用定时器互补输出_第4张图片
ETRF为强制清零位由OC1CE。OC1M[2:0]配置输出模式。通过TIMx_CCER配置吉星。CC1E输出使能控制OC1输出相应电平。

寄存器

stm32通用定时器互补输出_第5张图片
stm32通用定时器互补输出_第6张图片
stm32通用定时器互补输出_第7张图片
stm32通用定时器互补输出_第8张图片
stm32通用定时器互补输出_第9张图片
stm32通用定时器互补输出_第10张图片
寄存器太多不详述。
stm32通用定时器互补输出_第11张图片
stm32通用定时器互补输出_第12张图片

代码分析


#include "pwm.h"
#include "usart.h"
#include "stdio.h"
TIM_HandleTypeDef g_timx_handle;//定时器初始化结构体
void MX_general_time_Init(uint16_t arr,uint16_t psc)
{
	TIM_OC_InitTypeDef timx_oc_pwm_chy={0};//输出比较 初始化结构体
	g_timx_handle.Instance=TIM14;//选用定时器14
	g_timx_handle.Init.CounterMode=TIM_COUNTERMODE_UP;//设置为向上计数模式
	//预分频值
	g_timx_handle.Init.Prescaler=psc;
	//重装载值
	g_timx_handle.Init.Period=arr;
	HAL_TIM_PWM_Init(&g_timx_handle);//以PWM形式初始化定时器14,或者叫初始化tim pwm 的时基
	
	timx_oc_pwm_chy.OCMode=TIM_OCMODE_PWM1;//PWM mode 1  只需要结构体中这三个参数
	timx_oc_pwm_chy.Pulse=arr/2;//占空比50%
	timx_oc_pwm_chy.OCPolarity=TIM_OCPOLARITY_LOW;//输出极性
	HAL_TIM_PWM_ConfigChannel(&g_timx_handle,&timx_oc_pwm_chy,TIM_CHANNEL_1);//初始化TIM PWM通道
  HAL_TIM_PWM_Start_IT(&g_timx_handle,TIM_CHANNEL_1);  


}
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)/* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
{
	if(htim->Instance==g_timx_handle.Instance)
	{
		//使能时钟
		__HAL_RCC_TIM14_CLK_ENABLE();
	
		__HAL_RCC_GPIOF_CLK_ENABLE();
		
			GPIO_InitTypeDef gpio_init_struct;
		
		gpio_init_struct.Pin=GPIO_PIN_9;
		gpio_init_struct.Mode=GPIO_MODE_AF_PP;
		gpio_init_struct.Pull	= GPIO_PULLUP;
		gpio_init_struct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
		gpio_init_struct.Alternate = GPIO_AF9_TIM14;
		HAL_GPIO_Init(GPIOF,&gpio_init_struct);
		

	}
}

main函数


#include "main.h"
#include "gpio.h"
#include "stdio.h"
#include "usart.h"
#include "pwm.h"
void SystemClock_Config(void);

int main(void)
{
    uint16_t ledrpwmval = 0;
    uint8_t dir = 1;
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();


  MX_GPIO_Init();
	usart_Init();
	 MX_general_time_Init( 500 - 1, 84 - 1);//初始化设置 时间计算 84/84M*500= 500 us 即2K
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
	printf("demo!!!\r\n");
  while (1)
  {
    
        HAL_Delay(10);//控制变化频率时间越小变化越快

        if (dir)ledrpwmval++;                   /* dir==1 ledrpwmval递增 */
        else ledrpwmval--;                      /* dir==0 ledrpwmval递减 */

        if (ledrpwmval > 300)dir = 0;           /* ledrpwmval到达300后,方向为递减 */
        if (ledrpwmval == 0)dir = 1;            /* ledrpwmval递减到0后,方向改为递增 */

        /* 修改比较值控制占空比 */
        __HAL_TIM_SET_COMPARE(&g_timx_handle, TIM_CHANNEL_1, ledrpwmval);//每10ms写一次这个值
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  /** 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.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 25;
  RCC_OscInitStruct.PLL.PLLN = 336;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  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_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != 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 */

总结

配置步骤:1.定时器初始化 MX_general_time_Init(uint16_t arr,uint16_t psc)
				完成定时器选择,计数方式,设置预分频值,重装载值,初始化TIM PWM的时基
				oc模式设置PWM模式,设置CCR1值确定脉宽,设置输出极性(PWM模式和输出极性共同控制输出波形的极性)
				初始化TIM PWM通道
				2.写GPIO初始化函数
					完成开启定时器时钟,GPIO时钟,初始化GPIO引脚模式复用推挽,输出速度快速,复用功能
				3.主函数每隔固定时间控制占空比

你可能感兴趣的:(stm32,嵌入式硬件,单片机)