一般情况下我们在控制指定数目PWM输出的时候,都是采用在对每一次的脉冲中断进行,虽然也能产生对硬件的PWM脉冲数目精确控制,但却是通过对每一次的脉冲都进行计数实现的,然而有的情况下我们用到PWM脉冲周期可能会达到us级甚至更低,这样的情况下,对于中断频繁计数脉冲这种状况,会非常的占用MCU的资源,甚至严重的情况下 可能会影响到程序的运行。下面介绍一种,无需对脉冲个数每个都进行计数而是产生指定脉冲个数后在中断中停止的方法。

同样,这种方法用到的是定时器的同步模式,可以通过中文参考手册找到。如下图

在这里用到的就是一个定时器作为另一个定时器的预分频器。

先说一下整体思路

程序用到的是定时器4和定时器3,定时器4作为主定时器,定时器3作为从定时器。(为了简单方便下面名字采用T4和T3)

T4的输出比较OC1产生PWM作为T3的脉冲时钟,同时T3不做分频处理,这样的话就可以直接对T4产生的脉冲数计数,我们先设置好T3的溢出个数,当T3的计数器数到指定的个数就会触发更新中断,然后在中断函数里对T4的OC1的比较值置0,即可停止计数。同时将T3的计数器设置成0,以备下一次计数。

以上便是过程分析,这种思路即可以达到us级甚至更低,而且不会对程序的主函数造成影响(如果T3预设的值比较小,而且时间太短且频繁的话也会有影响,但是考虑到一般情况下如果达到us级的脉冲个数一般都是一次计数几万或者几十万上百万的个数,当数完这些就得需要几十毫秒的时间,基本上对主函数程序没有影响)

下面列出定时器初始化过程和中断函数的简单处理

void PWM_Tim3Init(unsigned int pres,unsigned int period)
{TIM_TimeBaseInitTypeDef TIM_TimeBaseInitTypeStruct;NVIC_InitTypeDef NVIC_InitTypeStruct;TIM_OCInitTypeDef   TIM_OCInitTypeStruct;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);TIM_TimeBaseInitTypeStruct.TIM_Prescaler=pres;TIM_TimeBaseInitTypeStruct.TIM_CounterMode=TIM_CounterMode_Up;TIM_TimeBaseInitTypeStruct.TIM_Period=period;TIM_TimeBaseInitTypeStruct.TIM_ClockDivision=TIM_CKD_DIV1;TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitTypeStruct);TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);NVIC_InitTypeStruct.NVIC_IRQChannel=TIM3_IRQn;NVIC_InitTypeStruct.NVIC_IRQChannelPreemptionPriority=2;NVIC_InitTypeStruct.NVIC_IRQChannelSubPriority=2;NVIC_InitTypeStruct.NVIC_IRQChannelCmd=ENABLE;NVIC_Init(&NVIC_InitTypeStruct);TIM_SelectInputTrigger(TIM3,TIM_TS_ITR3);TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_External1);TIM_SelectMasterSlaveMode(TIM3,TIM_MasterSlaveMode_Enable);TIM3->CNT=0X00;TIM_Cmd(TIM3,ENABLE);}
void PWM_Tim4Init(unsigned int pres,unsigned int period)
{GPIO_InitTypeDef  GPIO_InitTypeStruct;TIM_TimeBaseInitTypeDef TIM_TimeBaseInitTypeStruct;TIM_OCInitTypeDef   TIM_OCInitTypeStruct;NVIC_InitTypeDef NVIC_InitTypeStruct;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);GPIO_InitTypeStruct.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7;GPIO_InitTypeStruct.GPIO_Mode=GPIO_Mode_AF_PP;GPIO_InitTypeStruct.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOB,&GPIO_InitTypeStruct);TIM_TimeBaseInitTypeStruct.TIM_Prescaler=pres;TIM_TimeBaseInitTypeStruct.TIM_CounterMode=TIM_CounterMode_Up;TIM_TimeBaseInitTypeStruct.TIM_Period=period;TIM_TimeBaseInitTypeStruct.TIM_ClockDivision=TIM_CKD_DIV1;TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitTypeStruct);TIM_OCInitTypeStruct.TIM_OCMode=TIM_OCMode_PWM1;TIM_OCInitTypeStruct.TIM_OutputState=TIM_OutputState_Enable;TIM_OCInitTypeStruct.TIM_Pulse=0;TIM_OCInitTypeStruct.TIM_OCPolarity=TIM_OCPolarity_High;TIM_OCInitTypeStruct.TIM_OCIdleState=TIM_OCIdleState_Set;TIM_OC1Init(TIM4,&TIM_OCInitTypeStruct);TIM_CtrlPWMOutputs(TIM4,ENABLE);TIM_SelectOutputTrigger(TIM4,TIM_TRGOSource_OC1Ref); TIM_SelectMasterSlaveMode(TIM4,TIM_MasterSlaveMode_Enable);}
void TIM3_IRQHandler(void)
{if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  {TIM_SetCompare1(TIM4,0); //定时器4停止产生PWM,这样定时器3的时钟就停止了。如果重新开始计数只需重新设置即可TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );}
}
#include "stm32f10x.h"
#include "time.h"
......
......
int main()
{NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);MotorPWM_Tim3Init(0,CountValue); PWM_Tim4Init(71,Value);SetPWMValue(TIM4,1,Value/2);TIM_Cmd(TIM4,ENABLE);while(1){}}

