当前位置: 首页 > news >正文

脉冲计数实现

将定时器 2 通道 2 输入的低电平脉冲作为定时器 2 的时钟,并通过串口打印脉冲数 PSC=0,ARR=65535 外部时钟模式1、触发选择、上升沿触发、不分频、不滤波。

“外部时钟模式 1(ECM1)用 TIM2_CH2 计脉冲

main.c:

#include "sys.h"        // 项目通用头(通常会包含芯片HAL头文件及时钟配置)
#include "delay.h"      // 延时相关
#include "led.h"        // LED 驱动(用于简单指示)
#include "uart1.h"      // 串口1 打印
#include "counter.h"    // 本实验的计数器对外接口(见下方)int main(void)
{HAL_Init();                         /* 初始化HAL库:复位外设、初始化Flash接口、Systick等 */stm32_clock_init(RCC_PLL_MUL9);     /* 配置系统时钟到72MHz(HSE*9),为后续外设/内核提供时钟 */led_init();                         /* LED初始化(可选,用于指示运行状态) */uart1_init(115200);                 /* 串口1初始化为115200-8-N-1,用于打印结果 */printf("hello world!\r\n");/* * 计数器初始化:*  - arr = 65536 - 1 => 自动重装载寄存器ARR=0xFFFF(16位满量程)*  - psc = 0         => 预分频=0(即不分频,计数器每来一个外部脉冲就+1)** 说明:TIM2本身是32位定时器,但你把ARR设成了16位最大值,这样更直观地做“0~65535”循环计数。* 如果你要更大计数范围,可把ARR设更大(比如0xFFFFFFFF,需要按32位读改)。*/counter_init(65536 - 1, 0);while(1){/* 方式1:读取当前CNT并在变化时打印(示例与原逻辑一致) */count_get();/* 方式2(推荐做实时计数):得到“自上次调用以来的增量脉冲数”,更高效,避免频繁printf阻塞uint32_t incr = count_get_delta();if (incr) { printf("inc: %lu\r\n", incr); }*/// 适当小延时,避免打印过快造成串口阻塞(根据实际脉冲频率调整)delay_ms(1);}
}

counter.h

#ifndef __COUNTER_H__
#define __COUNTER_H__#include "stm32f1xx_hal.h"  // 确保包含到F1的HAL头;若你的sys.h已包含,可按需修改#ifdef __cplusplus
extern "C" {
#endif/* 对外接口函数声明 *//*** @brief 外部时钟模式1:用 TIM2_CH2 计数外部脉冲* @param arr 自动重装载值(周期 - 1),例如 65536 - 1 表示16位满量程* @param psc 预分频(0 表示不分频)*/
void     counter_init(uint32_t arr, uint16_t psc);/*** @brief 读取当前CNT值,若变化则通过printf打印(和你的原函数一致)*/
void     count_get(void);/*** @brief 返回“自上次调用以来的增量脉冲数”,自动处理ARR回卷(推荐统计增量用)* @return 增量(0 表示无新增脉冲)*/
uint32_t count_get_delta(void);#ifdef __cplusplus
}
#endif#endif /* __COUNTER_H__ */

counter.c:

#include "counter.h"
#include "stdio.h"/* 全局句柄:TIM2 用于计外部脉冲 */
TIM_HandleTypeDef counter_handle = {0};/* 保存上/下两次读取的计数值,用于变化打印与增量计算 */
static volatile uint32_t g_old_cnt = 0;      // 上一次读取的CNT
static volatile uint32_t g_arr     = 0xFFFF; // 记录配置的ARR,便于做回卷运算/*** @brief  初始化 TIM2 为“外部时钟模式1”,在 CH2(PA1) 上计数外部脉冲* @param  arr  自动重装载值(周期-1),例:65536-1* @param  psc  预分频系数(0=不分频)*/
void counter_init(uint32_t arr, uint16_t psc)
{/* ------------ 1. 基本定时器参数配置(只负责计数器本体) ------------ */counter_handle.Instance = TIM2;                     // 选择 TIM2counter_handle.Init.Prescaler = psc;                // 计数器预分频:0=不分频counter_handle.Init.Period = arr;                   // 自动重装载值 ARR,计数达到ARR后回到0counter_handle.Init.CounterMode = TIM_COUNTERMODE_UP;         // 向上计数counter_handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;   // 内部分频不再分(DIV1)HAL_TIM_Base_Init(&counter_handle);                 // 初始化基本定时器(装载上述配置)g_arr = arr;                                        // 保存ARR,供回卷计算/* ------------ 2. 配置输入捕获通道(把CH2当作触发源TI2FP2) ------------ */TIM_IC_InitTypeDef ic_cfg = {0};ic_cfg.ICPolarity  = TIM_INPUTCHANNELPOLARITY_RISING;  // 触发沿:上升沿(与你的“上升沿触发”一致)// 若要“低电平脉冲起始”为有效,可改成 FALLING(下降沿):// ic_cfg.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING;ic_cfg.ICSelection = TIM_ICSELECTION_DIRECTTI;     // 选择直连TI(CH2直接接到IC)ic_cfg.ICPrescaler = TIM_ICPSC_DIV1;               // 输入捕获不分频(不跳边)ic_cfg.ICFilter    = 0;                            // 不滤波(0~15 可选,>0 可做数字滤波,抗抖/毛刺)HAL_TIM_IC_ConfigChannel(&counter_handle, &ic_cfg, TIM_CHANNEL_2);/* ------------ 3. 配置从模式为“外部时钟模式1”(ECM1) ------------ */TIM_SlaveConfigTypeDef slave_cfg = {0};slave_cfg.SlaveMode        = TIM_SLAVEMODE_EXTERNAL1; // 外部时钟模式1:由触发输入驱动计数器时钟slave_cfg.InputTrigger     = TIM_TS_TI2FP2;           // 触发选择:TI2 的滤波后信号(来自CH2)slave_cfg.TriggerPolarity  = TIM_TRIGGERPOLARITY_RISING; // 触发极性:上升沿// 若改下降沿,对应改为 TIM_TRIGGERPOLARITY_FALLINGslave_cfg.TriggerPrescaler = TIM_TRIGGERPRESCALER_DIV1;  // 触发预分频(对触发边沿再做1/2/4/8分频)slave_cfg.TriggerFilter    = 0;                          // 触发滤波(通常对ETR有效;TIx滤波主看ICFilter)HAL_TIM_SlaveConfigSynchro(&counter_handle, &slave_cfg);/* ------------ 4. 使能通道与启动计数 ------------ */HAL_TIM_IC_Start(&counter_handle, TIM_CHANNEL_2);  // 使能CH2输入捕获(允许触发链路工作)HAL_TIM_Base_Start(&counter_handle);               // 打开计数器(CEN=1)。此后,每个外部有效边沿 => CNT+1
}/*** @brief  由HAL库自动回调:定时器输入捕获 MSP(底层)初始化* @note   在这里打开GPIO/TIM时钟,并把PA1配置成输入*/
void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim)
{if(htim->Instance == TIM2){GPIO_InitTypeDef gpio = {0};__HAL_RCC_GPIOA_CLK_ENABLE();  // 使能 GPIOA 时钟(PA1 在 A 口)__HAL_RCC_TIM2_CLK_ENABLE();   // 使能 TIM2 时钟/* TIM2_CH2 => PA1,配置为“输入”* F1系列定时器通道的复用是固定映射,无需设置AF功能号。* 建议上拉(PULLUP),让空闲时为高电平,这样外部“低脉冲”更清晰地产生一个“下降+上升”的边沿对。*/gpio.Pin   = GPIO_PIN_1;               // PA1gpio.Mode  = GPIO_MODE_INPUT;          // 输入模式(F1用这个即可;若是F4/07等系列可用GPIO_MODE_AF_PP/OD并上拉)gpio.Pull  = GPIO_PULLUP;              // 上拉:空闲=高,抗干扰gpio.Speed = GPIO_SPEED_FREQ_HIGH;     // 对输入影响不大,可保持高速HAL_GPIO_Init(GPIOA, &gpio);}
}/*** @brief  读取当前CNT,若变化则打印(与你原始逻辑保持一致)* @note   printf 可能阻塞,脉冲频率高时建议换成 count_get_delta() 方案做累计*/
void count_get(void)
{uint32_t new_cnt = __HAL_TIM_GET_COUNTER(&counter_handle);  // 读取TIM2->CNT(0..ARR循环)if (new_cnt != g_old_cnt)                                   // 仅在变化时打印,减少串口负担{g_old_cnt = new_cnt;                                    // 更新历史值printf("CNT: %lu\r\n", (unsigned long)new_cnt);         // 打印当前计数}
}/*** @brief  返回“自上次调用以来”的增量脉冲数,自动处理ARR回卷* @return 增量(0 表示期间无新脉冲)*/
uint32_t count_get_delta(void)
{uint32_t cur = __HAL_TIM_GET_COUNTER(&counter_handle);  // 当前CNTuint32_t inc;if (cur >= g_old_cnt) {inc = cur - g_old_cnt;                               // 常规情况:直接相减} else {inc = (g_arr + 1u - g_old_cnt) + cur;                // 回卷情况:先从old到ARR,再从0到cur}g_old_cnt = cur;                                         // 更新历史值return inc;
}

二、参数/函数逐点解释

1) ARR = 65536 - 1 为什么常这么写?

  • 计数范围是 0 … ARR,所以把 ARR=65536-1 等价于 0…65535(16位满量程)。

  • 你当然可以改成别的数(比如 9999),那就是 0…9999 后回卷。

  • 若想极大范围,TIM2 是 32 位定时器,可以把 ARR 设得更大(如 0xFFFFFFFF),但相应地:

    • CNTuint32_t 读取与存储;

    • 增量/回卷逻辑也按 32 位来处理。

