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.
工具/软件:Code Composer Studio
我正在尝试使用 SMCLK 通过 timerA 测量 SPI 从器件的运行时间。
但 timerA 的结果是怪异的。
它的工作频率为400Hz。 我测量了它、但精度非常高。
我只需要200个数据、因此它只需0.5秒即可工作。
SMCLK (=MCLK)为16MHz、输入分频器为8、所以...
预期结果为1M。
16M/8/2=1,000,000
但实际结果是930、000 ~ 950、000。
我没有更改 LPM 模式。
SPI 从器件运行时、使用中断和 SPI 通信。
FLL 被使能。 如果禁用、结果约为77、000。
为什么会发生这种情况?
此代码是我的 timerA 设置。
void init_timerA()
{
//启动计时器。 用户指南第370页
// TAIE - Timer_A 中断使能。 该位启用 TAIFG 中断请求
// Timer_A 时钟源选择10b = SMCLK
// InputDivider。 0xC0 =/8
// ID。 输入分压器。 00b =/1、11b =/8。
// ID_3 (3*0x40u)// Timer A 输入分频器:3-/8 */
// TASSEL1 = 10b = SMCLK\
// TASSEL0 = 01b = ACLK。
TA0CTL |= TASSEL1 + ID_3 + TAIE;//+ 0xC0;
//CM0 = 0x4000、10b =下降沿上的捕捉
//CCIS_3 (3*0x1000u)/*捕获输入选择:3- Vcc */
//cap (0x0100)//捕获模式:1 /比较模式:0 */
TA0CCTL0 = CM0 + CCIS_3;//
// 1. 向 TACLR 位写入1 (TACLR = 1)来清零 TAxR、时钟分频器状态和计数器方向。
TA0CTL |= TACLR;//+ TAIE;// Timer_A 清零。 将该位置位将复位 TAxR、定时器时钟分频器逻辑(分频器设置保持不变)和计数方向。
// 2. 如有必要、将初始计数器值写入 TAxR。
TA0R = 0;
// 3. 初始化 TAxCCRn。
TA0CCR0 = 50000;
// 16M / 8 (div)/ 400 (Hz)= 5000。
// 4. 对 TAxIV、TAIDEX 和 TAxCCTLn 应用所需的配置。
// 5. 对 TAxCTL 应用所需的配置、包括对 MC 位。
//模式控制
//00b =停止模式:定时器暂停
//01b = MC0 =向上计数模式:定时器向上计数到 TAxCCR0
//10b = MC1 =连续模式:定时器计数到0FFFFh
//11b =向上/向下计数模式:定时器向上计数至 TAxCCR0、然后向下计数至0000h
TA0CTL |= MC0;
}
我将主时钟更改为4MHz 并重试。
结果是205、000。
它没有发生太大变化。
和。
我在测量时间之前添加了此代码。
while (WDTcount < 10){
WDTcount++;
MCU_lpm_enter (4);
}
。 + init_timerA ();+测量时间。
结果是291、400。
为什么选择 CCIS_3? 否设置 CAP=1?
SPI 信号频率是多少? 即、您使用 SMCLK 2MHz 测量的周期是多少?
是否启用中断以读出计时器计数值? 如果没有、如何保证立即读取计时器数据? 您是否已经捕获了很多次、并使用2个相邻的捕捉定时器值计算时钟计数?
谢谢、
Lixin
您好、Lixin、
1、CCIS、CAP。 没有具体原因。
已0~2 CCIS Δ I 和 CAP、但结果未更改。
2. SPI 信号频率
UCB0CTLW0 |= UCSSEL_SMCLK;// SMCLK
UCB0BR0 = 0x10;
使用 SMCLK 2MHz 测量的周期是多少?
我想测量以400Hz 频率运行的器件运行200次的时间。
500ms 是完美的、497.5 ~ 502.5ms 是安全的。 否则表明出现了问题、需要重新启动。
2MHz?
由于其他原因、我不得不降低时钟以降低功耗。
4.是否启用中断以读出计时器计数值?
我使用类似这样的中断。
定时器计数达到50000、它返回0并产生溢出中断。
#pragma vector=TIMER0_A1_vector
_interrupt void TIMER0_A1_ISR (void){
int _= TA0IV;
TimerAmount ++;
}
如果 TimerAcount = 5、ticksave = 40000、
结果为29、000。
5.您是否已经捕获了很多次并使用2个相邻的捕获定时器值计算时钟计数?
仅捕获2次。 前后。 这是我的代码。
tickstart = TA0R; startOF = TimerAcount; while (savednum < 200){//获取200次。 中断。 在0.5秒内 if (readflag){// LIS 中断 readflag = false; LIS_GET_xyz_saveto (savednum); savednum++; } } end_timerA ();// TA0CTL = 0; ticksave = TA0R; endof = TimerAmount;
如果禁用 FLL、结果约为206、000
如果启用 FLL、则重用大约291000。
谢谢、
:KH
FLL 可确保您的 DCO (SMCLK)以您认为的速度运行。 关闭它通常不有用。 如果必须将其关闭、至少要先等待锁定;理论上、这可能需要大约0.5秒。
未经请求:按此方式进行定时容易受到翻转干扰的影响。 考虑使用 TA0EX0 (或可能是 ACLK)进一步降低定时器的速度、这样定时器在您的计时期间不会(正常情况下)发生回绕。
感谢您的建议。
我更改了设置并重试。
MCLK、SMCLK = 4MHz、输入分频器= 64、运行时间= 0.5秒。
预期理想节拍= 31、250 +- 156.25
这次我保存了每次传输的节拍数。
[0]无符号 short 100 0x0024B0
[1]无符号短整型230 0x0024B2
[2]无符号短整型360 0x0024B4
[3]无符号短整型490 0x0024B6
[4]无符号短整型621 0x0024B8
(笑声)
[98]无符号短整型15137 0x002574
[99]无符号短整型15322 0x002576
[100]无符号短整型15507 0x002578
[101]无符号短整型15693 0x00257A
前半部分测量结果不好。
15693 * 64 = 1、004、352。
[155]无符号短整型26876 0x0025E6
[156]无符号短整型27092 0x0025E8
[157]无符号短整型27309 0x0025EA
[158]无符号短整型27525 0x0025EC
[197]无符号短整型35971 0x00263A
[198]无符号短整型36188 0x00263C
[199]无符号短整型36405 0x00263E
但在后半部分、上升增加、结果完全错误。
1) 1)也许您可以解释我们所看到的内容。 哪些数字"完全错误"、您如何辨别?
2) 2)您如何进行测量? 您是每次清除计时器、还是捕获开始+停止并减去? 当我执行此操作时、我通常会让连续模式计时器保持运行并捕获开始+停止、因为这使得算术变得简单。
3) 3)您的具体时间是什么? 您之前发布的片段主要由条件(if))决定,因此它在不同条件下的行为似乎有所不同。
4) 4)开始试用之前、您是否等待 FLL 锁定? 您可以在该范围内执行其他操作、但在开始测量时确实需要锁定 FLL (一致的时钟)。
您好、Bruce、
1.很抱歉,我是说。 结果(36000)不是我所期望的结果(31250)。
2.检查2次。 前后。
启动 timerA、
检查计时器、
我想知道的有关运行时间的信息、
停止计时器(可能无用?)、
检查计时器。
3.操作和捕获
P1OUT &=!BIT4;
tickstart = TA0R; startOF = TimerAcount; while (savednum < 200){//获取200次。 中断。 在0.5秒内 if (readflag){// LIS readflag 的中断= false; P1OUT |= BIT5;//切换引脚1.5 lis_get_xyz_saveto (savednum); P1OUT &=!BIT4;//切换引脚1.5 tickarr[savednum]= TA0R; savednum++; } end_timerr = tickr; }= tickr;timercount (timerr = tickr;}= tickr = tickr;}= tickr = tickr;timerr =
我使用 GPIO (使用示波器)进行了测试、并确认操作正常。
4、我现在没有触摸 FLL、等待1.25秒。
我应该等待多长时间?
这是程序流程。
初始化 MSP430FR2433。
更改 init MSP 和其他器件的配置。
初始化看门狗定时器。
while (WDTcount < 5){
WDTcount++;
MCU_lpm_enter (4);
}
等待1.25秒。
初始化 timerA。
测量时间。
(笑声)
我尝试在等待序列之前移动 init_timerA、但结果没有不同。
谢谢。
1) 1)好的、所以第二个数字是 tickr[]的内容、并且由于您不是每次清除 TA0R、所以它会单调增加。 (我并不一定建议清除计时器、我只是在描述。)
那么、有趣的是连续线之间的差值。 这确实在逐步增加,从第一组中的大约130个增加到最后一组中的217个。
3) 3)您要测量的内容主要由 if ()决定、我怀疑该 if ()会检查 ISR 中的变量集。 请记住、(a) ISR 速率可能与代码不协调、因此您要测量 ISR 之间的旋转、(b)您还需要测量 ISR 的成本。
具体而言(a):如果 ISR 周期比代码稍长、它将向前漂移、并且由于额外的旋转、测量值将逐渐增加。 我建议您将开始/停止捕捉放在 if()内。
4)通常、FLL 应在不到0.5秒的时间内锁定(使用 REFO、我希望您是这样)。 您是否相当确定该环路真正等待1.25秒?
如果您想确定、可以插入:
> while (CSCTL7 &(FLLUNLOCK0 | FLLUNLOCK1));//轮询直到 FLL 锁定
[从示例 msp430fr243x_CS_07.c 中删除、此处:
https://dev.ti.com/tirex/explore/node?node=AJXSKLubovap2pQl1MpHeA__IOGqZri__LATEST
]
未经请求:
P1OUT &= !BIT5;
// toggle pin 1.5
这相当于"P1OUT = 0;"。 我怀疑您想要:
P1OUT &= ~BIT5;
// toggle pin 1.5
您好、Bruce、
ISR 是否是问题的原因? 但是。 此程序不能在没有中断的情况下运行。
从器件接收就绪信号是中断、SPI 事务使用中断。
将开始/停止捕捉放置在 if()内?
我无法理解。
if (readflag){
继续执行 timerA
P1OUT 引脚1.5 =高电平
执行 SPI 操作
P1OUT 引脚1.5 =低电平
挂起时间 A
}
此代码只能测量脉冲为高电平时的时间。 并不是一整天。
FLL 可能有一个大问题。
void init_clocks () { //根据器件数据表的要求为 MCLK 配置一个 FRAM 等待状态 //在8MHz 之前运行配置时钟系统。 FRCTL0 = FRCTLPW | NWAITS_1; _ bis_SR_register (SCG0);//禁用 FLL CSCTL3 |= SELREF_REFOLCLK;//将 REFO 设置为 FLL 基准源 CSCTL0 = 0;//清除 DCO 和寄存 器 CSCTL1 &=~(DCOSEL); //清除 DCO 频率选择位优先 // DCORSEL_3 = 0x011 -> 8MHz // DCORSEL_0 = 0x000 -> 1MHz // DCORSEL_1 = 0x001 -> 2MHz // DCORSEL_2 = 0x010 -> 4Mhz // DCORSEL_5 = 0x101 -> 16MHz。 默认值。 CSCTL1 |= DCORSEL_2;//设置 DCO CSCTL2 = FLLD_0 + 487;// DCOCLKDIV = DCO _ DELAY_CYCLLES (3); __BIC_SR_register (SCG0);//启用 FLL while (CSCTL7 &(FLLUNLOCK0 | FLLUNSCLMCL_);//直到锁定 FLLCSCL_ DCLK4);// DCLLMCL_ DLL_轮询= FLL_CLK4 ;//直到 CLOCLKLMS_CLLMS_LMS_被锁定 //将默认 REFO (~32768Hz)设置为 ACLK 源,ACLK = 32768Hz //默认 DCOCLKDIV 设置为 MCLK 和 SMCLK 源 CSCTL6 &=~(XT1AUTOOFF); }
在该代码中、在这里进行了调试。 'while (CSCTL7 &(FLLUNLOCK0 | FLLUNLOCK1));'。
我发表意见
CSCTL1 &= ~(DCORSEL_7);
// Clear DCO frequency select bits first
并尝试将 CSCTL1更改为
CSCTL1 = DCOFTRIMEN | DCOFTRIM0 | DCOFTRIM1 | DCORSEL_0、2、3;
但仍在实现 while ()。
我是否应该发布有关此问题的新问题?
非常感谢。
3) 3)如果您的目标是捕获 ISR 的时间、则应执行此操作。 但请记住、您正在测量之间的空闲时间、这两个时间(这些事件是异步的)可能会有所不同。
4) 4)简短回答:尝试 DCORSEL=5。 复位值为=1。 [参考用户指南(SLAU445I)表3-5和数据表(SLASE59D)表5-6 ]
稍长:"487"指定绝对速度(487*32768Hz=~16MHz)。 如果该速度不在 RSEL 范围内、FLL 将把 CSCTL0:DCO 推至其范围的一端或另一端并保持在该端(饱和)、无法锁定。
我希望这种情况下的结果是恒定(虽然不正确) DCO 速度、这本身不会解释逐渐的计时漂移。
如果您尚未查看示例 msp430fr243x_CS_03.c、请点击此处:
https://dev.ti.com/tirex/explore/node?node=AHMHa7q.qkFTrXXRnRPsug__IOGqZri__LATEST
您可能只需复制/粘贴相关部分。 (这是我通常所做的。)
您好、Bruce、
当 MCLK 为4MHz 时、
CSCTL2 = FLLD_0 + 122;
此代码运行良好! 谢谢你。
我以前不了解 FLLN。
通过这种出色的 FLLN、TimerA 变得更加精确。 但它似乎还不完美。
我使用4个不同的电路板进行了测量。
结果:
1.31038、31153、31074、31112、31079
2.31737、31745、31772、31748
3. 31926、31955、31958、31933
4. 31248、31252、31243、31246
最佳结果是31250 +- 156。
1号有点小、2、3号太大。
谢谢。