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.

[参考译文] MSP430FR5994:DMA/定时器捕捉- DMA 传输后数据中断

Guru**** 2582405 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/866908/msp430fr5994-dma-timer-capture---broken-data-after-dma-transfer

器件型号:MSP430FR5994

你好!

我正在尝试对进入器件的脉冲进行采样、测试设置是 MCU、测试信号(2.4kHz 频率的1uS 脉冲)连接到端口 P1.0和 P2.3。 我的想法是在比较模式(两个边沿)下启动计时器、在 TA0CCR2标志上进行自动 DMA 传输、并在稍后处理收集的数据、按脉冲宽度收集统计数据。 在实际固件中、它是在 FreeRTOS 任务中完成的、但我简化了项目以隔离问题。

因此,我有一个缓冲区,其数据样本格式如下:[1个脉冲前时间戳][1个脉冲尾时间戳][2个脉冲启动][2个脉冲结束]... (笑声) (笑声) 等等。

因此、具有16MHz 时钟时、我希望数据像[1 16 8001 8016 16001 16016]或类似这样的数据。 但有时(在工作一分钟左右之后)我会得到奇怪的结果-第一个采样时间戳是错误的、例如 [1 16 8001 8016 16051 16016]。

由于我有可预测的信号、我可以看到它与正确的时间戳之间的区别仅为几位、即0x2AB0而不是0x2AB0、或0x4370而不 是0x4340、或0x08F4而不是0x08C0、总是错误位被错误设置、而不是清除。  

以下是我的代码:

#include 
#include 

#include "lib/GPIO_macros.h"
#include "lib/hardware.h"

volatile unsigned char new_data_available = 0;

#pragma vector=Port1_vector
__interrupt void Port_1 (void){
if (P1IV = 0x02) new_data_available = 1;
}

#define detector buffer_size 32
unsigned short ***[detector buffer_size_1];//消除超出范围的编译器警告
unsigned short detector stats[16]={0、0、0、0、0、0、0、0、0、0、 0、0、0、0、0、 0、0、0、0、0、 0};

int main (void){
WDTCTL = WDTPW + WDTHOLD;//停止看门狗计时器以防止超时复位
PM5CTL0 &=~LOCKLPM5; //禁用 GPIO 上电默认高阻抗模式
// DMACTL4 |= DMARMWDIS;//必须注释,减慢速度

PIN_CONFIGURATION (LFXT1、MODE_PERFICE_1);
PIN_CONFIGURATION (LFXT2、MODE_PERFICE_FUNC功能性1);

CSCTL0 = CSKEY; //解锁 CS 控制寄存器
CSCTL4 |= LFXTDRIVE_3; //最高驱动器设置(仅用于启动)
CSCTL4 &=~(LFXTOFF|LFXTBYPASS);//打开晶振
while (CSCTL5 & LFXTOFFG){ //等待晶振稳定(清除故障标志)
CSCTL5 &=~(LFXTOFFG);
SFRIFG1 &=~OFIFG;
}
CSCTL4 &=~LFXTDRIVE_3; //清除 LFXTDRIVE (将请求的驱动模式设置为最低电流)

FRCTL0 = FRCTLPW | NWAITS_1; //见 slau367k.pdf 中的表8-1
CSCTL1 = DCORSEL | DCOFSEL_4; //将 DCO 频率设置为16MHz
CSCTL2 = SELA_LFXTCLK | SELM__DCOCLK | SELS__DCOCLK;//将时钟源设置为 DCO
CSCTL3 = 0x0000;//将所有分频器减至最小值
CSCTL0_H = 0x00;//锁定 CS 控制寄存器

PIN_CONFIGURATION (detector _IN0、MODE_PERAPTERY_FUNC功能性1);// 39、P2.3、[TA0.0]
PIN_CONFIGURATION (Detector IN1、MODE_INPUT_FLOLINULOCTOR); // 1、P1.0、[GPIO INT]

对于(无符号短整型 I=0;I > 1;
Buffer_PTR_Current = buffer_PTR_over - samples_rest * 2;//开始两个样本占位符
对于(;;){
if (buffer_ptr = buffer_ptR_current) break;

无符号短启动=*缓冲区_PTR++;
无符号短宽度=*缓冲区_PTR++;
width = start;//我们可以在不< check 的情况下执行此操作(由于'unsigned short'溢出)
if (buffer_ptr = buffer_ptR_over) buffer_ptr = buffer_ptR_start;

如果(宽度> 32768){
break;//<--在这里断点
}

宽度>=4;
如果(宽度> 15)宽度= 15;

Deter_states[width]++;
}
}

}


这是什么?

RAM 故障? DMA 诀窍? 未知勘误章节? )