2) PSC = 0

  • 预分频器对“计数时钟”再做一次分频,PSC=0 表示不分频。

  • 在外部时钟模式 1 下,“有效触发边沿”就是计数器时钟源;通常我们希望每个脉冲计一次,所以 PSC=0

3) TIM_SLAVEMODE_EXTERNAL1 + TIM_TS_TI2FP2

  • 外部时钟模式1(ECM1):把“触发输入(TRGI)”当作计数器时钟。

  • TIM_TS_TI2FP2:把 CH2 的滤波后输入(TI2FP2)选作“触发输入”。

  • 效果:PA1 上每来一次选定极性的有效边沿 => CNT + 1

4) 极性与滤波

  • ICPolarity=RISING / TriggerPolarity=RISING:上升沿触发(你现在的需求)。

  • 若你的外部脉冲是“低电平脉冲”(空闲高,短时拉低),一般脉冲开始是一个下降沿脉冲结束是一个上升沿

    • 你希望“每个低脉冲只记一次”,通常选其中一个边沿(比如上升沿或下降沿),二选一即可

    • 想在“低脉冲开始就计数”,把极性改成 FALLING

  • 滤波:

    • ICFilter(0~15)对 TIx 输入做数字滤波(多个采样一致才认为有效),可抑制毛刺/抖动。

    • 频率高且信号干净时设 0;有噪声/机械抖动时适当增大(但会降低最高可计频率)。

