大家好,我是单片机爱好者-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、数据手册等所有相关资料。