TIM输入捕获
输入捕获简介
- IC(Input Capture) 输入捕获
- 输入捕获模式下, 当通道输入引脚出现指定电平跳变时, 当前CNT的值将被锁存到CCR中, 可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数
- 每个高级定时器和通用定时器都拥有四个输入捕获通道
- 可配置为PWMI模式, 同时测量频率和占空比
- 可配合主从触发模式, 实现硬件全自动测量
频率测量
-
测频法: 在闸门时间T内, 对上升沿计次, 得到N, 则频率fx = N / T(适用于测高频信号)
-
测周法: 两个上升沿内, 以标准频率fc计次, 得到N, 则频率fx = fc / N(适用于测低频信号s)
-
中界频率: 测频法与测周法误差相等的频率点, fm = sqrt(fc / T)
输入捕获通道
- fDTS: 滤波器采样时钟来源
- TI1F: 滤波后的信号
- CCMR1寄存器里的ICF位可以控制滤波器的参数
- 通道2部分电路未画出
主从触发模式
主模式: 将定时器内部的信号, 映射到TRGO引脚, 用于触发别的外设
从模式: 接受其他外设或者自身外设的信号, 用于控制自身定时器的运行
输入捕获基本结构
- 工作流程: 设边沿检测极性为高电平, 信号沿通道GPIO->滤波器->边沿检测, 当检测到高电平后, 发出TI1FP1信号;TI1FP1有两条通道, 第一条通道继续向下到分频器, 最后到CCR捕获/比较寄存器, CCR接受到信号后, 捕获CNT的计次N; 另一条通道, 则通过从模式将CNT置零。
- 用得到的计次N可得频率 f = fc / N, fc是标准频率, 通过配置时基单元设置, 这里用的是测周法测频率的原理
PWMI基本结构
- 与输入捕获结构相似, 但开启了第二条通道, 第二条通道在下降沿(与第一条通道触发方式相反), 触发CCR2寄存器捕获CNT的值得到N1,第一条通道则还是在上升沿捕获CNT的值得到N2
- 如图所示: 易得占空比 = (N1+1)*100 / (N2+1) %
案例1: TIM输入捕获测量信号频率(对应输入捕获基本机构)
说明
- 用PA0 的定时器 生成测试信号, PA6的定时器 捕获信号测量频率
- 由于配置过程类似, 这里仅对IC单元的配置和从模式配置进行详细说明, 其余过程在注释中可以大致了解。
硬件接线
配置IC单元
// 配置IC单元
TIM_ICInitTypeDef TIM_InitStructure;
TIM_InitStructure.TIM_Channel=TIM_Channel_1; // 定时器通道
TIM_InitStructure.TIM_ICFilter=0xF; // 滤波器
TIM_InitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising; // 边沿极性选择
TIM_InitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1; // 分频器
TIM_InitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI; // 配置选择器模式
TIM_ICInit(TIM3, &TIM_InitStructure);
TIM_ICInitTypeDef
typedef struct
{
uint16_t TIM_Channel; /*!< Specifies the TIM channel.
This parameter can be a value of @ref TIM_Channel */
uint16_t TIM_ICPolarity; /*!< Specifies the active edge of the input signal.
This parameter can be a value of @ref TIM_Input_Capture_Polarity */
uint16_t TIM_ICSelection; /*!< Specifies the input.
This parameter can be a value of @ref TIM_Input_Capture_Selection */
uint16_t TIM_ICPrescaler; /*!< Specifies the Input Capture Prescaler.
This parameter can be a value of @ref TIM_Input_Capture_Prescaler */
uint16_t TIM_ICFilter; /*!< Specifies the input capture filter.
This parameter can be a number between 0x0 and 0xF */
} TIM_ICInitTypeDef;
TIM_Channel
#define TIM_Channel_1 ((uint16_t)0x0000)
#define TIM_Channel_2 ((uint16_t)0x0004)
#define TIM_Channel_3 ((uint16_t)0x0008)
#define TIM_Channel_4 ((uint16_t)0x000C)
TIM_ICPolarity
#define TIM_ICPolarity_Rising ((uint16_t)0x0000)
#define TIM_ICPolarity_Falling ((uint16_t)0x0002)
#define TIM_ICPolarity_BothEdge ((uint16_t)0x000A)
TIM_ICSelection
#define TIM_ICSelection_DirectTI ((uint16_t)0x0001) /*!< TIM Input 1, 2, 3 or 4 is selected to be
connected to IC1, IC2, IC3 or IC4, respectively */
#define TIM_ICSelection_IndirectTI ((uint16_t)0x0002) /*!< TIM Input 1, 2, 3 or 4 is selected to be
connected to IC2, IC1, IC4 or IC3, respectively. */
#define TIM_ICSelection_TRC ((uint16_t)0x0003) /*!< TIM Input 1, 2, 3 or 4 is selected to be connected to TRC. */
TIM_ICPrescaler
#define TIM_ICPSC_DIV1 ((uint16_t)0x0000) /*!< Capture performed each time an edge is detected on the capture input. */
#define TIM_ICPSC_DIV2 ((uint16_t)0x0004) /*!< Capture performed once every 2 events. */
#define TIM_ICPSC_DIV4 ((uint16_t)0x0008) /*!< Capture performed once every 4 events. */
#define TIM_ICPSC_DIV8 ((uint16_t)0x000C) /*!< Capture performed once every 8 events. */
TIM_ICFilter
uint16_t TIM_ICFilter; /*!< Specifies the input capture filter.
This parameter can be a number between 0x0 and 0xF */
配置从模式
// 配置从模式
TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1); // 选择输入触发
TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset); // 选择从模式
void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource)
/**
* @brief Selects the Input Trigger source
* @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral.
* @param TIM_InputTriggerSource: The Input Trigger source.
* This parameter can be one of the following values:
* @arg TIM_TS_ITR0: Internal Trigger 0
* @arg TIM_TS_ITR1: Internal Trigger 1
* @arg TIM_TS_ITR2: Internal Trigger 2
* @arg TIM_TS_ITR3: Internal Trigger 3
* @arg TIM_TS_TI1F_ED: TI1 Edge Detector
* @arg TIM_TS_TI1FP1: Filtered Timer Input 1
* @arg TIM_TS_TI2FP2: Filtered Timer Input 2
* @arg TIM_TS_ETRF: External Trigger input
* @retval None
*/
void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode)
/**
* @brief Selects the TIMx Slave Mode.
* @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral.
* @param TIM_SlaveMode: specifies the Timer Slave Mode.
* This parameter can be one of the following values:
* @arg TIM_SlaveMode_Reset: Rising edge of the selected trigger signal (TRGI) re-initializes
* the counter and triggers an update of the registers.
* @arg TIM_SlaveMode_Gated: The counter clock is enabled when the trigger signal (TRGI) is high.
* @arg TIM_SlaveMode_Trigger: The counter starts at a rising edge of the trigger TRGI.
* @arg TIM_SlaveMode_External1: Rising edges of the selected trigger (TRGI) clock the counter.
* @retval None
*/
整体代码
IC.c
#include "stm32f10x.h"
/*
初始化TIM3_IC
*/
void TIM3_IC_Init(void)
{
// RCC使能时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
// 配置GPIO口 A6 TIM3_CH1
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置时钟源
TIM_InternalClockConfig(TIM3);
// 配置时基单元
TIM_TimeBaseInitTypeDef TimeBase_InitStructure;
TimeBase_InitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TimeBase_InitStructure.TIM_CounterMode=TIM_CounterMode_Up; // 向上计数
TimeBase_InitStructure.TIM_Period=65536-1; // ARR
TimeBase_InitStructure.TIM_Prescaler=72-1; // PSC
TimeBase_InitStructure.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM3, &TimeBase_InitStructure);
// 配置IC单元
TIM_ICInitTypeDef TIM_InitStructure;
TIM_InitStructure.TIM_Channel=TIM_Channel_1; // 定时器通道
TIM_InitStructure.TIM_ICFilter=0xF; // 滤波器
TIM_InitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising; // 边沿极性选择
TIM_InitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1; // 分频器
TIM_InitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI; // 配置选择器模式
TIM_ICInit(TIM3, &TIM_InitStructure);
// 配置从模式
TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1);
TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);
// 开启定时器
TIM_Cmd(TIM3, ENABLE);
}
/*
获取TIM3_CH1 输入波形频率
*/
uint16_t Get_TIM3_CH1_Freq(void)
{
return 72000000/(TIM_GetPrescaler(TIM3)+1)/ (TIM_GetCapture1(TIM3)+1);
}
PWM.c
#include "stm32f10x.h"
/*
初始化TIM2的PWM模式
*/
void TIM2_PWM_Init(void)
{
// RCC使能时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// 配置GPIO口
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置内部时钟作为TIM的时钟源
TIM_InternalClockConfig(TIM2);
// 配置时基单元
TIM_TimeBaseInitTypeDef TimeBase_InitStructure;
TimeBase_InitStructure.TIM_ClockDivision=TIM_CKD_DIV1 ;
TimeBase_InitStructure.TIM_CounterMode=TIM_CounterMode_Up; // 向上计数
TimeBase_InitStructure.TIM_Period=100-1; // ARR
TimeBase_InitStructure.TIM_Prescaler=720-1; // PSC
TimeBase_InitStructure.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM2, &TimeBase_InitStructure);
// 配置OC单元
TIM_OCInitTypeDef OC1_InitStructure;
TIM_OCStructInit(&OC1_InitStructure);
OC1_InitStructure.TIM_OutputState=TIM_OutputState_Enable;
OC1_InitStructure.TIM_OCMode=TIM_OCMode_PWM1; // 设置模式
OC1_InitStructure.TIM_OCPolarity=TIM_OCPolarity_High; // 设置有效电平
OC1_InitStructure.TIM_Pulse=50; // CCR
TIM_OC1Init(TIM2, &OC1_InitStructure);
// 开启时钟
TIM_Cmd(TIM2, ENABLE);
}
/*
初始化TIM3的PWM模式
*/
void TIM3_PWM_Init(void)
{
// RCC使能时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// 配置GPIO口
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置内部时钟作为TIM的时钟源
TIM_InternalClockConfig(TIM3);
// 配置时基单元
TIM_TimeBaseInitTypeDef TimeBase_InitStructure;
TimeBase_InitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TimeBase_InitStructure.TIM_CounterMode=TIM_CounterMode_Up;
TimeBase_InitStructure.TIM_Period=100-1; // ARR
TimeBase_InitStructure.TIM_Prescaler=720-1; // PSC
TimeBase_InitStructure.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM3, &TimeBase_InitStructure);
// 配置OC单元
TIM_OCInitTypeDef OC1_InitStructure;
TIM_OCStructInit(&OC1_InitStructure);
OC1_InitStructure.TIM_OCMode=TIM_OCMode_PWM1; // 设置模式
OC1_InitStructure.TIM_OCPolarity=TIM_OCPolarity_High; // 设置有效电平
OC1_InitStructure.TIM_OutputState=TIM_OutputState_Enable;
OC1_InitStructure.TIM_Pulse=50; // CCR
TIM_OC1Init(TIM3, &OC1_InitStructure);
// 开启时钟
TIM_Cmd(TIM3, ENABLE);
}
/*
设置TIM2的CRR1寄存器
*/
void TIM2_PWM_Set_Compare1(uint16_t Compare)
{
TIM_SetCompare1(TIM2, Compare); // 设置OC1 CCR寄存器
}
/*
设置TIM3的CRR1寄存器
*/
void TIM3_PWM_Set_Compare1(uint16_t Compare)
{
TIM_SetCompare1(TIM3, Compare);
}
main.c
#include "stm32f10x.h"
#include "OLED.h"
#include "PWM.h"
#include "IC.h"
// TIM输入测频率
// 2023年3月25日11:11:15
int main(void)
{
TIM2_PWM_Init();
TIM3_IC_Init();
OLED_Init();
OLED_ShowString(1, 1, "Freq:00000Hz");
while(1)
{
OLED_ShowNum(1, 6, Get_TIM3_CH1_Freq(), 5);
}
}
案例2: PWMI模式下测量信号频率和占空比(对应PWMI基本结构)
整体代码
IC.c
#include "stm32f10x.h"
/*
初始化TIM3_IC
*/
void TIM3_IC_Init(void)
{
// RCC使能时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
// 配置GPIO口 A6 TIM3_CH1
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置时钟源
TIM_InternalClockConfig(TIM3);
// 配置时基单元
TIM_TimeBaseInitTypeDef TimeBase_InitStructure;
TimeBase_InitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TimeBase_InitStructure.TIM_CounterMode=TIM_CounterMode_Up; // 向上计数
TimeBase_InitStructure.TIM_Period=65536-1; // ARR
TimeBase_InitStructure.TIM_Prescaler=72-1; // PSC
TimeBase_InitStructure.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM3, &TimeBase_InitStructure);
// 配置IC单元
TIM_ICInitTypeDef TIM_InitStructure;
TIM_InitStructure.TIM_Channel=TIM_Channel_1; // 定时器通道
TIM_InitStructure.TIM_ICFilter=0xF; // 滤波器
TIM_InitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising; // 边沿极性选择
TIM_InitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1; // 分频器
TIM_InitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI; // 选择器
TIM_PWMIConfig(TIM3, &TIM_InitStructure); // 区别在这里
// 配置从模式
TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1); // 选择TI1FP1通道
TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset); // 选择Reset模式
// 开启定时器
TIM_Cmd(TIM3, ENABLE);
}
/*
获取TIM3_CH1 输入波形频率
*/
uint32_t Get_TIM3_CH1_Freq(void)
{
return 72000000/(TIM_GetPrescaler(TIM3)+1)/ (TIM_GetCapture1(TIM3)+1);
}
/*
获取TIM3_PWMI 模式下占空比
*/
uint32_t Get_TIM3_Duty(void)
{
return (TIM_GetCapture2(TIM3) + 1)*100 / (TIM_GetCapture1(TIM3) + 1);
}
TIM_PWMIConfig函数原型
/**
* @brief Configures the TIM peripheral according to the specified
* parameters in the TIM_ICInitStruct to measure an external PWM signal.
* @param TIMx: where x can be 1, 2, 3, 4, 5, 8, 9, 12 or 15 to select the TIM peripheral.
* @param TIM_ICInitStruct: pointer to a TIM_ICInitTypeDef structure
* that contains the configuration information for the specified TIM peripheral.
* @retval None
*/
void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct)
{
uint16_t icoppositepolarity = TIM_ICPolarity_Rising;
uint16_t icoppositeselection = TIM_ICSelection_DirectTI;
/* Check the parameters */
assert_param(IS_TIM_LIST6_PERIPH(TIMx));
/* Select the Opposite Input Polarity */
if (TIM_ICInitStruct->TIM_ICPolarity == TIM_ICPolarity_Rising)
{
icoppositepolarity = TIM_ICPolarity_Falling;
}
else
{
icoppositepolarity = TIM_ICPolarity_Rising;
}
/* Select the Opposite Input */
if (TIM_ICInitStruct->TIM_ICSelection == TIM_ICSelection_DirectTI)
{
icoppositeselection = TIM_ICSelection_IndirectTI;
}
else
{
icoppositeselection = TIM_ICSelection_DirectTI;
}
if (TIM_ICInitStruct->TIM_Channel == TIM_Channel_1)
{
/* TI1 Configuration */
TI1_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, TIM_ICInitStruct->TIM_ICSelection,
TIM_ICInitStruct->TIM_ICFilter);
/* Set the Input Capture Prescaler value */
TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler);
/* TI2 Configuration */
TI2_Config(TIMx, icoppositepolarity, icoppositeselection, TIM_ICInitStruct->TIM_ICFilter);
/* Set the Input Capture Prescaler value */
TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler);
}
else
{
/* TI2 Configuration */
TI2_Config(TIMx, TIM_ICInitStruct->TIM_ICPolarity, TIM_ICInitStruct->TIM_ICSelection,
TIM_ICInitStruct->TIM_ICFilter);
/* Set the Input Capture Prescaler value */
TIM_SetIC2Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler);
/* TI1 Configuration */
TI1_Config(TIMx, icoppositepolarity, icoppositeselection, TIM_ICInitStruct->TIM_ICFilter);
/* Set the Input Capture Prescaler value */
TIM_SetIC1Prescaler(TIMx, TIM_ICInitStruct->TIM_ICPrescaler);
}
}
PWM.c
#include "stm32f10x.h"
/*
初始化TIM2的PWM模式
*/
void TIM2_PWM_Init(void)
{
// RCC使能时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// 配置GPIO口
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置内部时钟作为TIM的时钟源
TIM_InternalClockConfig(TIM2);
// 配置时基单元
TIM_TimeBaseInitTypeDef TimeBase_InitStructure;
TimeBase_InitStructure.TIM_ClockDivision=TIM_CKD_DIV1 ;
TimeBase_InitStructure.TIM_CounterMode=TIM_CounterMode_Up; // 向上计数
TimeBase_InitStructure.TIM_Period=100-1; // ARR
TimeBase_InitStructure.TIM_Prescaler=720-1; // PSC
TimeBase_InitStructure.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM2, &TimeBase_InitStructure);
// 配置OC单元
TIM_OCInitTypeDef OC1_InitStructure;
TIM_OCStructInit(&OC1_InitStructure);
OC1_InitStructure.TIM_OutputState=TIM_OutputState_Enable;
OC1_InitStructure.TIM_OCMode=TIM_OCMode_PWM1; // 设置模式
OC1_InitStructure.TIM_OCPolarity=TIM_OCPolarity_High; // 设置有效电平
OC1_InitStructure.TIM_Pulse=50; // CCR
TIM_OC1Init(TIM2, &OC1_InitStructure);
// 开启时钟
TIM_Cmd(TIM2, ENABLE);
}
/*
初始化TIM3的PWM模式
*/
void TIM3_PWM_Init(void)
{
// RCC使能时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// 配置GPIO口
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置内部时钟作为TIM的时钟源
TIM_InternalClockConfig(TIM3);
// 配置时基单元
TIM_TimeBaseInitTypeDef TimeBase_InitStructure;
TimeBase_InitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TimeBase_InitStructure.TIM_CounterMode=TIM_CounterMode_Up;
TimeBase_InitStructure.TIM_Period=100-1; // ARR
TimeBase_InitStructure.TIM_Prescaler=720-1; // PSC
TimeBase_InitStructure.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM3, &TimeBase_InitStructure);
// 配置OC单元
TIM_OCInitTypeDef OC1_InitStructure;
TIM_OCStructInit(&OC1_InitStructure);
OC1_InitStructure.TIM_OCMode=TIM_OCMode_PWM1; // 设置模式
OC1_InitStructure.TIM_OCPolarity=TIM_OCPolarity_High; // 设置有效电平
OC1_InitStructure.TIM_OutputState=TIM_OutputState_Enable;
OC1_InitStructure.TIM_Pulse=50; // CCR
TIM_OC1Init(TIM3, &OC1_InitStructure);
// 开启时钟
TIM_Cmd(TIM3, ENABLE);
}
/*
设置TIM2的CRR1寄存器
*/
void TIM2_PWM_Set_Compare1(uint16_t Compare)
{
TIM_SetCompare1(TIM2, Compare); // 设置OC1 CCR寄存器
}
/*
设置TIM2的PSC寄存器
*/
void TIM2_PWM_Set_PSC(uint16_t PSC)
{
TIM_PrescalerConfig(TIM2, PSC, TIM_PSCReloadMode_Update);
}
/*
设置TIM3的CRR1寄存器
*/
void TIM3_PWM_Set_Compare1(uint16_t Compare)
{
TIM_SetCompare1(TIM3, Compare);
}
main.c
#include "stm32f10x.h"
#include "OLED.h"
#include "PWM.h"
#include "IC.h"
// PWMI模式下测量信号频率和占空比
// 2023年3月25日11:13:10
int main(void)
{
TIM2_PWM_Init();
TIM3_IC_Init();
OLED_Init();
OLED_ShowString(1, 1, "Freq:00000Hz");
OLED_ShowString(2, 1, "Duty:00%");
// 设置占空比
TIM2_PWM_Set_Compare1(30); // Duty = CCR / ARR + 1
// 设置频率
TIM2_PWM_Set_PSC(72-1); // Freq = 72M / (ARR + 1) / (PSC + 1)
while(1)
{
OLED_ShowNum(1, 6, Get_TIM3_CH1_Freq(), 5);
OLED_ShowNum(2, 6, Get_TIM3_Duty(), 2);
}
}
TIM3_PWM_Set_Compare1(uint16_t Compare)
{
TIM_SetCompare1(TIM3, Compare);
}
#### main.c
```C
#include "stm32f10x.h"
#include "OLED.h"
#include "PWM.h"
#include "IC.h"
// PWMI模式下测量信号频率和占空比
// 2023年3月25日11:13:10
int main(void)
{
TIM2_PWM_Init();
TIM3_IC_Init();
OLED_Init();
OLED_ShowString(1, 1, "Freq:00000Hz");
OLED_ShowString(2, 1, "Duty:00%");
// 设置占空比
TIM2_PWM_Set_Compare1(30); // Duty = CCR / ARR + 1
// 设置频率
TIM2_PWM_Set_PSC(72-1); // Freq = 72M / (ARR + 1) / (PSC + 1)
while(1)
{
OLED_ShowNum(1, 6, Get_TIM3_CH1_Freq(), 5);
OLED_ShowNum(2, 6, Get_TIM3_Duty(), 2);
}
}
参考资料
https://www.bilibili.com/video/BV1th411z7sn?p=18&vd_source=722e2c21f78eecf154c5c9d24c2841b3