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.

[参考译文] MSP430F5172:如何同步由两个计时器生成的具有不同时基的边沿?

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/857397/msp430f5172-how-to-synchronize-edges-generated-by-two-timers-with-different-time-bases

器件型号:MSP430F5172

处理器: MSP430F5172

我想知道、当两个不同定时器的时基不同时、在两个 CCR 输出模块之间实现上升沿同步的最准确方法是什么。   理想情况下、我希望边沿在彼此之间的几个 MCLK 内发生、最好小于10。   请记住、这个帖子 是整个项目的总体简化、但它具有一个基本概念。   首先、让我用图表进行演示:


顶部脉冲序列由 TD0和 TD0CCR1生成、其输出比较单元配置为在引脚 TD0.1上输出  TD0、配置为使用通过常用时钟分频器生成的62500kHz 时钟运行。  脉冲序列本身有一个1秒的周期; 因此、在这个脉冲序列的任何一个周期内、总共发生62500个 TD0时钟周期。   脉冲序列时序由(1)一个数组生成、该数组保存间隔(2)保存要知道何时处于图形末尾的边沿数的常量(3)时序数组中位置的索引、以及(4) 保存的变量 电流脉冲状态为高电平或低电平(5) ISR 会递增要定时的间隔并修改 TD0CCR1  

下面是我的一些示例代码、展示了如何生成顶部脉冲序列:

#include 
#include 

// //
//输出脉冲时序
// ACLK @ 500kHz * 1/8分频器= 16us/tick
//
//注意:针对连续模式的 TD0/TD1置1
// pulseTiming_master[]乘以交替高电平周期、低电平周期、高电平周期、低电平周期等
////
注:此数组中的所有元素都应加1 / 16us =62500
// //
// 75ms 接通、100ms 关断、75ms 接通、700ms 关断
uint16_t pulseTiming_master[4] ={4688、6250、4688、46874};
常量 uint8_t numEdges_master = 4;
volatile uint8_t pulseIdx_master = 0;
易失性 pulseState_t curPulseVal_master =低电平;


//此 ISR 在 TD0R 计数到 TD0CCR1-6时触发
// OUTMOD_1 -->设置硬件输出单元中的引脚
// OUTMOD_5 -->重置硬件输出单元中的引脚
// PJ.6 --> TD0.1 --> PULSE
#pragma Vector = TIMER0_D1_VECTOR
__INTERRUPT void Timer0_D1_ISR (void)
{
switch (TD0IV)
{
情况0: //无中断;为 CCR0保留
中断;
案例2: // TD0CCR1

if (curPulseVal_master ==低电平) //... 引脚翻转为高电平、然后我们进入该 ISR ...
{
//引脚现在设置为高电平、下一个中断要将其复位为低电平
TD0CCTL1 = OUTMOD_5 | CCIE;
curPulseVal_master =高电平;
}
其他
if (curPulseVal_master ==高电平) //... 引脚翻转为低电平、然后进入该 ISR ...
{
//引脚现在复位为低电平、下一个中断需要将其设置为高电平
TD0CCTL1 = OUTMOD_1 | CCIE;
curPulseVal_master =低电平;
}

//更新时间间隔
TD0CCR1 = TD0R + pulseTiming_master[pulseIdx_master];
//更新脉冲时序数组的索引...
if (pulseIdx_master < numEdges_master - 1) pulseIdx_master++;
其他 pulseIdx_master = 0;

中断;
案例4: // TD0CCR2
中断;

默认值:__never_executed();

}
}