5) HAL_TIM_IC_StartHAL_TIM_Base_Start

  • HAL_TIM_IC_Start:打开通道的输入捕获功能(允许 TI2FP2 形成触发)。

  • HAL_TIM_Base_Start:真正使能计数器(CEN=1)。两者都要开。

三、脉冲计数原理(外部时钟模式1)

可以用一个简化方框图理解:

外部信号(到PA1=TIM2_CH2)│▼输入滤波(ICFilter) ──> 形成 TI2FP2(带滤波的CH2信号)│▼触发选择(TS=TI2FP2) ──> 触发极性(上升/下降沿) ──> “触发事件”│└─────────────> 设从模式为 External1:把“触发事件”当作计数器时钟│▼计数器 CK_CNT│▼CNT = CNT + 1  (每个有效边沿+1)
  • 核心思想:不是用内部APB时钟去“滴答”,而是把外部边沿当作“时钟脉冲”。

  • 因此 CNT 的步进频率 = 外部有效边沿频率(再考虑触发/IC分频)

  • 你要的是“低电平脉冲的次数”,那就选定某个边沿(比如脉冲结束的上升沿),每次出现就 CNT+1

1. TIM_HandleTypeDef.Init 的参数

这是定时器的基本配置部分。

counter_handle.Init.Prescaler = psc;
counter_handle.Init.Period = arr;
counter_handle.Init.CounterMode = TIM_COUNTERMODE_UP;
counter_handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  • Prescaler:预分频器 (PSC)

    • 0 ~ 0xFFFF

    • 实际计数频率 = 计数时钟 / (PSC+1)

  • Period:自动重装载寄存器 (ARR)

    • 定时器计数的上限,CNT 计到 ARR 后溢出回 0。

  • CounterMode:计数模式

    • TIM_COUNTERMODE_UP(向上计数)

    • TIM_COUNTERMODE_DOWN(向下计数)

    • TIM_COUNTERMODE_CENTERALIGNED1/2/3(中心对齐模式,常用于PWM)

  • ClockDivision:时钟分频(对内部时钟的进一步分频)

    • TIM_CLOCKDIVISION_DIV1

    • TIM_CLOCKDIVISION_DIV2

    • TIM_CLOCKDIVISION_DIV4

    • 通常用于滤波/死区计数。

2. TIM_IC_InitTypeDef 的参数

输入捕获通道配置。

ic_cfg.ICPolarity  = TIM_INPUTCHANNELPOLARITY_RISING;
ic_cfg.ICSelection = TIM_ICSELECTION_DIRECTTI;
ic_cfg.ICPrescaler = TIM_ICPSC_DIV1;
ic_cfg.ICFilter    = 0;
  • ICPolarity(极性)

    • TIM_INPUTCHANNELPOLARITY_RISING(上升沿)

    • TIM_INPUTCHANNELPOLARITY_FALLING(下降沿)

    • TIM_INPUTCHANNELPOLARITY_BOTHEDGE(双边沿)

  • ICSelection(选择)

    • TIM_ICSELECTION_DIRECTTI(直连输入 TIx → 通道)

    • TIM_ICSELECTION_INDIRECTTI(间接输入,另一通道)

    • TIM_ICSELECTION_TRC(触发控制器输入)

  • ICPrescaler(输入分频)

    • TIM_ICPSC_DIV1(每个有效边沿都计)

    • TIM_ICPSC_DIV2(每 2 个有效边沿计 1)

    • TIM_ICPSC_DIV4(每 4 个)

    • TIM_ICPSC_DIV8(每 8 个)

  • ICFilter(滤波)

    • 0 ~ 15,越大抗干扰能力越强,但能识别的最高频率下降。

    • 常用于抖动/毛刺信号。

3. TIM_SlaveConfigTypeDef 的参数

从模式配置,用于外部时钟/触发同步。

slave_cfg.SlaveMode        = TIM_SLAVEMODE_EXTERNAL1;
slave_cfg.InputTrigger     = TIM_TS_TI2FP2;
slave_cfg.TriggerPolarity  = TIM_TRIGGERPOLARITY_RISING;
slave_cfg.TriggerPrescaler = TIM_TRIGGERPRESCALER_DIV1;
slave_cfg.TriggerFilter    = 0;
  • SlaveMode(从模式)

    • TIM_SLAVEMODE_DISABLE(关闭从模式)

    • TIM_SLAVEMODE_RESET(触发信号使 CNT 复位)

    • TIM_SLAVEMODE_GATED(触发信号作为门控)

    • TIM_SLAVEMODE_TRIGGER(触发信号启动定时器)

    • TIM_SLAVEMODE_EXTERNAL1(外部时钟模式1,脉冲作为时钟源)← 你用的

  • InputTrigger(触发输入源)

    • TIM_TS_TI1FP1(通道1的滤波输入)

    • TIM_TS_TI2FP2(通道2的滤波输入)← 你用的

    • TIM_TS_ETRF(外部触发输入 ETR)

    • TIM_TS_ITR0~3(内部触发,用于定时器之间联动)

  • TriggerPolarity(触发极性)

    • TIM_TRIGGERPOLARITY_RISING

    • TIM_TRIGGERPOLARITY_FALLING

    • TIM_TRIGGERPOLARITY_BOTHEDGE

  • TriggerPrescaler(触发预分频)

    • TIM_TRIGGERPRESCALER_DIV1

    • TIM_TRIGGERPRESCALER_DIV2

    • TIM_TRIGGERPRESCALER_DIV4

    • TIM_TRIGGERPRESCALER_DIV8

  • TriggerFilter(触发滤波)

    • 0 ~ 15,抗干扰。

4. GPIO_InitTypeDef 的参数

IO 口配置(初始化 PA1)。

gpio.Pin   = GPIO_PIN_1;
gpio.Mode  = GPIO_MODE_INPUT;
gpio.Pull  = GPIO_PULLUP;
gpio.Speed = GPIO_SPEED_FREQ_HIGH;
  • Pin:选择引脚,如 GPIO_PIN_0 | GPIO_PIN_1

  • Mode:模式

    • GPIO_MODE_INPUT(输入)

    • GPIO_MODE_OUTPUT_PP(推挽输出)

    • GPIO_MODE_OUTPUT_OD(开漏输出)

    • GPIO_MODE_AF_PP(复用推挽)

    • GPIO_MODE_AF_OD(复用开漏)

    • GPIO_MODE_ANALOG(模拟输入)

  • Pull:上下拉

    • GPIO_NOPULL

    • GPIO_PULLUP

    • GPIO_PULLDOWN

  • Speed:输出速度(对输入无关)

    • GPIO_SPEED_FREQ_LOW

    • GPIO_SPEED_FREQ_MEDIUM

    • GPIO_SPEED_FREQ_HIGH

不同结构体对应不同的参数选择:

  • 计数器基本配置PrescalerPeriodCounterModeClockDivision

  • 输入捕获配置ICPolarityICSelectionICPrescalerICFilter

  • 从模式配置SlaveModeInputTriggerTriggerPolarityTriggerPrescalerTriggerFilter

  • GPIO 配置PinModePullSpeed

STM32 HAL 定时器常见配置参数速查表:每张表都包含:字段、可选宏/取值、含义/作用、常用场景示例(含你本l例“外部时钟模式1计数”的推荐值)。

TIM_Base 初始化(TIM_HandleTypeDef.Init

字段可选值/范围作用常用场景示例
Prescaler0 ~ 0xFFFF(F1)计数器预分频:计数时钟 = 输入时钟 / (PSC+1)外部时钟计数0(每个外部边沿+1);定时中断:按期望溢出频率计算
Period0 ~ 0xFFFF(F1,16位TIM);0~0xFFFFFFFF(32位TIM,如 TIM2/5)自动重装载(ARR),CNT 到 ARR 后回卷计数器满量程65535(写 65536-1);定时中断:按周期计算
CounterModeTIM_COUNTERMODE_UP / DOWN / CENTERALIGNED1/2/3计数模式计数/定时UPPWM中心对齐CENTERALIGNEDx
ClockDivisionTIM_CLOCKDIVISION_DIV1/2/4内部分频,影响数字滤波/死区采样一般 DIV1
RepetitionCounter*仅高级定时器(TIM1/TIM8)N 次更新后再触发一次更新事件高级PWM特殊应用

* F1 的 HAL 里 RepetitionCounter 通过 TIMx->RCR 访问,不总在 Init 中暴露。


输入捕获配置(TIM_IC_InitTypeDef

字段可选值/范围作用外部脉冲计数(ECM1)推荐频率/周期测量常用
ICPolarityTIM_INPUTCHANNELPOLARITY_RISING / FALLING / BOTHEDGE识别哪种边沿为有效视脉冲定义:每个脉冲只记一次 → 选 RISINGFALLING 之一测周期多用 RISING
ICSelectionTIM_ICSELECTION_DIRECTTI / INDIRECTTI / TRC通道输入选择DIRECTTI(TIx直连)DIRECTTI(两通道互联时另一路可用 INDIRECTTI
ICPrescalerTIM_ICPSC_DIV1/2/4/8边沿抽取分频DIV1(每个边沿都记)噪声多时可降采样
ICFilter0 ~ 15数字滤波(越大越抗抖,但最高可测频率下降)0 或小值;有毛刺时增大依输入噪声设定

从模式/触发配置(TIM_SlaveConfigTypeDef

字段可选值/范围作用外部脉冲计数(ECM1)推荐其他常见用途
SlaveModeDISABLE / RESET / GATED / TRIGGER / EXTERNAL1从模式选择TIM_SLAVEMODE_EXTERNAL1(外部时钟模式1)主从同步TRIGGER/RESET门控GATED
InputTriggerTIM_TS_TI1FP1 / TI2FP2 / ETRF / ITR0~3触发源选择(TRGI)TIM_TS_TI2FP2(CH2 触发)定时器联动ITR0~3外部脚ETRF
TriggerPolarityRISING / FALLING / BOTHEDGE触发极性ICPolarity 对应选一个边沿即可同步/门控时按边沿需求
TriggerPrescalerDIV1/2/4/8触发预分频DIV1降低触发频率
TriggerFilter0 ~ 15触发滤波0 或小值抗干扰

备注:ECM1 实际计数由 TRGI 驱动,TRGI 又来自 InputTrigger 选定的源(如 TI2FP2),因此 IC 配置 + 从模式配置 两部分要匹配。


主模式(触发输出)配置(TIM_MasterConfigTypeDef

字段可选值/范围作用常用场景
MasterOutputTriggerTIM_TRGO_RESET / ENABLE / UPDATE / OC1 / OC1REF / OC2REF / OC3REF / OC4REF决定 TRGO 输出的事件多定时器同步:用 UPDATE 让别的TIM以此为触发
MasterSlaveModeTIM_MASTERSLAVEMODE_ENABLE/DISABLE使能主从模式(便于同步)级联/同步启动等

通道级(输出比较/PWM)配置(TIM_OC_InitTypeDef)—(若你做PWM会用到)

字段可选值/范围作用常用场景
OCModeTIM_OCMODE_TIMING / ACTIVE / INACTIVE / TOGGLE / PWM1 / PWM2 / FORCED_ACTIVE / FORCED_INACTIVE通道输出模式PWM1/PWM2 生成PWM
Pulse0 ~ ARRCCRx,占空比占空比 = CCR / (ARR+1)
OCPolarityTIM_OCPOLARITY_HIGH/LOW有效电平极性反相输出时选 LOW
OCFastModeENABLE/DISABLE快速比较特殊应用

外部触发输入(ETR)/ 外部时钟模式2(了解即可)

可选值/范围说明
外部时钟模式2HAL_TIM_ConfigClockSource(..., TIM_CLOCKSOURCE_ETRMODE2)通过 ETR 脚作为时钟源(与 ECM1 不同路径)
ETR 极性/滤波/预分频TIM_ETRPOLARITY_NONINVERTED/INVERTEDTIM_ETR_PRESCALER_DIV1/2/4/8TIM_ETR_FILTER 0~15当使用 ETR 时可单独配置

GPIO 初始化(GPIO_InitTypeDef,与定时器通道配合)

字段可选值/范围作用外部脉冲计数建议
PinGPIO_PIN_x选择引脚例:GPIO_PIN_1(TIM2_CH2=PA1)
ModeINPUT / AF_PP / AF_OD / OUTPUT_PP / OUTPUT_OD / ANALOG引脚模式F1 用输入模式GPIO_MODE_INPUT)接外部信号
PullPULLUP / PULLDOWN / NOPULL上下拉建议 PULLUP,空闲为高,低脉冲清晰
SpeedLOW/MEDIUM/HIGH输出速率对输入影响不大,可 HIGH

常见“目标任务”推荐配置(速查)

目标关键配置备注
外部脉冲计数(ECM1)IC: Polarity=RISING(或FALLING), Selection=DIRECTTI, Prescaler=DIV1, Filter=0~NSlave: Mode=EXTERNAL1, Trigger=TIxFPx(与你用的通道对应), TriggerPolarity=同上, TriggerPrescaler=DIV1, TriggerFilter=0~NPSC=0, ARR=期望满量程你这题:TIM2_CH2→TI2FP2,上升沿记一次脉冲
定时中断(TimeBase)SlaveMode=DISABLE;根据目标周期设置 PSC/ARRHAL_TIM_Base_Start_IT常用来做固定周期任务
PWM 输出OC: Mode=PWM1/2, Pulse=CCR, Polarity=HIGHPSC/ARR 设置PWM频率;HAL_TIM_PWM_Start频率 = TimerClk / (PSC+1) / (ARR+1);占空比 = CCR/(ARR+1)
频率/占空比测量(PWM输入模式)HAL_TIM_PWM_ConfigChannel / HAL_TIM_IC_ConfigChannel(成对配置) + HAL_TIM_...PWM 输入模式(或两通道互联)用一通道测周期,另一通道测高电平宽度

计算方法:

  • 内部时钟定时模式

    • 计数频率 f_cnt = f_tim / (PSC+1)

    • 溢出频率 f_ov = f_cnt / (ARR+1)周期 T = (PSC+1)*(ARR+1)/f_tim

  • 外部时钟模式1(ECM1)

    • 计数步进由触发有效边沿决定:f_cnt ≈ f_edge / (ICPrescaler * TriggerPrescaler)(忽略滤波饱和)

  • PWM

    • PWM 频率 f_pwm = f_tim / (PSC+1) / (ARR+1)

    • 占空比 D = CCR / (ARR+1)

http://www.xdnf.cn/news/1319977.html

相关文章:

  • Docker之自定义jkd镜像上传阿里云
  • 排列组合+数量+资料
  • 25. 能否创建一个包含可变对象的不可变对象
  • 编程算法实例-Armstrong数(阿姆斯特朗数)
  • IDE/去读懂STM32CubeMX 时钟配置图(有源/无源晶振、旁路/晶振模式、倍频/分频)
  • 负载测试与压力测试详解
  • Rust Async 异步编程(五):执行器和系统 I/O
  • Spring 创建 Bean 的 8 种主要方式
  • MXFP4量化:如何在80GB GPU上运行1200亿参数的GPT-OSS模型
  • 【SpringBoot】Swagger 接口工具
  • 如何在Windows系统中更改用户名(中文转英文全流程)
  • 云原生俱乐部-RH134知识点总结(2)
  • MySQL数据库备份与恢复
  • neo4j导入导出方法
  • 25年第十本【金钱心理学】
  • 半敏捷卫星观测调度系统的设计与实现
  • 《WINDOWS 环境下32位汇编语言程序设计》第3章 使用MASM
  • Effective C++ 条款46:需要类型转换时请为模板定义非成员函数
  • Critic-V: VLM Critics Help Catch VLM Errors in Multimodal Reasoning(CVPR 2025)
  • 飞算AI 3.2.0实战评测:10分钟搭建企业级RBAC权限系统
  • 【牛客刷题】求四个数的最小公约数:两种高效解法详解(枚举法和最大公约数法)
  • 华为云之Linux系统安装部署Tomcat服务器
  • 【技术博客】480p 老番 → 8K 壁纸:APISR × SUPIR × CCSR「多重高清放大」完全指南
  • YoloV9改进策略:Block改进-DCAFE,并行双坐标注意力机制,增强长程依赖与抗噪性-即插即用
  • 【Golang】:函数和包
  • HTTPS 配置与动态 Web 内容部署指南
  • 数组实现各类数据结构
  • 创建工作空间与功能包
  • nodejs 中间件
  • 科目二的四个电路