STM32輸出比較模式


STM32輸出比較模式

搜索好久,各種文章良莠不齊,轉載以下幾篇

http://www.eeworld.com.cn/mcu/article_2016101130334.html(輸出比較凍結模式)

http://www.eeworld.com.cn/mcu/article_2016101130330.html(輸出比翻轉模式)

http://www.eeworld.com.cn/mcu/article_2016101130334.html(輸出比較主動模式)

http://www.dqzdhw.com/danpianji/1138.html(輸出比較非主動模式)

 

 

就為了這個東西,搞了幾個小時,故余雖愚,卒獲有所聞。

 

再附上一篇大佬的神作:

http://blog.sina.com.cn/s/blog_3ba262a10101esd1.html

轉自:https://www.cnblogs.com/sanshijvshi/p/10317574.html

HAL庫代碼我來補充:如下 

pwm.c文件

/* 
*TIM3 init function 
* 定時器初始化
* 該定時器的 時鍾頻率源 為 72MHZ
* 預分頻設置為 0  則  計數時鍾頻率為  72MHZ/(PSC+1)  =1mhz
* 計數一次的時間 是      1/1000000=    1 us
*/
void MX_TIM3_Init(void)
{
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};    //時鍾配置結構體          變量
  TIM_MasterConfigTypeDef sMasterConfig = {0};        //定時器主配置結構               變量  
  TIM_OC_InitTypeDef sConfigOC = {0};               //輸出比較結構體              變量

  htim3.Instance = TIM3;                             //操作的是定時器3
  htim3.Init.Prescaler = 71;                          //這樣計數一次的時間就是  1個  us
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;      //向上計數
  htim3.Init.Period = 65535;                        //自動重裝載設置值
  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();
  }
  if (HAL_TIM_OC_Init(&htim3) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }

  
  //sConfigOC.OCMode = TIM_OCMODE_TOGGLE;    //輸出比較      輸出翻轉
  sConfigOC.OCMode=TIM_OCMODE_TIMING;        //因項目用到的功能是任意一個引腳,便可輸出方波所以啟用此模式
  sConfigOC.Pulse = CCR1_Val;                        //比較的脈沖值   這樣一配置完  運行后就進入中斷程序
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;  //最初默認為  高電平
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;   //  此參數 在輸出比較下無效
  if (HAL_TIM_OC_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)   //以此參數初始化通道1
  {
    Error_Handler();
  }
   sConfigOC.Pulse = CCR2_Val;  
  if (HAL_TIM_OC_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2) != HAL_OK) //以此參數初始化通道2 
  {
    Error_Handler();
  }
    sConfigOC.Pulse = CCR3_Val;  
  if (HAL_TIM_OC_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_3) != HAL_OK) //以此參數初始化通道3 
  {
    Error_Handler();
  }
    sConfigOC.Pulse = CCR4_Val;  
  if (HAL_TIM_OC_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)//以此參數初始化通道4
  {
    Error_Handler();
  }
  HAL_TIM_MspPostInit(&htim3);     //執行4個通道的 GPIO功能的初始化

  HAL_TIM_OC_Start_IT(&htim3,TIM_CHANNEL_1);  //開啟定時器  開啟中斷
  HAL_TIM_OC_Start_IT(&htim3,TIM_CHANNEL_2);
  HAL_TIM_OC_Start_IT(&htim3,TIM_CHANNEL_3);
  HAL_TIM_OC_Start_IT(&htim3,TIM_CHANNEL_4);

}

