历史上的今天
返回首页

历史上的今天

今天是:2024年10月28日(星期一)

正在发生

2021年10月28日 | stm32专题二十六:测量PWM 频率 + 占空比

2021-10-28 来源:eefocus

实验的基本原理:


利用通用定时器产生4路占空比不同的PWM波形(频率100k,占空比0.5 0.4 0.3 0.2);

利用高级定时器的PWM输入模式来测量PWM参数;

有几个值得注意的地方:


捕获寄存器CCR1和CCR2的值在计算占空比和频率的时候必须加1;

计数周期不能设置的太小,如果我们设置的计数周期 < PWM周期,那么就无法捕获PWM脉冲,一般驱动电机的PWM是10k ~ 25kHz,当设置的周期为1ms,对应频率为1kHz,那么就可以捕获1kHz以上的PWM 信号;

下面是测量pwm的代码:


bsp_AdvanceTim.c


#include "bsp_AdvanceTim.h" 

 

static void ADVANCE_TIM_NVIC_Config(void)

{

    NVIC_InitTypeDef NVIC_InitStructure; 

    // 设置中断组为0

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

// 设置中断来源

    NVIC_InitStructure.NVIC_IRQChannel = ADVANCE_TIM_IRQ;

// 设置抢占优先级

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  

  // 设置子优先级

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);

}

 

static void ADVANCE_TIM_GPIO_Config(void) 

{

   GPIO_InitTypeDef GPIO_InitStructure;

 

RCC_APB2PeriphClockCmd(ADVANCE_TIM_CH1_GPIO_CLK, ENABLE);

  GPIO_InitStructure.GPIO_Pin =  ADVANCE_TIM_CH1_PIN;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  

  GPIO_Init(ADVANCE_TIM_CH1_PORT, &GPIO_InitStructure);

}

 

static void ADVANCE_TIM_Mode_Config(void)

{

  // 开启定时器时钟,即内部时钟CK_INT=72M

ADVANCE_TIM_APBxClock_FUN(ADVANCE_TIM_CLK,ENABLE);

 

/*--------------------时基结构体初始化-------------------------*/

TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

// 自动重装载寄存器的值,累计TIM_Period+1个频率后产生一个更新或者中断

TIM_TimeBaseStructure.TIM_Period=ADVANCE_TIM_PERIOD;

// 驱动CNT计数器的时钟 = Fck_int/(psc+1)

TIM_TimeBaseStructure.TIM_Prescaler= ADVANCE_TIM_PSC;

// 时钟分频因子 ,配置死区时间时需要用到

TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;

// 计数器计数模式,设置为向上计数

TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;

// 重复计数器的值,没用到不用管

TIM_TimeBaseStructure.TIM_RepetitionCounter=0;

// 初始化定时器

TIM_TimeBaseInit(ADVANCE_TIM, &TIM_TimeBaseStructure);

 

/*--------------------输入捕获结构体初始化-------------------*/

  // 使用PWM输入模式时,需要占用两个捕获寄存器,一个测周期,另外一个测占空比

TIM_ICInitTypeDef  TIM_ICInitStructure;

// 捕获通道IC1配置

// 选择捕获通道

  TIM_ICInitStructure.TIM_Channel = ADVANCE_TIM_IC1PWM_CHANNEL;

// 设置捕获的边沿

  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;

// 设置捕获通道的信号来自于哪个输入通道,有直连和非直连两种

  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;

// 1分频,即捕获信号的每个有效边沿都捕获

  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;

// 不滤波

  TIM_ICInitStructure.TIM_ICFilter = 0x0;

// 初始化PWM输入模式

  TIM_PWMIConfig(ADVANCE_TIM, &TIM_ICInitStructure);

// 当工作做PWM输入模式时,只需要设置触发信号的那一路即可(用于测量周期)

// 另外一路(用于测量占空比)会由硬件自带设置,不需要再配置

// 捕获通道IC2配置

// TIM_ICInitStructure.TIM_Channel = ADVANCE_TIM_IC1PWM_CHANNEL;

//  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;

//  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_IndirectTI;

//  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;

//  TIM_ICInitStructure.TIM_ICFilter = 0x0;

//  TIM_PWMIConfig(ADVANCE_TIM, &TIM_ICInitStructure);

// 选择输入捕获的触发信号,触发的那一路信号对应的就是周期

  TIM_SelectInputTrigger(ADVANCE_TIM, TIM_TS_TI1FP1);

 

// 选择从模式: 复位模式

// PWM输入模式时,从模式必须工作在复位模式,当捕获开始时,计数器CNT会被复位

  TIM_SelectSlaveMode(ADVANCE_TIM, TIM_SlaveMode_Reset);

  TIM_SelectMasterSlaveMode(ADVANCE_TIM,TIM_MasterSlaveMode_Enable); 

 

  // 使能捕获中断,这个中断针对的是主捕获通道(测量周期那个)

  TIM_ITConfig(ADVANCE_TIM, TIM_IT_CC1, ENABLE);

// 清除中断标志位

TIM_ClearITPendingBit(ADVANCE_TIM, TIM_IT_CC1);

// 使能高级控制定时器,计数器开始计数

  TIM_Cmd(ADVANCE_TIM, ENABLE);

}

 

