简介

使用STM32中TIMER的输入捕获功能可以测量PWM方波的频率和占空比。测量通常有两种方法:中断法和DMA传输法。根据我的经验,中断法最多能测量到150KHz的方波,而DMA方法最多可达1MHz(注:在这种极限状态下,信号占空比太大也容易测量失败)。下面就分别介绍这两种方法。

1. 使用STM32CubeMX生成代码

首先是选用TIMER,TIMER必须要选用两个相邻通道,并且一个是Input Capture Direct Mode,另一个是Input Capture Indirect Mode。在这种模式下,STM32将两个通道同时连接到同一个外部GPIO端口上。然后将TIMER的加载值设置成最大值,并将前一个通道设置成上升沿触发,后一个设置成下降沿触发。最后打开中断和DMA,DMA要设置成循环模式。最后根据个人硬件配置情况设置好后,生成代码就可以了。(注:以下用例选择的是TIME15的通道1和通道2。)

2. 中断方法测量

注意:尽管上面配置中使能了DMA,但使用中断测量方法没有用到DMA。
首先需要在main.c中定义全局变量:

#define COUNT_MAX    8
static volatile uint16_t risingCount[COUNT_MAX];
static volatile uint16_t fallingCount[COUNT_MAX];
static volatile uint16_t offset, number;

然后在main()函数中的无限循环的前面加入TIMER的启动语句:

         HAL_TIM_IC_Start_IT(&htim15, TIM_CHANNEL_1);HAL_TIM_IC_Start_IT(&htim15, TIM_CHANNEL_2);

再在无限循环中加入测量结果的打印语句:

        if (number >= 2){uint16_t index1 = (offset - 2) & (COUNT_MAX - 1);uint16_t index2 = (index1 + 1) & (COUNT_MAX - 1);uint16_t width = fallingCount[index1] - risingCount[index1];uint16_t period = risingCount[index2] - risingCount[index1];printf("W:%u P:%u\r\n", width, period);  /*  W是脉冲宽度,P是方波周期 */number = 1;}

打印出的测量结果值单位是TIMER的计数,需要根据TIMER的时钟频率折算成时间单位。这里省略。
最后加入中断采样函数:

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{if (htim->Instance == TIM15 && htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1){risingCount[offset] = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1); /* 上升沿的时间戳采样 */}if (htim->Instance == TIM15 && htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2){fallingCount[offset] = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2); /* 下降沿的时间戳采样 */offset = (offset + 1) & (COUNT_MAX - 1);number++;}
}

由于中断处理需要时间,这种测量方法仅对频率在150KHz以下的方波有效。

3. DMA方法测量

DMA方法不同于上面的中断方法,所以程序需要重新写。也首先需要在main.c中定义全局变量:

#define DMA_LEN      16
static uint16_t dmaBuff[DMA_LEN] __attribute__(( aligned(32)));
static uint16_t dmaReady;

然后在main()函数中的无限循环的前面加入启动TIMER和DMA的语句:

HAL_TIM_DMABurst_MultiReadStart(&htim15, TIM_DMABASE_CCR1, TIM_DMA_CC1, (uint32_t *)dmaBuff, TIM_DMABURSTLENGTH_2TRANSFERS, DMA_LEN);
TIM_CCxChannelCmd(htim15.Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE); /* HAL库函数内可能没有启动TIMER,这里补上 */
TIM_CCxChannelCmd(htim15.Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
__HAL_TIM_ENABLE(&htim15);

这是启动TIMER的Burst读模式。在这一模式下TIMER可以一次DMA请求传输多个寄存器的值。这里我们需要读出通道1和通道2两个寄存器的时间戳值,DMA请求由通道1触发。
有些STM32处理器的HAL库没有提供这个Burst读模式的API,可以用下面的替代函数:

void TIM_DMABurst_MultiReadStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, uint32_t BurstRequestSrc,uint32_t *BurstBuffer, uint32_t BurstLength, uint32_t BufferLength)
{/* Set the DMA capture callbacks */htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMACaptureCplt;htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt;/* Set the DMA error callback */htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ;/* Enable the DMA channel */HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer, BufferLength);/* configure the DMA Burst Mode */htim->Instance->DCR = (BurstBaseAddress | BurstLength);/* Enable the TIM DMA Request */__HAL_TIM_ENABLE_DMA(htim, BurstRequestSrc);TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE);TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);__HAL_TIM_ENABLE(htim);htim->State = HAL_TIM_STATE_READY;
}

再在无限循环中加入测量结果的打印语句:

          if (dmaReady){uint16_t offset = (DMA_LEN - ((DMA_Stream_TypeDef *)htim15.hdma[TIM_DMA_ID_CC1]->Instance)->NDTR) & (DMA_LEN - 1);uint16_t index1 = (offset - 4) & (DMA_LEN - 1);uint16_t index2 = (index1 + 2) & (DMA_LEN - 1);uint16_t period = dmaBuff[index2] - dmaBuff[index1];uint16_t width = period + dmaBuff[index1 + 1] - dmaBuff[index1];if (width < period) printf("W:%u P:%u\r\n", width, period);dmaReady = 0;}

注:这里直接使用了DMA的计数寄存器NDTR。STM32处理器不同其名称可能也不同,比如也许是CNDTR。请查阅自己处理器的手册修改成正确名称。
最后加入DMA中断函数:

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{if (htim->Instance == TIM15){dmaReady = 1;}
}