以上就是核心代码,不足之处还望留言建议,谢谢

STM32 精确控制PWM脉冲个数相关推荐

  1. 定时器主从模式实现PWM脉冲个数、占空比以及频率可调(250kHz以下)

    GPIO配置: void GPIO_config(void) {GPIO_InitTypeDef GPIO_InitStructure;RCC_APB1PeriphClockCmd( RCC_APB1 ...

  2. 40st-m00330 型伺服电机STM32单片机PWM脉冲控制

    项目需要控制丝杠在一定范围内来回移动,一个来回需要控制10s,丝杠由40st_m00330 型伺服电机(见图2)转动带动.实现控制分为两部分,第一部分是对伺服电机控制器的设置基础,如下图1所示:第二部 ...

  3. STM32定时器间的同步 主TIM1产生PWM 从TIM4精确控制TIM1 PWM脉冲数量

    STM32 定时器间的同步 主TIM1产生PWM 从TIM4精确控制TIM1 PWM脉冲数量 文章目录 STM32 定时器间的同步 主TIM1产生PWM 从TIM4精确控制TIM1 PWM脉冲数量 编 ...

  4. STM32的单脉冲模式实现精确个数脉冲

    我们在做嵌入式产品的开发过程中,有时需要输出指定数目的脉冲.实现它的方法较多,这里介绍一种利用 STM32定时器的单脉冲模式来实现的方法. STM32定时器的单脉冲输出功能,其实是定时器输出比较功能的 ...

  5. stm32PWM精确控制脉冲个数

    点击打开链接原出处   谢谢大家 一起学习 01 /**************************** 02 **TIM2的通道1使用单脉冲模式 03 **TIM3使用门控模式用来输出PWM 0 ...

  6. 一个极简单的基于STM32的精确PWM脉冲计数

    一个极简单的精确PWM脉冲计数 基于hal库,直接上代码. void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim) {if(pl ...

  7. 频率与周期的精密控制——用SPI输出PWM脉冲

    什么是PWM? PWM(Pulse Width Modulation)控制--脉冲宽度调制技术,通过对一系列脉冲的宽度进行调制,来等效地获得所需要波形(含形状和幅值).PWM在如今的应用十分广泛,电机 ...

  8. 精准控制PWM脉冲的频率和数量

    在一些项目中,我们经常要控制PWM脉冲的频率和数量,比如步进电机的控制等,下面分享一个程序是关于这方面的,程序的思想就是通过STM32的定时器来输出PWM波,并开启定时器中断,在中断里面计数脉冲的数量 ...

  9. STM32测量PWM波频率及占空比

    测量PWM波频率 PWM模式输入 基本原理 实验(PWM输入部分代码) 测量一段时间内脉冲个数求频率 PWM模式输入 该方式是在STM32输入捕获模式基础上扩展升级的功能,可以测量PWM波的频率及占空 ...

最新文章

  1. ORACLE 异常错误处理
  2. 梦幻手游最新服务器,梦幻西游手游12月18日新服务器开服公告
  3. 安装Rational Enterprise Suite(Robot...)时遇到的问题及解决办法!
  4. java发送文件_java 模拟http发送文件和参数
  5. mysql ignore 1 lines_MYSQL使用笔记(1)
  6. mybatisGenerator 代码自动生成报错 Result Maps collection already contains value for BaseResultMap...
  7. mysql修改失败,mysql修改数据失败(是我的代码有问题吗)怎么解决?
  8. 团队合作-需求分析之WBS
  9. Docker容器实现SSH连接
  10. VC知识库文档中心嵌入开发WinCE 里面不少写的很好的WinCE的文章
  11. Java并发编程实战 - 笔记
  12. IT之路,从迷茫“愤青”到团队项目经理,他是如何一步步走出来的?
  13. Vite 中 npm run dev 报错 Error: spawn vue3-test2\node_modules\esbuild\esbuild.exe ENOENT
  14. 4.0寸86盒显示屏调试(一)
  15. 软考常用计算公式及理解
  16. 由火车运煤问题想到的
  17. 巴菲特致股东的一封信:2002年
  18. python colorbar字体大小_如何更改colorbar上基数和指数的字体大小?
  19. java中计算一段时间内白天的时间和夜晚的时间
  20. windows改键软件——sharpkeys

热门文章

  1. 主题:分享一个靠谱的免费论文查重网站
  2. Linux九阴真经之无影剑残卷7(进程管理)
  3. Github博客+腾讯云域名的快捷绑定方案
  4. Solaris系统配置IPMP (基于IP寻址与链路)
  5. AC自动机原理及代码实现
  6. 普通青年VS文艺青年VS2B青年,爆笑语录!
  7. 6.5 自定义报表方案
  8. Vim 利剑常磨,见血封喉
  9. 10进制转换16进制C代码实现
  10. 计算机应用基础模块5 acess形考答案,2018年3月计算机二级考试Access综合试题五