基于HAL库的STM32单定时器多路输入捕获测量PWM的频率和占空比实现(状态机方式实现)

这篇具有很好参考价值的文章主要介绍了基于HAL库的STM32单定时器多路输入捕获测量PWM的频率和占空比实现(状态机方式实现)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

 写在前面

先回顾下定时器的单路捕获PWM

多路捕获PWM的频率和占空比(状态机实现)

我的思路:

状态图

配置

给出示例代码

测试效果


 写在前面

        先有了这篇文章实现了单定时器的多通道测量频率,以外部时钟的方式可测量任意频率的方波),奈何不能多路测试PWM波的频率,于是有了本文。

基于HAL库的STM32的单定时器的多路输入捕获测量脉冲频率(外部时钟实现)_昊月光华的博客-CSDN博客

先回顾下定时器的单路捕获PWM

对于定时器的单路捕获PWM的频率和脉冲,用cubemx配置:一个通道捕获上升沿,另一个通道捕获下降沿,Slave Mode 为Reset Mode .触发源为 TL1FP1  这可以很好地测量输入信号的周期和高电平时间,是使用定时器输入捕获的常用模式。(但仅限于定时器捕获单路PWM波)

在这种模式下:

1.上升沿到来时,触发中断,保存计数值到CCR1(假设通道1捕获上升沿的计数值),然后定时器的计数值清0(TIMx->CNT = 0)(这一点是关键)

2.下降沿到来时,保存计数值到CCR2(假设通道2捕获下降沿的计数值),定时器的计数值不会清0.

hal 输入捕获,stm32,单片机,嵌入式硬件

PWM一个周期下映射到定时器的计数值 = 上升沿的计数值.(CCRx)

PWM的频率   =  定时器的频率(1M) / (捕获上升沿的计数值 -0)

PWM的占空比 = (下降沿的计数值 / 上升沿的计数值)

配置(以通道1上升沿直接捕获,通道2下降沿间接捕获)

hal 输入捕获,stm32,单片机,嵌入式硬件

给出以上的实例代码

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
    
    static u16 t = 0;
    static u16 d = 0;
    if(htim->Instance == TIM2)
    {
        if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
        {
            LEDDT[0]=1;
            t = HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1)+1;
            freq = 1000000 / t;
            duty = (float)d/t*100;
            
        }
        
        else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
        {
              LEDDT[1]=2;
            d =  HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_2)+1;
        }
        
        
    }
}

多路捕获PWM的频率和占空比(状态机实现)

我的思路:

  配置定时器的两个通道都为上升沿捕获,开启定时器对于通道的输入捕获中断。

状态图

hal 输入捕获,stm32,单片机,嵌入式硬件

需要注意定时器的计数值有可能会溢出,所以要记录下溢出次数(在定时器的溢出更新中断中记录)

 PWM频率=  定时器频率/  两个上升沿之间的计数值

定时器频率 = 系统时钟 /预分频系数 = 1M

两个上升沿之间的计数值 = 第二次上升沿的计数值 +( 溢出次数 x 重装载值)- 第一次上升沿的计数值.

PWM占空比 =  有效计数值 / 两个上升沿的计数值

有效计数值(假设以高电平为有效电平) = 下降沿的计数值 + ( 溢出次数 x 重装载值)-上升沿的计数值

配置

设置定时器的两个通道(多通道)为上升沿捕获计数值,这意味着每次PWM波在上升沿都会进入中断,保留计数值到CCRx.

用cubemx配置的话,就是很简单的配置方式,系统时钟80m,预分配系数80-1, 定时器频率为1M,预装载为0xffff(65535)

hal 输入捕获,stm32,单片机,嵌入式硬件

给出示例代码

TIM3的通道1和通道2

数据类型:

typedef struct mypwm{
    
    u32 firstrisingcnt;
    u32 secondrisingcnt;
    u32 fallingcnt;
    u32 validcnt; //有效计数值对应于脉宽
    float freq;
    float duty;
    u16 updatetimes;
    u8 state;
    
    
    
} pwms;