void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
{

  if(tim_baseHandle->Instance==TIM3)
  {
  /* USER CODE BEGIN TIM3_MspInit 0 */

  /* USER CODE END TIM3_MspInit 0 */
    /* TIM3 clock enable */
    __HAL_RCC_TIM3_CLK_ENABLE();   //  使能  定時器 3 的時鍾

    /* TIM3 interrupt Init */
    HAL_NVIC_SetPriority(TIM3_IRQn, 1, 2); //設置中斷優先級
    HAL_NVIC_EnableIRQ(TIM3_IRQn);         //使能定時器3 的全局中斷
  /* USER CODE BEGIN TIM3_MspInit 1 */

  /* USER CODE END TIM3_MspInit 1 */
  }
}
void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(timHandle->Instance==TIM3)
  {
  /* USER CODE BEGIN TIM3_MspPostInit 0 */

  /* USER CODE END TIM3_MspPostInit 0 */

    __HAL_RCC_GPIOA_CLK_ENABLE();   //  使能  GPIOA   端口的時鍾

    /**TIM3 GPIO Configuration
    PA6     ------> TIM3_CH1
    PA7     ------> TIM3_CH2
    PB0     ------> TIM3_CH3
    PB1     ------> TIM3_CH4
    */

#if 0   //用到輸出翻轉時用到 
    __HAL_RCC_GPIOB_CLK_ENABLE();  //使能 GPIOB   端口的時鍾
    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;    //開啟復用功能
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;  //處於高速的狀態
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
    GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
#endif
    GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;    //開啟復用功能
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;  //處於高速的狀態
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);


  /* USER CODE BEGIN TIM3_MspPostInit 1 */

  /* USER CODE END TIM3_MspPostInit 1 */
  }

}

void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle)
{

  if(tim_baseHandle->Instance==TIM3)
  {
  /* USER CODE BEGIN TIM3_MspDeInit 0 */

  /* USER CODE END TIM3_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_TIM3_CLK_DISABLE();    //關閉時鍾

    /* TIM3 interrupt Deinit */ 
    HAL_NVIC_DisableIRQ(TIM3_IRQn); //關閉中斷
  /* USER CODE BEGIN TIM3_MspDeInit 1 */

  /* USER CODE END TIM3_MspDeInit 1 */
  }
}

     
//重寫中斷回調函數
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{
    static u16 capture1 = 0;
    static u16 capture2 = 0;
    static u16 capture3 = 0;
    static u16 capture4 = 0;


     if(htim==(&htim3))
     {
        if(__HAL_TIM_GET_IT_SOURCE(&htim3,TIM_IT_CC1))
        {
            //得到通道1當前的計數值
            capture1=__HAL_TIM_GET_COMPARE(&htim3,TIM_CHANNEL_1);
            __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,capture1+CCR1_Val);
            MIDA=~MIDA;
            __HAL_TIM_CLEAR_IT(&htim3,TIM_IT_CC1);
        }

        if(__HAL_TIM_GET_IT_SOURCE(&htim3,TIM_IT_CC2))
        {
            //得到通道1當前的計數值
            capture2=__HAL_TIM_GET_COMPARE(&htim3,TIM_CHANNEL_2);
            __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_2,capture2+CCR2_Val);
            MIDB=~MIDB;
            __HAL_TIM_CLEAR_IT(&htim3,TIM_IT_CC2);
        }
        
        if(__HAL_TIM_GET_IT_SOURCE(&htim3,TIM_IT_CC3))
        {
            //得到通道1當前的計數值
            capture3=__HAL_TIM_GET_COMPARE(&htim3,TIM_CHANNEL_3);
            __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_3,capture3+CCR3_Val);
            MIDC=~MIDC;
            __HAL_TIM_CLEAR_IT(&htim3,TIM_IT_CC3);
        }
        
        if(__HAL_TIM_GET_IT_SOURCE(&htim3,TIM_IT_CC4))
        {
            //得到通道1當前的計數值
            capture4=__HAL_TIM_GET_COMPARE(&htim3,TIM_CHANNEL_4);
            __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_4,capture4+CCR4_Val);
            MIDD=~MIDD;
            __HAL_TIM_CLEAR_IT(&htim3,TIM_IT_CC4);
        }

     }

}

PWM.H文件如下:

#define  KHZ2  250
#define  KHZ3  167
#define  KHZ4  125
#define  KHZ5  100
#define  KHZ10 50

PWM_EXT __IO uint16_t CCR1_Val ;
PWM_EXT __IO uint16_t CCR2_Val ;
PWM_EXT __IO uint16_t CCR3_Val ;
PWM_EXT __IO uint16_t CCR4_Val ;

#define  MIDA PAout(4)
#define  MIDB PAout(5)
#define  MIDC PAout(6)
#define  MIDD PAout(7)


PWM_EXT TIM_HandleTypeDef htim3;      /*定時器句柄*/ 
 	
PWM_EXT void MX_TIM3_Init(void);

PWM_EXT void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM