主题中讨论的其他器件:TM4C123、
你好
需要输入边沿定时器采样源代码。
Peripherals 文件夹中没有示例文件。 ( EDGE_COUNT、 OneShot_16位、 Periode_16位、 PWM)
我需要 EDGE_TIME 示例文件。
谢谢
[附加所需配置的图像]
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
你好
需要输入边沿定时器采样源代码。
Peripherals 文件夹中没有示例文件。 ( EDGE_COUNT、 OneShot_16位、 Periode_16位、 PWM)
我需要 EDGE_TIME 示例文件。
谢谢
[附加所需配置的图像]
[引用 user="Jame shin"]我需要没有错误的示例代码。
申先生-谁在这里不是"不是"-只寻求这样的东西? 然而、最常见的情况是、"请求此类"无错"代码"需要投入所需的时间、精力和试用时间来满足这一严格要求! 这并不是说你没有作出太多努力,但你(没有)还没有达到你的目标,它是否"完全落在你的身上",而是投入更多的努力,追求"代码完美"? 我很肯定供应商的查尔斯已经作出了"最大努力"-谢谢蔡先生-很可能你会"融合"你的目标。
在该参考帖子中、我负责建议简化和加速(始终)由"kiss"得出的结果。 在这个特定情况下-我选择了两个定时器引脚-一个在上升沿中断-另一个在下降沿中断。
有两个重要的 PWM 测量参数:PWM 频率(或其反向、周期)和占空比。 占空比可由应用定义-但大多数情况下、占空比通常表示相对于 PWM 周期进行缩放的"活动时间百分比"。
虽然您的绘图很好-但它(对我而言)出现错误。 在图表中、占空比是波形中处于/接近逻辑高电平的部分、然后由信号周期"缩放"! (即占空比=信号的时间"高电平"/信号的周期) PWM 周期是背靠背(如极性)信号边沿之间的时间。 (由绘图中的"T"指定) 绘图忽略"信号的时间高电平与信号周期"之间所需的比例)
如果您的目标是最高精度、则最好捕获"n"类"相似极性"信号边沿之间的"时间增量"、这将降低"计时抖动"对测量的影响。 (然后、您可以将该"总持续时间"除以"n"、以确定信号的周期。)
此类 MCU 和紧密耦合的 IDE 系统的优势在于能够执行此类代码开发实验。 您需要的"反馈"是即时的-这使您能够系统地实现" Jame 创建的代码"的(更恰当的)目标-(当然)没有错误!"
James、您是时候开发"无错"代码了、并在这里为您的"帮助者"提供代码了。
[引用 user="Jame shin"]我想获取示例代码。
[引用 user="Jame shin"]我需要没有错误的示例代码。
认真???
TI 是否曾向您承诺/宣传他们将销售微控制器并为您的应用制定计划?
在这里至关重要不会有什么帮助、但如果这就是开发产品所需的一切、 那么楼下的女士为您提供咖啡是一个严肃的竞争对手、Jame shin。
如果您不理解使用两个计时器测量一个 PWM 信号的令人振奋的解决方案之外的原因、我建议您进一步研究它... 或者提供咖啡的女士可能也会得到位置...
布鲁诺
您好、Charles、 
还应注意的是、"两计时器"方法(从我之前的建议"kiss"中"跳过")证明编程和实施要简单得多且更快-并且(始终)应该是一个很好的考虑因素。   "绝对优化"的时间不是在"首次通过代码开发"期间、而是仅在"经证明"任何此类"优化"都能满足"实际需求"或产生可衡量的"节省"时尝试。   (因此有理由要求额外的时间/精力/费用。) 
我写了一个计时器捕获了"上升沿"、第二个"下降沿"、但 Jame 对此很清楚、他的"未命中"可能表示 详细的"辅助响应"的"几个较慢的读数"将会证明是有用的。 
同样、"要求"的"无错误"代码非常不寻常-不属于此"任何"论坛的目的和意图!  每个/每个论坛用户都必须为此目的利用(他们自己的)时间/努力/努力!      这不是"命令"和/或"命令"的事情、这似乎是海报的(不当和/或误解)欲望... 
查尔斯。
返回到第一个问题
我有两个担心。
1. 无法读取设置的时间模块的时钟?
printf 语句的顺序取决于中断例程的位置。
如何更改?
谢谢。
[附加的图像]
[示例源代码]
-它是从 TI 示例源修改的。
//
//
//// EDGE_COUNT.c -定时器边沿计数模式示例。
//
//版权所有(c) 2013-2015 Texas Instruments Incorporated。 保留所有权利。
//软件许可协议
//
以源代码和二进制形式重新分发和使用,无论是否
进行//修改,只要
满足以下条件//:
//
重新分发源代码必须保留上述版权
//声明、此条件列表和以下免责声明。
//
//二进制形式的再发行必须复制上述版权
//声明、此条件列表和//
分发随附的//文档和/或其他材料中的以下免责声明。
////
未经
事先书面许可,不能使用德州仪器公司的名称或//其贡献者的名称来认可或推广源自此软件的产品//。
////
本软件由版权所有者和贡献者提供
//“按原样”,不
承认任何明示或暗示的保证,包括但不限于//适销性和对//特定用途适用性的暗示保证。 在任何情况下、版权
//所有者或贡献者都不对任何直接、间接、偶然、
//特殊、模范、 或相应的损害(包括但不
限于采购替代产品或服务;丧失使用、
//数据或利润; 或业务中断)、无论
出于何种原因使用
本软件(即使被告知可能会造成此类损坏)、还是出于任何原因而产生的任何//责任理论(无论是合同、严格责任还是侵权行为)//(包括疏忽或其他)。
//
//这是 Tiva 固件开发包的修订版本2.1.2.111的一部分。
////
*****************
#include 
#include 
包含"inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/debug.h"
#include "driverlib/fpu.h"
#include "driverlib/interrupt.h"#include
"driverlib/driverlib#driverlib.driver.h"
#include "driverlib#driverlib/drivers.util.h"#include "driverlib#drivers.md.lib.driverlib.drivers/drivers.drivers.drivers.drivers/drivers.ide"#include "drivers.lib#include "drivers/driverlib#include "drivers.lib#include "drivers.lib"#drivers.util.md.md.md.lib"#include "drivers.util.lib.md.status"#include "drivers/drivers.md.util.lib#include "drivers.status"#include "drivers.dlpin.md.dlpin.md.lib#include "drivers.util.r.lib. 显示屏。
uint32_t g_ui32Flags;
//指示计时器递减计数器达到的频率的中断计数器
volatile uint32_t g_ui32IntCount;
//用于绘制显示的图形上下文。
tContext g_sContext;
//用于字符串格式化的缓冲区。
#define PRINT_BUK_SIZE 8.
char g_pPrintBuff[print_buff_size];
void
InitConsole (void)
{
//启用用于 UART0引脚的 GPIO 端口 A。
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);
//启用 UART0以便我们可以配置时钟。
SysCtlPeripheralEnable (SYSCTL_Periph_UART0);
GPIOPinConfigure (GPIO_PA0_U0RX);
GPIOPinConfigure (GPIO_PA1_U0TX);
//使用内部16MHz 振荡器作为 UART 时钟源。
UARTClockSourceSet (UART0_BASE、UART_CLOCK_PIOSC);
//为这些引脚选择替代(UART)功能。
GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_0 | GPIO_PIN_1);
//初始化控制台 I/O 的 UART
UARTStdioConfig (0、115200、16000000);
}
void
ProcessInterrupt (void)
{
//
//更新中断计数器。
//
G_ui32IntCount++;
//
//切换中断标志,告知主循环更新显示。
//
//HWREGBITW (&g_ui32Flags、0)^= 1;
HWREGBITW (&g_ui32Flags、1)^= 1;
}
//初始化显示。 此函数特定于 EK-LM4F232电路板
void
InitDisplay (void)
{
tRectangle sRect;
//初始化显示驱动程序。
CFAL96x64x16Init();
//初始化图形上下文并查找中间的 X 坐标。
GrContextInit (&g_sContext、&g_sCFAL96x64x16);
//用蓝色填充屏幕顶部以创建横幅。
sRect.i16XMin = 0;
sRect.i16YMin = 0;
sRect.i16XMax = GrContextDpyWidthGet (&g_sContext)- 1;
sRect.i16YMax = 9;
GrContextForegroundSet (&g_sContext、ClrDarkBlue);
GrRectFill (&g_sContext、&sRect);
//更改白色文本的前景。
GrContextForegroundSet (&g_sContext、ClrWhite);
//将应用程序名称放在横幅中间。
GrContextFontSet (&g_sContext、g_psFontFixed6x8);
GrStringDrawCenter(&g_sContext,"edge-count",-1,
GrContextDpyWidthGet (&g_sContext)/ 2、4、0);
//初始化计时器状态显示。
GrContextFontSet (&g_sContext、g_psFontFixed6x8);
GrStringDraw (&g_sContext、"Countdown:"、-1、8、26、 0);
GrStringDraw (&g_sContext、"interrupts:"、-1、8、36、 0);
}
void
MainLoopRun (void)
{
uint32_t ui32Count、ui32LastCount;
//为主循环设置。
ui32LastCount = 1;
//在计时器运行时永久循环。
while (1)
{
//获取当前计时器计数。
ui32Count = ROM_TimerValueGet (TIMER4_base、timer_A);
if (ui32Count!= ui32LastCount)
{
//更新显示。
usnprintf (g_pcPrintBuff、print_buff_size、"%d "、ui32Count);
GrStringDraw (&g_sContext、g_pcPrintBuff、-1、80、26、 true);
//记住新的计数值。
ui32LastCount = ui32Count;
UARTprintf ("按钮 CNT =%d \n"、ui32Count);
}
//自我们上次检查以来是否有中断?
if (HWREGBITW (&g_ui32Flags、1))
{
//清除该位。
HWREGBITW (&g_ui32Flags、1)= 0;
//更新中断计数。
usnprintf (g_pcPrintBuff、print_buff_size、"%d "、g_ui32IntCount);
GrStringDraw (&g_sContext、g_pcPrintBuff、-1、80、36、 true);
UARTprintf ("INT-Count =%d \n"、g_ui32IntCount);
// UARTprintf ("g_ui32Flags =%x \n"、&g_ui32Flags);
}
}
//
计时器4的中断处理程序。
void
Timer4IntHandler (void)
{
//清除计时器中断。
ROM_TimerIntClear (TIMER4_base、TIMER_CAP_MATCH);
ProcessInterrupt();
//定时器在达到匹配值时自动停止,因此在此处重新启用它。
ROM_TimerEnable (TIMER4_base、timer_A);
}
int
main (void)
{
//rom_FULazyStackingEnable();
//rom_SysCtlClockSet (SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
// SYSCTL_XTAL_16MHz);
ROM_SysCtlClockSet (SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
SYSCTL_XTAL_16MHz);
//计时器 Mourdle (Timer A 和 Timer B)时钟源集
// TimerClockSourceSet (TIMER4_base、TIMER_CLOCK 系统);
//初始化板上的显示。
InitDisplay();
// UART Func Call
InitConsole();
UARTprintf ("\nSYSCLK =%d Hz\n"、SysCtlClockGet ());
//启用 Timer4和 GPIOM
ROM_SysCtlPeripheralEnable (SYSCTL_Periph_TIMER4);
ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOM);
//将 PM0配置为计时器4的 CCP0 (计时器 A)引脚。
ROM_GPIOPinTypeTimer (GPIO_PORTM_BASE、GPIO_PIN_0);
GPIOPinConfigure (GPIO_PM0_T4CCP0);
//将引脚设置为使用内部上拉电阻。
MAP_GPIOPadConfigSet (GPIO_PORTM_BASE、GPIO_PIN_0、
GPIO_Strength _2mA、GPIO_PIN_TYPE_STD_WPU);
//启用处理器中断。
ROM_IntMasterEnable();
//将定时器配置为边沿计数模式。
///rom_TimerConfigure (TIMER4_base、(TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_CAP_COUNT));
ROM_TimerConfigure (TIMER4_base、(TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_CAP_COUNT_UP));
ROM_TimerControlEvent (TIMER4_base、TIMER_A、TIMER_EVENT_POS_EDGE);
ROM_TimerLoadSet (TIMER4_base、TIMER_A、15);
//ROM_TIMERLoadSet (TIMER4_base、TIMER_A、9);
ROM_TimerMatchSet (TIMER4_base、TIMER_A、15);
//ROM_TimerMatchSet (TIMER4_base、TIMER_A、0);
//设置边沿捕获计时器的中断。 请注意
、我们//使用捕获匹配中断、而不是超时中断!
ROM_IntEnable (INT_TIMER4A);
ROM_TimerIntEnable (TIMER4_base、TIMER_CAP_MATCH);
//计时器 Mourdle (Timer A 和 Timer B)时钟源设置
TimerClockSourceSet (TIMER4_base、TIMER_CLOCK 系统);// TIMER_CLOCK _PIOSC 或 TIMER_CLOCK 系统
//启用计时器。
ROM_TimerEnable (TIMER4_base、TIMER_A);
//计时器模块源时钟
UARTprintf ("TimerClk =%d Hz \n"、TimerClockSourceGet (TIMER4_base)));
//此时,计时器将在每次在相关引脚上检测到负边沿时递增计数。
MainLoopRun();
}
Jame、您好!
您对这些图表以及您的理解做了很好的工作。 干得不错! 还有几条有助于您实现目标的提示:
1 -如果没有明确说明、您的计时器将需要同步运行。 以下是有关它的主题、作为指导:
2 -您不必永久监控主循环中的计时器值、只需让中断为您执行该操作即可。 这是一个想法(这未经测试、只是将其作为示例编写...)
void Timer1A_ISR (void) { uint32_t ui32Status; ui32Status = ROM_TimerIntStatus (Timer1_base、true); TimerIntClear (Timer1_base、ui32Status); IF (ui32Status & timer_CAP_event) { pwmRisingCountLast = TimerValueGet (Timer1_base、timer_A); flagNewCountAvailable= true; } }
3 -当然、另一个计时器也是如此
4 -在主循环内、您只能在需要时进行新的计算。 如下所示:
while (1) { IF (可使用的标志 NewCountAvailable) { MakeCalculations(); flagNewCountAvailable= false; } }
5 -对于计算、您需要注意的是、16位计时器实际上比预期的周期小(除非您希望将信号连接到两个32位计时器、这是一个好主意)
void MakeCalculations (void) { /* *周期=时钟差 pwmRisingCountLast - pwmRisingCountPrevious, 但考虑了翻转和计时器宽度 * /* * dutywidth =时钟差 pwmFallingCountLast - pwmRisingCountPrevious, *同时还会缩小翻转和宽度 * 占空比= dutywidth / period; pwmRisingCountPrevious= pwmRisingCountLast; }
6 -如果您通过 UART 在控制台上或屏幕上看到您的值、那么每秒看到1000次就没什么意义了。 因此、您可能需要确定一个更方便的时刻来发送当前结果。 此外、您可能还需要对读数进行一些滤波或取平均值、具体取决于您的传感器是什么。
顺便说一下、您使用什么编辑程序来创建这些原理图?
此致
布鲁诺
***类似*** 
(注意:单次、良好消抖、如此处实现的开关...) 非常好的解释-海报(插图)可能会影响他的基本思考过程... 
与计时器进行简单的实验应该澄清-海报中"额外太多"的介绍使他偏离了他的"中心任务"。 (认为"外科手术"-相关区域是"清晰的"-所有其他的都是"被"堆成"的-因此焦点是"在问题上(组织)被强迫"-而不是多余的!)
当然-这证明了 kiss 的另一个例子-在这里最常"踢到路边"。。 (以不必要的"痛苦/痛苦"为代价。)
Jame Shin、您好!
[引用 user="Jame shin"] 
UARTprintf ("TimerClk =%d Hz \n"、TimerClockSourceGet (TIMER4_base))[/quot] 
Bruno 正确地说、语法 仅返回用于 GPTM 模块的源时钟、而不是相对于 源时钟时间的计数器寄存器值。
因此、我们必须在中断后读取 GPTM 寄存器计数、以获取边沿时间检查的值。 数据表详细介绍了每个 GPTM 配置 模式、但 文档 GPTM 勘误表可能会影响方法或计数方向、具体取决于使用情况。 请务必查看勘误文档以了解受影响的 GPTM 模式。
下面、我们计算 GPTM 匹配计数中断触发一次性计时器后的边沿计数、该计时器在 1秒的间隔内触发计时器。 输入中断后处理程序内特定语法点的类似计算可通过边沿计时器寄存器来完成。 我们真的不关心 上升/下降信号边沿时间 进入 NVIC 中断控制器、而只关心 软件可以通过硬件的寄存器值连接此时间。 不必担心边沿时间 NVIC 对1kHz PWM 输入的响应速度(不是如此相对)、而是考虑计数器捕获和记录所述时间相对于寄存器值和匹配 中断时间的能力。
/*获取 GPTMTBV 自由运行计数值。 // ui32TBVEdgeCount = HWREG (TIMER0_BASE + TIMER_O_TBV); //获取 GPTMTBILR 电流匹配边沿计数*/ ui32TBILREdgeCount = HWREG (TIMER0_BASE + TIMER_O_TBILR); //确定上升到 32TB iEdgeCount 的边沿总数= HWREG (TIMER0_BASE + TIMER_O_TBILR);//确定32 uGB)
Jame、您好!
很抱歉耽误你的回答。 Bruno 所说的是、API 只是返回寄存器值、该值指示时钟源是什么、而不是时钟源的频率。 请查看读取计时器控制寄存器以返回 API 函数的 API 函数。
uint32_t TimerClockSourceGet (uint32_t ui32Base) { // //检查参数。 // assert (_TimerBaseValid (ui32Base)); // //返回计时器时钟源。 // return (HWREG (ui32Base + TIMER_O_CC));
[引用用户="Jame shin"]x2时间= 12.5ns x 79992个周期(计数衰减)= 999.9us [/引用]
不在这里,也不是现在! "科学符号"和轻微的"四舍五入"是否有帮助?
[编辑] Whoops -发誓我看到该周期编号为7992 -请(现在)看到它不是。 在"sci 表示法"和"舍入"列表中、必须添加"视力"(或清醒)。
µs:(1.25 * 10 ^-8)*(8 * 10 ^ 4)= 10 ^-4 = 0.001000、即1000 μ s! 此类(信封背面)"快速校准"通常可避免"数量级"错误(但不能避免数字误读)。
Jame、您好!
[引用 user="Jame shin"]在所附的图像中,请解释为什么计时器时钟至少是输入信号的4倍?
GPTM 源时钟不必运行 SYSCLK 速度、并且可以 根据应用使用 PIOSC 16MHz 内部精密时钟源为计时器提供62.5ns 的时钟周期。
很抱歉、您的边沿时间示例软件请求令人困惑、 您似乎 是在请求计算上升边沿时间、而 不是在两个不同边沿之间专门串联时间、这与上升边沿时间无关。 为了保持简单、 尝试使用 公式1/F 来计算 CCP 输入的边沿时间、将其作为相对于 SYCLK 或 PIOSC 的 GPTM 节拍总数 不确定为什么在24位边沿定时器 应轻松确定 单个输入信号相对于 GPTM 定时器节拍的频率时需要使用两个 CCP 输入中断。
数据表 使用中有一个公式来确定 GPTM 源时钟速率相对于 可能 需要测量的 CCP 输入频率 GPTM。
BTW 1kHz = 1ms 不会。
为供应商的 Charles 辩护-我们不知道他如何"写得更清楚!"
您的绘图可能包含太多-从而使思考过程不堪重负吗?
Charles 描述了两个定时器的用法-一个定时器配置为捕获上升沿-另一个定时器配置为捕获下降沿。 输入信号路由到两个定时器引脚。 (即它是同一信号)
您会询问"如何在这两个计时器之间实现"同步"。 这是一个标准函数-可在 API 中使用-未知您"错过"了什么。
两个计时器方法的"美"是其简单性-正如 Charles (清晰地)所写的那样-"两个计时器的锁存值之间的差异"是您的 x1"。
Jame、您好!
我准备了一个简单的示例、演示如何使用两个计时器来计算占空比。 我测量的占空比为1kHz PWM 的0.01%。 计时器 正确测量占空比。 您需要修改/适应您的应用。 此示例调用 TimerSynchronize (TIMER0_BASE、TIMER_0A_SYNC|TIMER_0B_SYNC)来同步两个计时器。 但是、由于 timerA 和 timerB 共享相同的时基、因此不需要同步、但如果您计划在不同的计时器发生器之间使用、则需要进行同步。 对于 TIMER0中使用的 timerA 和 timerB、在同步或不同步的情况下、我看不到占空比有任何差异。
e2e.ti.com/.../3124.tm4c123_5F00_timer_5F00_edge_5F00_time_5F00_mode.zip
Jame、您好、
首先、我建议您将工程图的一部分更改为两个计时器、以将真实信号表示为实际信号。 在一些地方、您已经将偏移信号拉到计时器 A 和 B 中。我拖动其中一个信号来表示实际发生的情况、这样其他读取器就不会被误导:
接下来、要回答您的问题:
a)中断例程需要多少个周期?
您可以信赖以下几种方式:
1)通过外部测量时间:将 GPIO 引脚配置为输出、在您要测量的代码块之前、将其升高到高电平;在模块之后、将其升高到低电平。 在示波器中看到信号。 时间差是这些指令执行的周期、加上提升和降低 GPIO 的命令(TOTAL_CYCLES)。 然后、使用彼此相邻的相同升高/降低指令、并测量该时间量(翻转周期)。 如果从总计中减去切换周期时间、则会得到已研究周期时间。 请注意、代码优化将对其产生影响、因此您可以在 OPTIM 关闭的情况下测量最坏的情况。
2) 2)查看完整块的汇编代码、并手动添加每个汇编指令所采用的指令周期。
3) 3)不使用 GPIO、而是将宽定时器配置为以系统时钟为源连续运行。 在代码块之前、读取自由运行的定时器值。 在代码块之后、再次执行它。 请注意周期差异。 与 GPIO 概念一样、减去两个相邻定时器读取指令所花费的周期数。
4) 4)一些功能更强大的 IDE 具有告诉您给定块需要多少个周期的功能。
b)系统可以测量的最大检测周期是多少:
我想说这是一个很好的问题、您可以计算并回答。 鉴于此主题对计时器进行了广泛的研究、您是否同意将此答案作为最终练习? 进行数学计算并在此处提出答案、我相信我们能够查看并在需要时指导纠正。
布鲁诺
***类似***显著-您的(赦免)“基于 kiss 的”绘图提供的简单性! 好的。
有时需要将刚开始的人从巢中“推”出来。   (妈妈鸟很好@—论坛民间——也许,“不是那么多……” 
任何标题为"我需要"的帖子显示对"所有其他人"的关心/关注极小-并且由于 API 中列出/描述了"计时器同步功能"-但 "逃避了"需要"的注意-大部分宣称的"需要"是自引起的-这是否不正确?    不适当的"手持"可能会导致跳蚤的"永不离开!"    (在"鸟类和论坛"王国中都是不明智的...) 
[引用 user="Jame shin"]我认为我需要至少8个周期来处理 ISR 跳转。
常见误解:新程序员往往会混淆 TimerValueGet ()返回的值。 这可以是部分(完全?) TivaWare 用户指南的责任、其中指出:
'此函数读取指定定时器的当前值。' 这是不真实的! 该函数的代码为:
return ((ui32Timer==定时器_A)? HWREG (ui32Base + TIMER_O_TAR):HWREG (ui32Base + TIMER_O_TBR);
寄存器 TIMER_O_TAR (或换句话说、GPTM_TAR)完整说明:
'在输入边沿计数和时间模式之外的所有情况下、该寄存器显示 Timer A 计数器的当前值。 在输入边沿计数模式中、该寄存器包含已经发生的边沿数。 在输入边沿定时模式中、该寄存器包含上一次边沿事件发生的时间"
系统进入 ISR 所需的周期数无关紧要。 当您到达那里并获得计时器值时、此值将反映发生信号转换的"旧"瞬间。
布鲁诺
Jame、您好!
1) 1)我从未说过、进入中断需要8个 CPU 周期。 我将您的应用用例(1kHz 输入 PWM)作为参考、并尝试推导出占空比为0.01%(即8个 CPU 周期)时将有多少个周期。 然后我说过、如果 CPU 在检测到下一个边沿之前处理中断、然后覆盖尚未被 CPU 读取的捕获值、则8个周期将过短。 如果您想测量 CPU 进入 ISR 所需的周期数、这就是我的建议。 您使用相同的上升沿中断。 当检测到边沿时、时间戳被保存到 GPTMTAV 中、在 ISR 内的第一条指令中、你将立即读取 GPTMTAR 寄存器。 GPTMTAR 是自由运行计数器。 这两个寄存器之间的差异大致是进入 ISR 所需的时间。 请注意、Bruno 也有很好的建议。
2) 2)最大周期取决于您的源时钟频率以及您使用的是16位、24位、32位还是48位。 您只需将 CPU 时钟周期乘以所使用的计时器分辨率。