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