void ADVANCE_TIM_Init(void)

{

ADVANCE_TIM_NVIC_Config();

ADVANCE_TIM_GPIO_Config();

ADVANCE_TIM_Mode_Config();

}

 

/*********************************************END OF FILE**********************/

bsp_AdvanceTim.h


#ifndef __BSP_ADVANCETIM_H

#define __BSP_ADVANCETIM_H

 

 

#include "stm32f10x.h"

 

/************高级定时器TIM参数定义,只限TIM1和TIM8************/

// 当使用不同的定时器的时候,对应的GPIO是不一样的,这点要注意

// 这里我们使用高级控制定时器TIM1

 

#define            ADVANCE_TIM                   TIM1

#define            ADVANCE_TIM_APBxClock_FUN     RCC_APB2PeriphClockCmd

#define            ADVANCE_TIM_CLK               RCC_APB2Periph_TIM1

 

// 输入捕获能捕获到的最小的频率为 72M/{ (ARR+1)*(PSC+1) }

/* 注意,这里的计数周期不能设置的太小,如果我们设置的计数周期 < PWM周期

那么就无法捕获PWM脉冲,一般驱动电机的PWM是10k ~ 25kHz,我们设置的

周期为1ms,对应频率为1kHz,那么就可以捕获1kHz以上的PWM 信号*/

#define            ADVANCE_TIM_PERIOD            (1000-1)

#define            ADVANCE_TIM_PSC               (72-1)

 

// 中断相关宏定义

#define            ADVANCE_TIM_IRQ               TIM1_CC_IRQn

#define            ADVANCE_TIM_IRQHandler        TIM1_CC_IRQHandler

 

// TIM1 输入捕获通道1

#define            ADVANCE_TIM_CH1_GPIO_CLK      RCC_APB2Periph_GPIOA

#define            ADVANCE_TIM_CH1_PORT          GPIOA

#define            ADVANCE_TIM_CH1_PIN           GPIO_Pin_8

 

#define            ADVANCE_TIM_IC1PWM_CHANNEL    TIM_Channel_1

#define            ADVANCE_TIM_IC2PWM_CHANNEL    TIM_Channel_2

 

 

/**************************函数声明********************************/

 

void ADVANCE_TIM_Init(void);

 

 

#endif /* __BSP_ADVANCETIM_H */

然后在中断服务函数中读取CCR1 和 CCR2寄存器的值,并计算 频率 和 占空比。


__IO uint16_t IC2Value = 0;

__IO uint16_t IC1Value = 0;

__IO float DutyCycle = 0;

__IO float Frequency = 0;

/*

 * 如果是第一个上升沿中断,计数器会被复位,锁存到CCR1寄存器的值是0,CCR2寄存器的值也是0

 * 无法计算频率和占空比。当第二次上升沿到来的时候,CCR1和CCR2捕获到的才是有效的值。其中

 * CCR1对应的是周期,CCR2对应的是占空比。

 */

void ADVANCE_TIM_IRQHandler(void)

{

  /* 清除中断标志位 */

  TIM_ClearITPendingBit(ADVANCE_TIM, TIM_IT_CC1);

 

  /* 获取输入捕获值 */

  IC1Value = TIM_GetCapture1(ADVANCE_TIM);

  IC2Value = TIM_GetCapture2(ADVANCE_TIM);

  // 注意:捕获寄存器CCR1和CCR2的值在计算占空比和频率的时候必须加1

if (IC1Value != 0)

  {

    /* 占空比计算 */

    DutyCycle = (float)((IC2Value+1) * 100) / (IC1Value + 1);

 

    /* 频率计算 */

    Frequency = (72000000/(ADVANCE_TIM_PSC+1))/(float)(IC1Value + 1);

printf("占空比:%0.2f%%   频率:%0.2fHzn",DutyCycle,Frequency);

  }

  else

  {

    DutyCycle = 0;

    Frequency = 0;

  }

}


实际测试效果如下:

推荐阅读

史海拾趣

Gumstix公司的发展小趣事
检查电路中是否有异物导致短路,清理异物并修复受损部分。
CMOSIS公司的发展小趣事

近年来,随着人工智能、物联网等技术的快速发展,CMOS图像传感器行业也面临着深刻的变革。CMOSIS公司敏锐地把握住了这一趋势,积极调整战略方向,加大了在人工智能算法、低功耗设计等方面的研发投入。通过不断创新和优化产品,公司成功应对了行业变革带来的挑战,保持了稳健的发展态势。

