STM8S_库函数_TIM1输入捕获测量信号周期

大家好,我是单片机爱好者-MCU起航。这里说下使用库函数方式控制STM8S103F3P6片上的定时器1,也就是TIM1。上一节说了如何使用TIM1实现基本的定时功能,这一节看一下如何使用TIM1来测量PWM的周期,或者频率。

首先看一下TIM1信号输入部分的结构框图:

前面四个通道,代表TIM1的四个输入通道(PWM输出模式时,可做为输出通道)。后面IC1~IC4,代表送入到TIM1的四个信号通路。

然后,这里我们以IC3为例,说一下输入捕获是怎么工作的。数据手册里也有一个详细的说明,但我个人感觉比较繁琐,我按照我理解的来说下。

1、IC3的信号源有三个可选:TI3FP3、TI4FP3、TRC。

2、可以对这三个信号源进行滤波操作,避免杂波;可进行分频操作,避免频率太高,不好测量。

3、可以选择是上升沿还是下降沿触发捕获。

4、可选择触发捕获时,是否有中断。

5、工作时,启动TIM1计数,假设下降沿触发。连续发生两次捕获,记录每次捕获时的计数器的值,两个值相减,得到PWM的周期。

复杂问题简单化,我觉得这样好理解。

具体如何实现,我们看代码:

#include "stm8s.h"

/**
  * @addtogroup TIM1_Input_Capture
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
uint32_t TIM1ClockFreq = 2000000;
__IO uint32_t LSIClockFreq = 0;
uint16_t ICValue1 =0, ICValue2 =0;
/* Private function prototypes -----------------------------------------------*/
static void TIM1_Config(void);
/* Private functions ---------------------------------------------------------*/
/* Public functions ----------------------------------------------------------*/

/**
  * @brief  Main program.
  * @param  None
  * @retval None
  */
void main(void)
{

  /* TIM1 configuration -----------------------------------------*/
  TIM1_Config();
    
  /* Compute clock frequency */
  LSIClockFreq = (8 * TIM1ClockFreq) / (ICValue2 - ICValue1);
  
  /* Insert a break point here */
  while (1)
  {}
}

/**
  * @brief  Configure TIM1 to to capture the internal clock source
  * @param  None
  * @retval None
  */
static void TIM1_Config(void)
{
  TIM1_ICInit( TIM1_CHANNEL_3, TIM1_ICPOLARITY_FALLING, TIM1_ICSELECTION_DIRECTTI,
               TIM1_ICPSC_DIV8, 0x0);
  
  /* Enable TIM1 */
  TIM1_Cmd(ENABLE);

  /* Clear CC1 Flag*/
  TIM1_ClearFlag(TIM1_FLAG_CC3);
  
  /* wait a capture on CC3 */
  while((TIM1->SR1 & TIM1_FLAG_CC3) != TIM1_FLAG_CC3);
  /* Get CCR3 value*/
  ICValue1 = TIM1_GetCapture3();
  TIM1_ClearFlag(TIM1_FLAG_CC3);
  
  /* wait a capture on cc3 */
  while((TIM1->SR1 & TIM1_FLAG_CC3) != TIM1_FLAG_CC3);
  /* Get CCR3 value*/
  ICValue2 = TIM1_GetCapture3();
  TIM1_ClearFlag(TIM1_FLAG_CC3);
}

开头定义了一个变量TIM1ClockFreq,它里面存的是TIM1的时钟频率2M。直接看主函数,很简单,只有三部分。

1、对TIM1进行配置;2、计算PWM频率;3、原地等待。

所以,关键在第一部分,我们看下具体代码。在函数“TIM1_Config”里,几乎完成了大部分工作。

1、TIM1初始化,选择通道3、下降沿触发、通道3过来的信号(也就是TIM1_ICSELECTION_DIRECTTI)、信号8分频、无滤波。

2、使能TIM1,并清楚IC3的捕获标志。

3、等待第一次捕获出现,记录当时的计数器的值,并清捕获标志。

4、等待第二次捕获出现,记录当时的计数器的值,并清捕获标志。

看到这,应该明白了。ICValue1和ICValue2存储的分别是第一次捕获和第二次捕获时,计数器里面的值,两个值相减,得到的就是PWM的周期。所以才会有这行代码:

/* Compute clock frequency */

LSIClockFreq = (8 * TIM1ClockFreq) / (ICValue2 – ICValue1);

TIM1的通道3对应单片机的PC3脚,如图:

最后,编译、下载、上电,功能正常!

打完收工!

要获取该程序完整的工程文件,可以关注公众号:单片机爱好者,然后回复关键词:STM8S。可以获取完整的下载链接,里面包含工程文件、视频、PPT、数据手册等所有相关资料。

发表评论

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据