在溢出更新中断的回调函数中:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{


  if(htim->Instance == TIM3)
    {
        
       mpwms[0].updatetimes++;
       mpwms[1].updatetimes++;
         //两路的更新计数值自加1,这里实际上可以用一个代替
        
        
    }
}

输入捕获的中断回调函数


void Inputcapturehandle(pwms * cpwm,u32 cnt,TIM_HandleTypeDef *htim,u32 ch)
{
    
     u32 temp = 0;
     switch(cpwm->state)
    {   
        case 0:     //测量上升沿
        {    
                //开启下次为下降沿采样
                __HAL_TIM_SET_CAPTUREPOLARITY(htim, ch, TIM_INPUTCHANNELPOLARITY_FALLING); 
                //溢出计数值置为0
                cpwm->updatetimes = 0;
               //捕获第一次计数值
                cpwm->firstrisingcnt =cnt;
                //更新状态
                cpwm->state = 1;
             
                break;
        }
         
        case 1:    //测量下降沿
        {
            //开启下一次为上升沿采样
         __HAL_TIM_SET_CAPTUREPOLARITY(htim, ch, TIM_INPUTCHANNELPOLARITY_RISING);      
         //捕获下降沿的计数值
        cpwm->fallingcnt = cnt;
         //计算有效计数值(考虑溢出)
        cpwm->validcnt =  (cpwm->updatetimes * htim->Instance->ARR)+ cpwm->fallingcnt-cpwm->firstrisingcnt;    
         //溢出计数置为0
        cpwm->updatetimes  =0;  
         //更新下一状态
        cpwm->state = 2;       
                break;     
            
         }
               
     
        case 2:  //再次测量上升沿
            {
                //捕获第二次上升沿的计数值
                cpwm->secondrisingcnt = cnt;
                //计算两个上升沿之间的计数值(考虑溢出)
                temp =  cpwm->secondrisingcnt + (cpwm->updatetimes * htim->Instance->ARR) - cpwm->firstrisingcnt;
                //溢出计数值置为0
                cpwm->updatetimes = 0;
                //计算频率 = 定时器频率/一个PWM波的两个上升沿的计数值
                cpwm->freq = 1e6/temp;
                //计算占空比
                cpwm->duty = cpwm->validcnt*1.0f / temp *100;
                //更新状态
                cpwm->state = 0;
                
                    
            }   
            break;  
            
        
    }
               
}


void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
    
   
 
     if(htim->Instance ==  TIM3)
    {
        if(htim->Channel ==  HAL_TIM_ACTIVE_CHANNEL_1)
        {
            
            //进入到自己的中断回调函数中执行
            Inputcapturehandle(&mpwms[0],TIM3->CCR1,htim,TIM_CHANNEL_1);

            
        }
        else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
        {
                 //进入到自己的中断回调函数中执行
           Inputcapturehandle(&mpwms[1],TIM3->CCR2,htim,TIM_CHANNEL_2);
        }
            
            
    }
        
        
}

测试效果

通过电位器控制输出PWM波的频率和占空比:输出格式为 频率 -占空比

hal 输入捕获,stm32,单片机,嵌入式硬件文章来源地址https://www.toymoban.com/news/detail-529908.html

