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.

[参考译文] TM4C1231H6PZ:捕获和比较计时器计算零导通时间

Guru**** 2330840 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/594540/tm4c1231h6pz-capture-and-compare-timer-calculating-zero-on-time

器件型号:TM4C1231H6PZ

您好!

我正在使用捕获和比较计时器计算输入信号的周期和导通时间。 我有两个输入碰巧连接到 WT4CCP0和 WT4CCP1。 我的两个通道同时监控输入信号。 WT4CCP0无错误地计算信号参数。 WT4CCP1在大多数情况下运行良好、但会定期计算0导通时间。 我在计时器 ISR 中计算了导通时间。 我随附了此代码。 是否有人可以看到可能产生此错误的代码有任何问题?  

void Wide Timer_4_subtimer_B_ISR (void){

ROM_TimerIntClear (WTIMER 4_base、TIMER_CAPB_EVENT);

IPC_Properties[6].IPC_Edge = ROM_GPIOPinRead (GPIO_PORTD_BASE、GPIO_PIN_5)>> 5;

if (IPC_Properties[6]。IPC_Edge = 1){
IPC_Properties[6]。IPC_TimerPrev = IPC_Properties[6]。IPC_Timer;
IPC_Properties[6].IPC_Timer = ROM_TimerValueGet (WTIMER 4_base、timer_B);
}
否则{
IPC_Properties[6].IPC_TimerFling = ROM_TimerValueGet (WTIMER 4_base、Timer_B);
IPC_Properties[6]。IPC_OnTime = IPC_Properties[6]。IPC_TimerFling - IPC_Properties[6]。IPC_Timer;
}

TMR_StartExpirationTimerMS (&IPC_Properties[6]。IPC_Shutoff、1000);

ROM_TimerEnable (WTIMER 4_base、IPC_Properties[6].IPC_TimerConfig);
}

void Wide Timer_4_subtimer_A_ISR (void){

ROM_TimerIntClear (WTIMER 4_base、TIMER_CAP_EVENT);

IPC_Properties[8]。IPC_Edge = ROM_GPIOPinRead (GPIO_PORTD_BASE、GPIO_PIN_4)>> 4;

if (IPC_Properties[8]。IPC_Edge =1){
IPC_Properties[8]。IPC_TimerPrev = IPC_Properties[8]。IPC_Timer;
IPC_Properties[8].IPC_Timer = ROM_TimerValueGet (WTIMER 4_base、timer_A);
}
否则{
IPC_Properties[8]。IPC_TimerFling = ROM_TimerValueGet (WTIMER 4_base、timer_A);
IPC_Properties[8]。IPC_OnTime = IPC_Properties[8]。IPC_TimerFling - IPC_Properties[8]。IPC_Timer;
}

TMR_StartExpirationTimerMS (&IPC_Properties[8]。IPC_Shutoff、1000);


ROM_TimerEnable (WTIMER 4_base、IPC_Properties[5]。IPC_TimerConfig);
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您的代码在子计时器 A 和 B 之间正确并联。  当您大部分时间报告"正常性能"时-这种情况出现(除了编码问题)。

    作为一项简单的测试-"问题"是否会移动您是否应该"反向"输入信号?   这证明有点具有启发性-不是吗?

    这些信号的频率和潜在重叠是无法描述的。   此类信号"重叠"(与单个中断优先级和/或响应时间相结合)是否可能证明是负责任的?

    您可以"交叉连接"一个信号源-这样您的两个计时器输入都是"常用驱动"-并观察结果。

    也许我的"最佳"诊断想法-将有问题的通道路由到第二个(独立)计时器(通过同一输入信号驱动2个计时器)-这样会触发额外的中断-并注意问题是否会流向添加的计时器...

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    第一公里、

    让我对您的规范和策略做一些观察、也许它们会有所帮助:

    -避免清除特定的中断触发器、如 TimerIntClear (WTIMER 4_base、TIMER_CAP_EVENT);-随着代码的增长或将其导入到其他项目中时、您最终将启用其他触发器、您的代码将永久循环到此计时器 ISR 中。 习惯将所有中断标志读取到变量中、然后将其全部擦除。

    -您正在读取中断内部的 GPIOPin。 如果您的引脚在测量转换发生的间隔内翻转、以及进行此读数时、会发生什么情况? 有些东西将会是弹道导弹。 请注意、在发生转换时可能会处理其他中断、并且在几个周期之后、代码才会到达该点。

    -您是否确保计时器的负载足以测量事件的周期? 如果您只是使用"正常" 16位、那么速度非常快...

    - ISR 很短,但如果可以更短,那就更好了(所以不影响其他 ISR):只需将值捕获到变量中,然后设置一个标志来评估主循环中的某个位置的此类值。 在 ISR 中执行的操作越少、越好。

    一种更为复杂但准确的测量方法是使用 DMA。 您可以将 DMA 配置为在每次信号翻转时将计时器计数传输到已知的存储器阵列中。 在这么多转换之后、您运行例程来执行您正在执行的这种差异评估。 如果没有太多通道、实际上可以为一个转换配置两个 DMA 传输:一个传输计时器计数器、另一个传输引脚电平、因此最后您有如下表:

    14200 1.
    14300 0
    17150 1.
    17250 0

    此致、

    布鲁诺