提前感谢您!

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

    >    TA0CCTL2 = CM_3 | CAP; // both edges

    如果您也设置 SCS、您是否会获得相同的结果? 是的、MCLK 和 SMCLK (=DCO)应该被隐式同步、但是我从来没有尝试过没有 SCS 的捕获。

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

    哇,这很有帮助! 非常感谢!

    我在主固件中使用了该位、将其关闭有助于一点、因此我也将 SCS 位关闭以进行测试。 但是当我在这里打开它时、它开始像应该那样在脉冲的前缘和尾缘之间工作多达6-7个 MCLK 周期。

    因此我尝试理解为什么我的测试在主固件不运行时起作用、并发现  我在 vApplicationIdleHook ()中有__ bis_SR_register (LPM4_bits+GIE)。

    我有 16MHz SMCLK 提供的 timerA、因此 MCU 实际上处于 LPM1模式(IAR 状态日志摘要证明了这一点)。

    我对这一行进行了注释、并获得了更好的结果(与测试中的结果不同、但实际上要好得多)。

    因此、我更改了该行以使 CPU 处于 LPM0模式、而不是 LPM4模式-仍然有效。

    更改为 LPM1 -完全不好。 不仅"接收"不良数据、而且所有数据都很糟糕、只记录了一个边沿(仅前边沿或尾边沿)。

    它在 LPM0模式下工作、但在 LPM1模式下不工作。

    我阅读了文档、发现 LPM0和 LPM1模式之间没有差异。 我有用于计时器的16MHz SMCLK、因此 DCOCLK 在捕获时绝对有效、因此 DMA 应立即启动。 LPM1 禁用了 FRAM、但"(2)通过 FRAM 控制器 A 禁用 FRAM 允许应用降低 LPM 电流消耗、但访问 FRAM 时唤醒时间会增加(例如、获取中断矢量)。 对于不访问 FRAM 的唤醒(例如、DMA 传输到 RAM)、唤醒时间不会增加。"

    那么、毕竟、我不明白为什么 DMA 在 LPM1模式下工作如此奇怪? 它具有 DCOCLK 就绪且稳定、CPU 已关闭、一切就绪。 但它不能按预期工作。

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

    我不知道答案。 最近有人(我现在似乎找不到)在 FR5994的 LPM 中使用 DMA 时遇到问题、但这是尝试将 DMA 放入 FRAM、而 FRAM 中的 sloth 似乎会起作用。 但您的情况并非如此。

    据我所知、您的测试案例(如上所述)现已成功。 如果您在其中引入 LPM、会发生什么情况? 这将避免所有 FreeRTOS 干扰。

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

    结果相同-它在 LPM0中工作、但在 LPM1中失败。

    我猜 FRAM 启动会锁定芯片内部的某个器件、因此 DMA 没有机会写入每秒脉冲并且错过传输。

    可能有 TI 的人会对此发表评论?

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

    我在 Launchpad 上运行了您的代码的(黑客攻击)副本、但我看不到您的症状。

    我必须移动器件和引脚分配、但我还采用了 TB0来生成与您描述的波形类似的波形(2.4kHz 时为1us 脉冲)、并将其接至捕捉引脚。 LPM 唤醒由 DMAIFG 和一个按钮完成(为您的 P1.0触发器代入)。 鼠标陷阱是您的"负宽度"检查。 我尝试了 LPM0/1/3/4 (是的、最后2次实际上是 LPM1)。

    在半个多小时内、我没有看到陷阱、并且对 DMA 缓冲器进行的多次抽查显示了所有的顺序。

    这里的最大区别可能是同一个 MCU 正在生成和捕获波形。 这会产生相当高的同步度。 (我甚至关闭了 SCS 而没有任何不良影响。) 这表明您的输入波形有意外的情况:

    1) 1)是否可能发生毛刺脉冲(脉冲< 20ns)?  

    2) 2) P1.0脉冲与 TA0.CCI2A 波形的协调程度如何?

    /cfs-file/__key/communityserver-discussions-components-files/166/Oleg_2D00_5994.c

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

    脉冲来自信号发生器、通过1k Ω 电阻器(用于额外滤波)和示波器控制器、因此我确信信号不包含毛刺脉冲。

    两个引脚连接在一起、因此 P1.0和计时器输入同时获得信号。 它们之间没有额外的逻辑。

    在此项目中、我们决定更改工作逻辑、将 IC 更改为64引脚、并制作模拟原理图以按脉冲持续时间对其进行排序、因此我将使用4个计时器 CLK 输入来对其进行计数。 这将允许使用低于 LPM1的 LPM 模式、这对我来说很重要、因为器件使用 CR2032电池。

    我怀疑我的问题与 PCB 上的 IC 有关、因此我订购了单独的 launchpad。

    这将需要"2-3周"才能收到它、 并将在"参考设计" launchpad 上尝试您的代码(和我的代码)、并在其中添加另一个 IC (可能会有另一个版本)。

    总之、非常感谢您的帮助!