由于DMA中断是在每次BUFFER满时才触发,所以对采样速率影响很小。

4. 结束语

以上仅是展示测量的基本方法,如要使其工作完善还需要一些更为细致的处理,这里就不涉及了。两种测量中都使用了双通道的测量方法。其实单通道也可以使用中断测量。但这需要在中断中加入触发沿的切换,可想而知其对测量速率会产生影响。好处仅是少占用了一个TIMER通道。
另外使用DMA的测量方法需要STM32微处理器支持Burst模式。我不确定有哪些STM32支持或不支持此功能,你需要查阅手册确认其TIMER支持此功能才可以使用。

5.备注

请参考使用DMA测量方法的具体实例。

使用STM32测量PWM方波频率和占空比的方法相关推荐

  1. STM32笔记——定时器输入捕获功能(测量PWM的频率和占空比)

    目录 一.概述 二.输入捕获功能 2.1 输入捕获简介 2.2 输入捕获通道 三.输入捕获功能测量PWM波的频率和占空比 3.1 测量频率的方法 3.2 测量过程 一.概述 主要介绍通用定时器的输入捕 ...

  2. STM32中的PWM的频率和占空比的设置

    网上看到一篇文章,不是很完整,但是有助于我理解,个人觉得还可以,具体的代码,网上有很多,大家可以参考参考计算一下. 下面的这个是stm32的定时器逻辑图,上来有助于理解: TIM3的ARR寄存器和PS ...

  3. MiniFly微型四轴学习开发日志(四)——关于四轴硬件知识以及如何通过STM32输出PWM方波控制电机

    目录 四轴硬件知识 通过STM32输出PWM方波 一.四轴硬件知识 四轴无人机需要的硬件大致有以下几种:电子调速器(俗称电调),螺旋桨,电子(一般用无刷电机),飞行控制板,机架,电池,充电器,遥控器等 ...

  4. STM32通过PWM产生频率为20HZ占空比为50%方波,并通过单片机测量频率并显示

    已经有快半年没有整过32单片机,为了准备电赛最近又复习了一下单片机相关的知识.发现只是看教程.手册没有啥的也不知道自己有没有学会,于是决定做一个小小的测试.测试内容是通过PWM产生频率为20HZ的占空 ...

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

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

  6. 基于msp430G2553的低频方波频率、占空比、峰峰值测量函数

    使用的平台是TI公司的launch pad,频率和占空比已经实现,峰峰值还有有待改进 1.主函数部分: /*********************************************\ ...

  7. pwm的频率和占空比

    pwm的频率是指每秒钟信号从高电平到低电平再回到高电平的次数,占空比是高电平持续时间和低电平持续时间之间的比例.pwm的频率越高,其对输出的响应就会越快,频率越低输出响应越慢.pwm的调节作用来源于对 ...

  8. STM32使用PWM输入模式测试频率和占空比

    参考文档: STM32中文参考考手册 1.cubuMX设置 主程序添加代码 测试主程序: /* USER CODE BEGIN Header */ /************************* ...

  9. 10. GD32F103C8T6 定时器-测量pwm的占空比和频率

    一. 利用TIM2的输入通道0,通道1测量pwm的占空比和频率 1. 配置gpio void inpit_gpio_config(void) {rcu_periph_clock_enable(RCU_ ...

最新文章

  1. python 矩阵常用计算
  2. mysql 二进制查询_MySql如何插入和查询二进制数据_MySQL
  3. 为什么说Android才是游戏开发者的乐土?
  4. 西北大学计算机转专业,西北大学可以转专业吗,西北大学新生转专业政策
  5. [Python技巧]是时候用 defaultdict 和 Counter 代替 dictionary 了
  6. java windows7 环境变量_Windows7环境变量中,系统变量与用户变量的优先级
  7. 工程师已经被虐到不行不行的了
  8. python---(4) win10 环境下访问MYSQL 数据库
  9. poj2406Power string
  10. 云之幻哔哩哔哩uwp_【UWP】一款很 Fluent Design 的 Bilibili UWP客户端:哔哩
  11. Advanced Graphics and Animations for iOS Apps
  12. vc++2010学习版注册码分享
  13. 计算机技术概论知识点,《计算机基础概论》知识点.pdf
  14. proj4js 坐标转换
  15. SpringBoot整合Shiro学习(上)
  16. Rockchip RK3288型号获取
  17. 洛谷:P1033 [NOIP2002 提高组] 自由落体 C++详解
  18. win8 java不是内部或外部命令_win8系统运行java提示“ava不是内部或外部命令两种解决方法...
  19. opencv读取黑白图片生成凹凸效果图
  20. 写在京东泄露12G用户信息后的一些感想

热门文章

  1. 认识c语言程序,认识C语言 -一个完整的C语言程序是什么样的?
  2. 前端知识之angular组件库之NG-ZORRO-ANTD结构窥探(三)pipe ,polify,service
  3. 图片编辑的利器(介绍韩国免费图片工具PhotoScape)
  4. PPT模板(2019推荐),16个高品质日本、欧美、韩国主题免费下载网站
  5. 如何与陌生人搭讪十技巧
  6. CCNA培训(一)20210710day01
  7. vue中将网页以pdf格式下载
  8. 如何生活而不是活着?
  9. 程序设计——小型计算机
  10. typeorm-统计数据,格式化时间