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.

FLL+ 不稳定



1MHz:

8MHz:

12MHz:

20MHz:

输出的是MCLK,用的是F5529官方例程的库.

#include <msp430.h>
#include "F5xx_F6xx_Core_Lib/HAL_PMM.h"
#include "F5xx_F6xx_Core_Lib/HAL_UCS.h"


int main(void)
{
volatile unsigned int i;

WDTCTL = WDTPW+WDTHOLD;
SetVCore(PMMCOREV_3);

P1DIR |= BIT1;
P1DIR |= BIT0;
P1SEL |= BIT0;
P3DIR |= BIT4;
P3SEL |= BIT4;
Init_FLL_Settle(20000, 610);


while(1)
{
P1OUT ^= BIT1; // Toggle P1.1
__delay_cycles(600000); // Delay
}
}

  • 用这个:

    void SetVcoreUp (UINT16_T level)
    {
    PMMCTL0_H = PMMPW_H; /* Open PMM registers for write */
    SVSMHCTL = SVSHE + SVSHRVL0 * level + SVMHE + SVSMHRRL0 * level; /* Set SVS/SVM high side new level */
    SVSMLCTL = SVSLE + SVMLE + SVSMLRRL0 * level; /* Set SVM low side to new level */

    while ((PMMIFG & SVSMLDLYIFG) == 0); /* Wait till SVM is settled */

    PMMIFG &= ~(SVMLVLRIFG + SVMLIFG); /* Clear already set flags */
    PMMCTL0_L = PMMCOREV0 * level; /* Set VCore to new level */

    if ((PMMIFG & SVMLIFG)) /* Wait till new level reached */
    while ((PMMIFG & SVMLVLRIFG) == 0);

    SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level; /* Set SVS/SVM low side to new level */
    PMMCTL0_H = 0x00; /* Lock PMM registers for write access */
    }

    void UcsInit (void)
    {
    // Increase Vcore setting to level3 to support fsystem=25MHz
    // NOTE: Change core voltage one level at a time..
    SetVcoreUp (0x01);
    SetVcoreUp (0x02);
    SetVcoreUp (0x03);

    UCSCTL3 = SELREF_2; // Set DCO FLL reference = REFO
    UCSCTL4 |= SELA_2; // Set ACLK = REFO

    __bis_SR_register(SCG0); // Disable the FLL control loop
    UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx
    UCSCTL1 = DCORSEL_7; // Select DCO range 50MHz operation
    UCSCTL2 = FLLD_1 + 762; // Set DCO Multiplier for 25MHz
    // (N + 1) * FLLRef = Fdco
    // (762 + 1) * 32768 = 25MHz
    // Set FLL Div = fDCOCLK/2
    __bic_SR_register(SCG0); // Enable the FLL control loop

    // Worst-case settling time for the DCO when the DCO range bits have been
    // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
    // UG for optimization.
    // 32 x 32 x 25 MHz / 32,768 Hz ~ 780k MCLK cycles for DCO to settle
    __delay_cycles(782000);

    // Loop until XT1,XT2 & DCO stabilizes - In this case only DCO has to stabilize
    do
    {
    UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);
    // Clear XT2,XT1,DCO fault flags
    SFRIFG1 &= ~OFIFG; // Clear fault flags
    }while (SFRIFG1&OFIFG); // Test oscillator fault flag
    }

  • 你用2M采样率去采样8M,20M的频率?

    根据采样定律你的采样率至少要是信号的2倍.

     

  • 2M是采样深度,最大单通道48M采样率,显示是24M采样率(为实际采样率).

    而且就算2M采样率不可能采到12M吧.

  • UcsInit 是怎么回事.

  • 我有外部ACLK,32.768kHz,怎么参考这个来校准,会不会好一些.

  • 你用一个好点的示波器在测试下呢?F55XX的的FLL的两个间隔周期能做到10%的误差。

    楼上那个UCSINIT是用来设置FLL到目标频率的。那个函数是用来校准目标频率精度的。

    你的问题是一个频率的波形中,两个相邻的周期相差较大。

  • 部分MSP430的芯片采用了FLL模块,FLL就相当于PLL,目的是让调整输出CLK尽量靠近目标频率。和PLL不同的是,FLL校准是用数字的。缺点就是不能连续地调整频率输出,而是离散的输出。

    例如我们要想输出一个20M的频率,FLL会调整频率输出在20+XX和20-XX范围之间。这样就会出现在一段时间的波形中,两个相邻的系统时间有一定误差,这个误差通常在10%范围内。也就是说FLL调整的时钟是平均值为20M,而不是每个CLOK都是20M。

    楼主贴的波形明显地超出了10%的误差,所以我建议你用好点的示波器来测试下。

     

    另外,楼主可以讲一下你的具体需求,是什么样的应用需要用到高精度的CLOK。

     

    楼主想通过外部的32K来校准,实际上不是太通用。因为5系列的DCO本来就可以用FLL校准得很准了。

  • 用CX-117A晶振测试仪显示20.057MHz 114ppm,这样是不是已经超出系统频率,会不会有点什么问题.还是要把UCSCTL2 = FLLD_1 + 610中的610改小?走定时器好像有点担心.特别是系统异常复位,但是外部跑高速设备又麻烦.

    (609+1)*32768Hz=19.988480MHz

    (610+1)*32768Hz=20.021248MHz

  • 一小点超频没有问题,只要你的内核电压不要设置得太低就行。