int main (void)
{
WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器

//假设时钟系统已经配置了 MCLK = 16MHz、ACLK = 500kHz…… 此处未显示此内容

//停止计时器和清除分频器
TD0CTL0 = TDCLR;
TD0R = 0;
// TD0使用 ACLK @ 500kHz (2us)作为输入时钟;输入分频器= 8;连续模式;16位;独立组;
TD0CTL0 = TDSSEL_ACLK | ID_8 | CNTL__16 | SHR_0 | TDCLGRP_0;
//扩展 div = 1.
TD0CTL1 = TDIDEX__1;


//确保脉冲时序从初始条件开始
pulseIdx_master = 0;
curPulseVal_master =低电平;

//当 TD0R"计数到"TD0CCR1时、输出信号受到影响
TD0R = 0xFFFF;
TD0CCR1 = 0;

//立即加载;以设置操作的形式启动输出;启用中断
TD0CCTL1 = CLLD_0 | OUTMOD_1 | CCIE;

//开始计时器运行
TD0CTL0 |= MC__Continuous;


_bis_SR_register (GIE); //启用全局中断

while (1)
{

}
返回0;
}


好的,所以总体想法(参考图示)是为主脉冲的第一个上升沿(用蓝色图示)提供某种前导码  (用红色图示)。 包含第一个主器件上升沿之前的任意数量的脉冲(这些脉冲将在高/低时间以及数量的最终应用中发生变化)  前导码的最后一个上升沿必须同时发生、 或非常接近主脉冲的上升沿。    

与此相关的是、该前导码脉冲由不同的计时器 TD1运行、并且 TD1的时钟频率为16MHz。   这个脉冲在 TD1的控制下、使用 TD1CCR2输出单元、在  图中的 TD1.2引脚上输出脉冲、我可以进行一些时间数学运算来确定点"A"的位置、但我不知道在出现"A"时在软件中该怎么办。  此外、我不确定如何处理 TD0R 翻转和 TD1R 翻转之间的较长时间差。   实际上,前导码脉冲的高/低时间大约 为32 - 128us ... 需要将这个16MHz 输入时钟连接到 TD1。   

从 TD1生成此前导码的方法与主脉冲相同或相似、即使用输出比较单元、然后在 ISR 中读取线性数组中的值、为下一个间隔计时、直到达到前导码模式的末尾。   从这个意义上讲、前导码本身的周期等于主器件的周期; 在这里的简单示例中、1秒。   

在 MSP430论坛上与所有计时器专家联系:  如果您必须实现我在上面所述的目标、您将如何实现?   是否有办法使主器件/前导码脉冲的边沿精确对齐?   如果不是、我将在软件中执行什么操作来实现此帖子中所述的近距离同步?  

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

    您好!

    感谢您将此问题声明得如此详细。  但   我有点迷路了。

    1.我有疑问。 为什么不能将这两个脉冲序列组合到一个 TD0中?

    2. 您可以将 TD0的 CCR0用作定时器。  将 其设为 向上计数模式并设置中断时间。    当它到达 A 点时  、进入 ISR 来设定 TD1CCR2

    实际上、它将延迟一些周期。  它们由2个部分组成。 第一个是进入 ISR、您可以参阅 UG。 第二个是执行代码、您可以使用 CCS 来查看使用的周期数。

    伊斯天

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

    我无法将两个脉冲序列组合到单个 TDx 中、因为:

    • 1秒长周期需要一个非常慢的时钟(62500Hz)才能生成脉冲间隔
    • 前导码的高/低时间大约为128us,需要一个非常快的时钟(16MHz)来生成间隔
    • TDX 仅为16位。  因此、对于16MHz 时钟、最大间隔为65536*62.5ns = 4.096ms   

    因此、如上所述、此应用需要两个时钟。  

    感谢您建议使用 TD0的 CCR0。  我认为这是可以实现的、因为 CCR0资源是空闲的、目前未使用。  但是、TD0必须以连续模式运行才能正常工作、因为向上计数模式会将 CCR0资源用作周期设置寄存器。

    我现在将在代码中运行一些实验。

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

    是的、你是对的。

    TDO 有三个 CCRx、您可以使用 CCR2。 我将关闭此主题。 如果您有任何新问题、您可以创建一个新问题或仅在此主题下回复。

    伊斯天