zoukankan      html  css  js  c++  java
  • Keil MDK STM32系列(七) STM32F4基于HAL的PWM和定时器

    Keil MDK STM32系列

    配置 PWM 输出

    • 选择芯片
    • System Core -> SYS-> Debug: Serial Wire 防止下次无法烧录
    • System Core -> RCC-> High Speed Clock (HSE): Crystal/Ceramic Resonator 启用外接高速晶振
    • Clock Configuration: (配置为最高84MHz)选择外部晶振, 把HSE和PLLCLK连上, 在HCLK上输入84回车, 软件会自动调节各节点倍数
    • Timers -> TIM2
    • Clock Source: Internel Clock, 使用系统的时钟源
      • Channelx: PWM Generation CHx PWM输出
      • Counter Settings PWM频率 = 84MHz / (Perscaler + 1) / (Counter Period + 1)
        • Perscaler: 0
        • Counter Mode: Up
        • Counter Period: 256
        • Internal Clock Division(CKD): No Division
        • auto-reload preload: Enable - 如果启用, 在修改占空比时会等当前周期执行完再变化
      • Trigger Output
        • Master/Slave Mode (MSM bit): Disable
        • Trigger Event Selection: Reset (UG bit from TIMx_EGR)
    • PWM Generation Channel 1
      • Mode: PWM mode1
      • Pulse: 0
      • Output compare perload: Enable
      • Fast Mode: Disable
      • CH Polarity: High
    • PWM Generation Channel 2
      • ...

    PWM 配置, 体现在代码上的变化

    1. stm32f4xx_hal_conf.h 去掉了TIM的注释
    #define HAL_TIM_MODULE_ENABLED
    
    1. stm32f4xx_hal_msp.c 增加了初始化方法HAL_TIM_Base_MspInit(), HAL_TIM_MspPostInit(), HAL_TIM_Base_MspDeInit()
    void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)
    {
      if(htim_base->Instance==TIM2)
      {
      /* USER CODE BEGIN TIM2_MspInit 0 */
    
      /* USER CODE END TIM2_MspInit 0 */
        /* Peripheral clock enable */
        __HAL_RCC_TIM2_CLK_ENABLE();
      /* USER CODE BEGIN TIM2_MspInit 1 */
    
      /* USER CODE END TIM2_MspInit 1 */
      }
    
    }
    
    void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim)
    {
      GPIO_InitTypeDef GPIO_InitStruct = {0};
      if(htim->Instance==TIM2)
      {
      /* USER CODE BEGIN TIM2_MspPostInit 0 */
    
      /* USER CODE END TIM2_MspPostInit 0 */
    
        __HAL_RCC_GPIOA_CLK_ENABLE();
        __HAL_RCC_GPIOB_CLK_ENABLE();
        /**TIM2 GPIO Configuration
        PA15     ------> TIM2_CH1
        PB3     ------> TIM2_CH2
        */
        GPIO_InitStruct.Pin = GPIO_PIN_15;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
        GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
        GPIO_InitStruct.Pin = GPIO_PIN_3;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
        GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;
        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    
      /* USER CODE BEGIN TIM2_MspPostInit 1 */
    
      /* USER CODE END TIM2_MspPostInit 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==TIM2)
      {
      /* USER CODE BEGIN TIM2_MspDeInit 0 */
    
      /* USER CODE END TIM2_MspDeInit 0 */
        /* Peripheral clock disable */
        __HAL_RCC_TIM2_CLK_DISABLE();
      /* USER CODE BEGIN TIM2_MspDeInit 1 */
    
      /* USER CODE END TIM2_MspDeInit 1 */
      }
    
    }
    
    1. main.c 对TIM2增加初始化方法, TIM的初始化过程与其它外设是不一样的
      这里Prescaler=0, Period=255, 对应84MHz的SYSCLK, 输出的PWM频率为84MHz/256 = 32.8125KHz, 用于输出音频
    TIM_HandleTypeDef htim2;
    
    /**
      * @brief TIM2 Initialization Function
      * @param None
      * @retval None
      */
    static void MX_TIM2_Init(void)
    {
      TIM_ClockConfigTypeDef sClockSourceConfig = {0};
      TIM_MasterConfigTypeDef sMasterConfig = {0};
      TIM_OC_InitTypeDef sConfigOC = {0};
    
      htim2.Instance = TIM2;
      htim2.Init.Prescaler = 0;
      htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
      htim2.Init.Period = 255;
      htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
      htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
      if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
      {
        Error_Handler();
      }
      sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
      if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
      {
        Error_Handler();
      }
      if (HAL_TIM_PWM_Init(&htim2) != HAL_OK)
      {
        Error_Handler();
      }
      sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
      sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
      if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
      {
        Error_Handler();
      }
      sConfigOC.OCMode = TIM_OCMODE_PWM1;
      sConfigOC.Pulse = 0;
      sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
      sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
      if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
      {
        Error_Handler();
      }
      if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
      {
        Error_Handler();
      }
      /* USER CODE BEGIN TIM2_Init 2 */
    
      /* USER CODE END TIM2_Init 2 */
      HAL_TIM_MspPostInit(&htim2);
    
    }
    
    

    配置定时器

    通过TIMx配置

    • 勾选 Internal Clock
    • 配置下方参数
    • Counter Settings
      • Prescaler: 0
      • Counter Mode: Up
      • Counter Period: 1999 这里和Perscaler组合, 实现(0+1)(1999+1)个时钟的周期
      • Internal Clock Division (CKD): No division
      • auto-reload preload: Disable
    • Trigger Output (TRGO) Parameters
      • Master/Slave Mode (MSM bit): Disable
      • Trigger Envent Selection: Reset
    • NVIC Settings
      • TIM3 global interrupt: Enable

    对应代码变化

    stm32f4xx_hal_conf.h 启用TIM模块

    #define HAL_TIM_MODULE_ENABLED
    

    main.c 除了初始化方法, 还需要添加中断处理方法

    static void MX_TIM3_Init(void)
    {
      TIM_ClockConfigTypeDef sClockSourceConfig = {0};
      TIM_MasterConfigTypeDef sMasterConfig = {0};
      htim3.Instance = TIM3;
      htim3.Init.Prescaler = 0;
      htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
      htim3.Init.Period = 1999;
      htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
      htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
      if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
      {
        Error_Handler();
      }
      sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
      if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
      {
        Error_Handler();
      }
      sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
      sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
      if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
      {
        Error_Handler();
      }
    }
    
    void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    {
      //...
    }
    

    stm32f4xx_hal_msp.c 这里会一起处理其他的TIM实例

    void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)
    {
      if(htim_base->Instance==TIM2)
      {
        // ...
      }
      else if(htim_base->Instance==TIM3)
      {
        __HAL_RCC_TIM3_CLK_ENABLE();
        HAL_NVIC_SetPriority(TIM3_IRQn, 0, 0);
        HAL_NVIC_EnableIRQ(TIM3_IRQn);
      }
    
    }
    
    void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base)
    {
      if(htim_base->Instance==TIM2)
      {
        //...
      }
      else if(htim_base->Instance==TIM3)
      {
        __HAL_RCC_TIM3_CLK_DISABLE();
        HAL_NVIC_DisableIRQ(TIM3_IRQn);
      }
    
    }
    

    stm32f4xx_it.h 增加对应的定时中断处理

    void TIM3_IRQHandler(void);
    

    stm32f4xx_it.c

    /**
      * @brief This function handles TIM3 global interrupt.
      */
    void TIM3_IRQHandler(void)
    {
      HAL_TIM_IRQHandler(&htim3);
    }
    
  • 相关阅读:
    【Android】 分享一个完整的项目,适合新手!
    Android笔记:Fragment与ViewPager组合时,如何在FragmentActicity获取Fragment对象
    android 获取日期
    Java: 分解List<HashMap<String, String>>
    android ExpandableListView实现不同的布局
    android: activity切换之效果
    android: activity之间切换的抽屉效果
    android 获取适配的bitmap等相关
    Eclipse改变外观,护眼模式
    安装 NoMachine(NX) client and server
  • 原文地址:https://www.cnblogs.com/milton/p/15315792.html
Copyright © 2011-2022 走看看