Avery Dennison公司的发展小趣事

Avery Dennison与众多知名企业建立了紧密的合作关系,共同推动行业发展。例如,公司与利郎服饰的合作就是一个典型的例子。通过提供Embelex™系列装饰标、厂内打印解决方案、RFID解决方案以及3D标签打样数字化解决方案等,Avery Dennison助力利郎实现了数字化转型和业务扩张。这种合作模式不仅提升了双方的市场地位,也为整个服装行业带来了创新动力。

DDK公司的发展小趣事

DDK公司在发展过程中,始终牢记社会责任,积极履行企业公民的义务。公司积极参与公益事业,关注环境保护和社会发展,为社会做出了积极贡献。同时,DDK公司还积极推动行业健康发展,与同行企业共同维护市场秩序和公平竞争环境。这种社会责任的担当,让DDK公司在电子行业中树立了良好的企业形象。

Datapro International Inc公司的发展小趣事

随着技术的不断进步和市场的不断扩大,Datapro International Inc公司开始寻求新的市场机会。他们发现,随着企业信息化程度的提高,对数据存储和处理的需求也越来越大。于是,公司决定进军企业市场,并开发了一系列针对企业的数据存储解决方案。

在拓展企业市场的过程中,Datapro International Inc公司面临着来自竞争对手的激烈竞争。然而,他们凭借卓越的产品质量、专业的技术服务和灵活的商业模式,成功赢得了客户的信任和支持。随着企业市场的不断拓展,Datapro International Inc公司的业务规模也逐渐扩大。

CWIND公司的发展小趣事

随着全球对环保和可持续发展的重视程度不断提高,CWIND公司积极响应这一趋势,将绿色环保理念融入到产品研发和生产过程中。公司投入大量资金和资源,研发出了一系列符合环保标准的电子产品,并优化了生产工艺,减少了废弃物和污染物的排放。这一举措不仅提升了CWIND的品牌形象,还为公司赢得了更多的市场份额。

问答坊 | AI 解惑

电动车窗的硬件和软件设计

以前曾用机械方法控制的车门系统现在逐渐改成电子控制,越来越多的低端汽车也开始采用电子控制的车门控制系统,利用can或者lin总线通信技术实现四个车门之间的通信。车窗防夹功能是车门控制系统的难点之一。门控系统具有多种故障诊断能力,能够及时 ...…

查看全部问答>

关于benq m23g 的AT命令出错的问题,急!

怎么我的AT指令出现这样的问题: AT+CGDCONT=1, \"IP \", \"cmnet \" OK AT%CGPCO=1, \"PAP,, \",1 OK AT$NOSLEEP=1 OK AT$DESTINFO= \"10.2.1.1\",2,200 EXT: I ERROR 就是这个指令AT$DESTINFO= \"10.2.1.1\",2,200老出错 ...…

查看全部问答>

请推荐STM32型号:作一个CAN节点,十几个按键+十几个LDE驱动

                                 如题,最便宜的型号是那款?市场上可以买到吗?ST有CAN的开发资料吗?谢谢!…

查看全部问答>

菜鸟求教关于STM32GPIO端口寄存器问题

                                 gpio寄存器中对BSRR,BRR进行置0或1操作后,为什么ODR没有相应的改变值呢?…

查看全部问答>

谁知道怎么解决这些警告??、

WARNING:Xst:2211 - \"D:/example/scan/dds.vhd\" line 58: Instantiating black box module <sin>.WARNING:Xst:2734 - Property \"use_dsp48\" is not applicable for this technology.WARNING:Xst:2734 - Property \"use_dsp48\" is not appl ...…

查看全部问答>

新年快乐!

祝各位在新的一年里龙马精神!龙腾虎跃!…

查看全部问答>

编译TI例程是弹出警告

编译TI例程是弹出警告warning: entry-point symbol other than \"_c_int00\" specified:  \"code_start\"。这是什么一种情况啊。…

查看全部问答>

MSP-EXP430F5529的102*64液晶

想用MSP-EXP430F5529的102*64的液晶屏显示,但没用过,不知有没有大神能够指导一下这个的用法。…

查看全部问答>

关于PCB投板制板费用问题咨询,新手。

以前画的PCB都是用感光法做出来的,单面板,要么直接用洞洞板焊。最近画了块双面板,想投板,不知道现在的行情如何,亲们平时都在哪投板来着,价格一般是多少,最低价一般是多少,以前听说在一家投板,第一次投板会收取入门费,连制板什么的总共要 ...…

查看全部问答>

苦逼的找工作终于结束了

最近几个礼拜在找工作,也面试了好多家,感触多多。现在该小结下了。1:首先实力牛逼,未必就能找到一份好工作,这个和机遇有关。2:找工作,如果是实习生还是不要高调,最好中调。太高调了,未必能找到一份工作,即使你做了很多项目,再说公司也未 ...…

查看全部问答>