一、簡介
IC輸入捕獲
輸入捕獲模式下,當通道輸入引腳出現指定電平跳變時,當前CNT的值將被鎖存在CCR中,可用于測量PWM波形的頻率、占空比、脈沖間隔、電平持續時間等參數
每個高級定時器和通用定時器都擁有4個輸入捕獲通道
可配置為PWMI模式,同事測量頻率和占空比
可配合主從觸發模式。實現硬件全自動測量
二、工程代碼
項目一:
程序現象:自己“測”自己;輸入捕獲模式測頻率
配置流程:
? ? ? ? 1.RCC開啟時鐘
? ? ? ? 2.GPIO初始化,配置為輸入模式
? ? ? ? 3.配置時基單元
? ? ? ? 4.配置輸入捕獲單元(捕獲通道、捕獲方式、輸入捕獲預分頻器)
? ? ? ? 5.選擇從模式觸發源
? ? ? ? 6.觸發之后進行的操作
? ? ? ? 7.開始定時器
接線:一根杜邦線一端接在單片機的PA6,另一端接在PA0
?這個是輸入捕獲的代碼,輸出波形的代碼在在我之前寫的TIM輸出比較的文章里面pwm_led.c里面;
pwm_ic.c
#include "stm32f10x.h" // STM32F10x外設庫頭文件
#include "pwm_ic.h" // PWM控制相關頭文件
#include "delay.h" // 延時函數頭文件// 按鍵初始化函數
void PWM_IC_Init(void)
{// 定義定時器基礎結構體和輸出比較結構體TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; GPIO_InitTypeDef GPIO_InitStructure; // GPIO初始化結構體TIM_ICInitTypeDef TIM_ICInitStruct; // 定時器輸入捕獲初始化結構體// 使能TIM3和GPIOA的時鐘RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); // 使能定時器TIM3時鐘RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 使能GPIOA時鐘// 配置GPIOA的引腳6為定時器的輸入引腳(PWM輸入)GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; // 配置GPIOA的Pin6GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 配置引腳的速度為50MHzGPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; // 配置為輸入下拉模式GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化GPIOA的Pin6引腳/* 配置時鐘源 */TIM_InternalClockConfig(TIM3); // 選擇TIM3為內部時鐘源,若不調用此函數,TIM默認也是內部時鐘// 配置定時器基本參數TIM_TimeBaseStructure.TIM_Period = 65535 - 1; // 自動重載值,定時器的計數周期為65535,即計數從0到65534,周期為65535個時鐘周期TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1; // 預分頻器值,定時器時鐘源被分頻為72MHz / 72 = 1000000Hz,即定時器時鐘頻率為1MHzTIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // 時鐘分割設置為1,表示不進行時鐘分割,保持時鐘完整性TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 計數模式設置為向上計數模式,從0計數到自動重載值(65535)TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; // 重復計數器設置為0,不啟用重復計數器,定時器只進行單次計數TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); // 初始化定時器TIM3,應用上述配置// 配置定時器輸入捕獲參數TIM_ICInitStruct.TIM_Channel = TIM_Channel_1; // 使用TIM3的通道1TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI; // 選擇直接連接到TI1的輸入信號TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1; // 輸入捕獲預分頻器為1TIM_ICInitStruct.TIM_ICFilter = 0xF; // 輸入濾波器設置為最大濾波值TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising; // 上升沿觸發輸入捕獲TIM_ICInit(TIM3, &TIM_ICInitStruct); // 初始化輸入捕獲// 配置觸發器TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1); // 選擇輸入觸發器為TIM3通道1的輸入(TI1)TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset); // 配置為復位模式,作為從設備// 啟動定時器TIM3TIM_Cmd(TIM3, ENABLE); // 啟動TIM3,使其開始計數并處理輸入捕獲}// 獲取PWM頻率的函數
u32 IC_GetFreq(void)
{// 計算PWM頻率(單位為Hz),根據捕獲到的輸入信號周期return 1000000 / (TIM_GetCapture1(TIM3) + 1); // 以微秒為單位進行計算
}
pwm_ic.h
#ifndef __PWM_IC_H
#define __PWM_IC_H#include "stm32f10x.h"
#include "sys.h"void PWM_IC_Init(void);
u32 IC_GetFreq(void);#endif
main.c
#include "stm32f10x.h" // 設備相關頭文件
#include "pwm_ic.h" // PWM控制相關頭文件
#include "delay.h" // 延時相關頭文件int main(){PWM_IC_Init(); // 初始化PWMdelay_init(); // 初始化延時函數/*使用PWM模塊提供輸入捕獲的測試信號*/PWM_SetPrescaler(720 - 1); //PWM頻率Freq = 72M / (PSC + 1) / 100//這兩個函數在之前輸出比較文章中pwm_led.c里面PWM_SetCompare1(50); //PWM占空比Duty = CCR / 100while(1){ IC_GetFreq(); }
}
項目二:
程序現象:PWMI模式測頻率占空比
pwmi_ic.c
#include "stm32f10x.h" // STM32F10x外設庫頭文件
#include "pwmi_ic.h" // PWM控制相關頭文件
#include "delay.h" // 延時函數頭文件// 按鍵初始化函數
void PWMI_IC_Init(void)
{// 定義定時器基礎結構體和輸出比較結構體TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; GPIO_InitTypeDef GPIO_InitStructure; // GPIO初始化結構體TIM_ICInitTypeDef TIM_ICInitStruct; // 定時器輸入捕獲初始化結構體// 使能TIM3和GPIOA的時鐘RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); // 使能定時器TIM3時鐘RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 使能GPIOA時鐘// 配置GPIOA的引腳6為定時器的輸入引腳(PWM輸入)GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; // 配置GPIOA的Pin6GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 配置引腳的速度為50MHzGPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; // 配置為輸入下拉模式GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化GPIOA的Pin6引腳/* 配置時鐘源 */TIM_InternalClockConfig(TIM3); // 選擇TIM3為內部時鐘源,若不調用此函數,TIM默認也是內部時鐘// 配置定時器基本參數TIM_TimeBaseStructure.TIM_Period = 65535 - 1; // 自動重載值,定時器的計數周期為65535,即計數從0到65534,周期為65535個時鐘周期TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1; // 預分頻器值,定時器時鐘源被分頻為72MHz / 72 = 1000000Hz,即定時器時鐘頻率為1MHzTIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // 時鐘分割設置為1,表示不進行時鐘分割,保持時鐘完整性TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 計數模式設置為向上計數模式,從0計數到自動重載值(65535)TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; // 重復計數器設置為0,不啟用重復計數器,定時器只進行單次計數TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); // 初始化定時器TIM3,應用上述配置// 配置定時器輸入捕獲參數TIM_ICInitStruct.TIM_Channel = TIM_Channel_1; // 使用TIM3的通道1TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI; // 選擇直接連接到TI1的輸入信號TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1; // 輸入捕獲預分頻器為1TIM_ICInitStruct.TIM_ICFilter = 0xF; // 輸入濾波器設置為最大濾波值TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising; // 上升沿觸發輸入捕獲TIM_ICInit(TIM3, &TIM_ICInitStruct); // 初始化輸入捕獲// // 配置定時器輸入捕獲參數
// TIM_ICInitStruct.TIM_Channel = TIM_Channel_2; // 使用TIM3的通道2
// TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_IndirectTI; // 選擇交叉輸入到TI1的輸入信號
// TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1; // 輸入捕獲預分頻器為1
// TIM_ICInitStruct.TIM_ICFilter = 0xF; // 輸入濾波器設置為最大濾波值
// TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Falling; // 下降沿觸發輸入捕獲
// TIM_ICInit(TIM3, &TIM_ICInitStruct); TIM_PWMIConfig(TIM3,&TIM_ICInitStruct);// 配置觸發器TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1); // 選擇輸入觸發器為TIM3通道1的輸入(TI1)TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset); // 配置為復位模式,作為從設備// 啟動定時器TIM3TIM_Cmd(TIM3, ENABLE); // 啟動TIM3,使其開始計數并處理輸入捕獲}// 獲取PWM頻率的函數
u32 IC_GetFreq(void)
{// 計算PWM頻率(單位為Hz),根據捕獲到的輸入信號周期return 1000000 / (TIM_GetCapture1(TIM3) + 1); // 以微秒為單位進行計算
}u32 IC_GetDuty(void)
{return (TIM_GetCapture2(TIM3) + 1)* 100 / (TIM_GetCapture1(TIM3) + 1);
}
pwmi_ic.h
#ifndef __PWMI_IC_H
#define __PWMI_IC_H#include "stm32f10x.h"
#include "sys.h"void PWMI_IC_Init(void);
u32 IC_GetFreq(void);
u32 IC_GetDuty(void);#endif
main.c
#include "stm32f10x.h" // 設備相關頭文件
#include "pwmi_ic.h" // PWM控制相關頭文件
#include "delay.h" // 延時相關頭文件int main(){PWMI_IC_Init(); // 初始化PWMdelay_init(); // 初始化延時函數/*使用PWM模塊提供輸入捕獲的測試信號*/PWM_SetPrescaler(720 - 1); //PWM頻率Freq = 72M / (PSC + 1) / 100PWM_SetCompare1(50); //PWM占空比Duty = CCR / 100while(1){ IC_GetFreq(); IC_GetDuty();}
}