到了这里,关于基于HAL库的STM32单定时器多路输入捕获测量PWM的频率和占空比实现(状态机方式实现)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于STM32的定时器--定时中断(HAL库)

    本文旨在介绍如何使用STM32CubeMX配置+KEIL 5开发一个每10us定时器中断触发一次的项目。帮助初学者入门STM32的定时器使用。 定时器是STM32微控制器中非常重要的功能模块之一,用于计时、生成精确的时间延迟、触发事件等。STM32微控制器通常具有多个定时器模块,包括通用定时

    2024年02月14日
    浏览(58)
  • STM32 HAL库 通用定时器介绍及相关应用例程 定时器中断 输出PWM (点亮LED呼吸灯、输出PWM、输入捕获) CubeMX

    (部分图引自于ATK) 前情提要(基本定时器) 点此进入 通用定时器类别 通用定时器和基本定时器相比大致的工作方式是相似的,不过通用定时器比基本定时器多了一些很好用的功能,比如: 外部输入捕获 输出比较 输出PWM 时钟源 CubeMX为我们提供了配置时钟的非常方便的工

    2024年04月15日
    浏览(85)
  • 手把手教你开发stm32——定时器(上)(基于hal库)

    定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断。 16位计数器、预分频器、自动重装载寄存器的时基单元。 不仅具备基本的定时中断功能,而且还包含内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等多种功能。 根据复杂度和引用

    2024年02月03日
    浏览(49)
  • HAL STM32基于系统滴答定时器(SysTick)实现多任务时间片轮询

    📑RTOS(实时操作系统)和定时器时间片轮询是两种不同的任务调度和执行方式的差异简介 🔖 以下部分内容,由AI给出的解答: 🔖RTOS(实时操作系统): 🌿RTOS是一种专门设计用于实时系统的操作系统,它可以有效地管理多个任务,提供任务调度、同步和通信等功能。 🌿

    2024年02月21日
    浏览(47)
  • 基于STM32CubeIDE HAL库利用基本定时器实现串口接收不定长数据

    ✨申明:本文章仅发表在 CSDN 网站,任何其他网见此内容均为盗链和爬取,请多多尊重和支持原创! 🍁对于文中所提供的相关资源链接将作不定期更换。 📌相关参考《HAL库教程9:串口接收不定长数据》 🎉对于串口接收不定长数据的处理方案网上有很多,个人觉得采用定时

    2024年02月09日
    浏览(55)
  • 基于CubeMX(hal库)stm32中hrtim高分辨率定时器的基本使用(自存)

    1、选通道 单通道输出or双通道输出 2、Timer A~F配置 (Master Timer不用管) 比较值Compare 个人感觉跟CCR差不多的意思, 注意不要大于上面的Period就行 设置上升沿和下降沿时间: 若想让上设Compare=CCR 如图设置 即可 即在 计数到Compare1时拉低,计数溢出时拉高 所以上图输出频率10kHz占

    2024年02月04日
    浏览(56)
  • 2.基于正点原子STM32F103的定时器中断实验(HAL库实现)(cubeMX)

      基本上每一款MCU都会配备定时器这个外设,STM32 的每个通用定时器都是完全独立的,没有互相共享的任何资源。 同样,STM32F1系列的定时器功能也很强大,包括: TIM1和TIM8两个高级定时器; TIM2~TIM5是个通用寄存器; TIM7,TIM8,两个基本定时器。 由于本次实验适用于新手入门

    2023年04月26日
    浏览(161)
  • STM32控制步进电机:基于HAL库定时器中断的闭环步进电机驱动+精准控制脉冲数

    该篇文章中用到的步进电机闭环驱动器为Emm42_V4.0步进电机闭环驱动器。该闭环驱动器自带FOC矢量闭环控制算法,能实现力矩、速度、位置三环控制。 如下图所示,该42步进闭环电机驱动器的A+、A-、B+、B-连接步进电机,通过右侧的使能、脉冲、方向端对步进电机进行驱动控制

    2024年02月01日
    浏览(56)
  • STM32 HAL库-定时器中断

    关闭或开启所有中断;代码如下: STM32F407 有众多的定时器,其中包括 2 个基本定时器(TIM6 和 TIM7)、10 个通用定时 器(TIM2 ~ TIM5、TIM9 ~TIM14)、2 个高级控制定时器(TIM1 和 TIM8),这些定时器彼此完 全独立,不共享任何资源。 选择定时器,配置时钟源,设置预分频系数,计

    2024年01月25日
    浏览(65)
  • stm32——hal库学习笔记(定时器)

    使用纯软件(CPU死等)的方式实现定时(延时)功能 使用精准的时基,通过硬件的方式,实现定时功能 递增计数模式实例说明 中心对齐模式实例说明 TIM6 和TIM7 控制寄存器 1(TIMx_CR1) TIM6 和TIM7 DMA/中断使能寄存器(TIMx_DIER) TIM6 和TIM7 状态寄存器(TIMx_SR) TIM6 和TIM7 计数器(TIMx_CNT)

    2024年02月21日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包