• MSP430F5529晶振配置


    MSP430(F5529)相比MSP430(F149)来讲,功能更加强大。

    UCS简介
    MSP430F5XX/MSP430F6XX系列器件的UCS包含有五种时钟源,依次是:XT1CLK、VLOCLK、REFOCLK、DCOCLK和XT2CLK。这五种时钟的详细介绍请参考该系列芯片的指导手册,其中XT1CLK、VLOCLK、REFOCLK和XT2CLK跟MSP430F1XX系列没有太大区别,学习配置起来也比较简单。

    UCS上电默认状态

    PUC后,UCS模块的默认状态如下:

    XT1处于LF模式作为XT1CLK时钟源。ACLK选通为XT1CLK。  
    MCLK选通为DCOCLKDIV  
    SMCLK选通为DCOCLKDIV  
    FLL使能,且将XT1CLK作为FLL参考时钟。  
    XIN和XOUT脚设置为通用IO,XIN和XOUT配置为XT1功能前,XT1保持禁用。  
    如果可用的话,XT2IN和XT2OUT被设置为通用IO且保持禁止状态。  
    UCS时钟源切换

    由于REFOCLK、VLOCLK、DCOCLK(这里暂时这么认为)默认状态下是可用的,所以,切换的时候只需要通过UCSCTL4来配置ACLK、SMCLK和MCLK的时钟源即可,而XT1CLK和XT2CLK需要根据硬件的具体配置情况确定,所以,这两者的配置比起前三者来讲,就有些不同了。下面,我们做三个实验:

    (1)将MCLK和SMCLK配置REFOCLK、VLOCLK
    REFOCLK和VLOCLK是芯片默认提供的,只要芯片正常工作,这两个时钟就会正常工作,因此,该时钟配置非常简单,只需要修改UCSCTL4,将SELS和SELM配置为对应的选项VLOCLK或者REFOCLK即可,具体代码如下:

    1. #include
    2.  
    3. void main(void) {
    4.  
    5.   WDTCTL = WDTPW+WDTHOLD;
    6.  
    7.   P1SEL |= BIT0;
    8.  
    9.   P1DIR |= BIT0;//测量ACLK用
    10.  
    11.   P2SEL |= BIT2;
    12.  
    13.   P2DIR |= BIT2;//测量SMCLK用
    14.  
    15.   P7SEL |= BIT7;
    16.  
    17.   P7DIR |= BIT7;//测量MCLK用
    18.  
    19.   //UCSCTL4 = UCSCTL4&(~(SELS_7|SELM_7))|SELS_1|SELM_1; //将SMCLK和MCLK配置为VLOCLK
    20.  
    21.   UCSCTL4 = UCSCTL4&(~(SELS_7|SELM_7))|SELS_2|SELM_2; //将SMCLK和MCLK配置为REFOCLK
    22.  
    23.   while(1);
    24.  
    25. }

    上面的代码就实现了将SMCLK和MCLK切换为VLOCLK和REFOCLK,ACLK的操作也是同样的,不作过多解释。
    (2)将MCLK和SMCLK配置XT1CLK

    XT1CLK的配置要分为以下几步:

    配置IO口5.4和5.5为XT1功能。  
    配置XCAP为XCAP_3,即12PF的电容。  
    清除XT1OFF标志位。  
    等待XT1起振。         
    具体的代码如下: 

    1. #include  
    2.   
    3. void main(void) {  
    4.   WDTCTL = WDTPW+WDTHOLD;  
    5.     
    6.   P1SEL |= BIT0;  
    7.   P1DIR |= BIT0;//测量ACLK用  
    8.   P2SEL |= BIT2;  
    9.   P2DIR |= BIT2;//测量SMCLK用  
    10.   P7SEL |= BIT7;  
    11.   P7DIR |= BIT7;//测量MCLK用  
    12.   
    13.   P5SEL |= BIT4|BIT5; //将IO配置为XT1功能  
    14.   UCSCTL6 |= XCAP_3;  //配置电容为12pF  
    15.   UCSCTL6 &= ~XT1OFF; //使能XT1  
    16.   
    17.   while (SFRIFG1 & OFIFG){  
    18.     UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);         // 清除三类时钟标志位  
    19.                               // 这里需要清除三种标志位,因为任何一种  
    20.                               // 标志位都会将OFIFG置位  
    21.     SFRIFG1 &= ~OFIFG;                                  // 清除时钟错误标志位  
    22.   }  
    23.   UCSCTL4 = UCSCTL4&(~(SELS_7|SELM_7))|SELS_0|SELM_0;     //将SMCLK和MCLK时钟源配置为XT1  
    24.   while(1);  
    25. }  


    (3)将SMCLK和MCLK配置XT2
    将SMCLK和MCLK配置为XT2跟配置为XT1的过程基本相同,唯一不同的是,在配置SMCLK和MCLK为XT2之前,需要将ACLK和REFCLK的时钟源,因为ACLK和REFCLK的默认时钟源是XT1,而我们这里并没有配置启动XT1CLK,所以会产生XT1时钟错误,即XT1LFFG,因此,我们先将ACLK和REFCLK配置为芯片自带的时钟(REFOCLK或VLOCLK)或者即将启动的时钟(XT2),此外,XT2配置时不需要配置电容,故将SMCLK和MCLK配置为XT2的代码如下:

    1. #include  
    2.   
    3. void main(void) {  
    4.   WDTCTL = WDTPW+WDTHOLD;  
    5.     
    6.   P1SEL |= BIT0;  
    7.   P1DIR |= BIT0;//测量ACLK用  
    8.   P2SEL |= BIT2;  
    9.   P2DIR |= BIT2;//测量SMCLK用  
    10.   P7SEL |= BIT7;  
    11.   P7DIR |= BIT7;//测量MCLK用  
    12.   
    13.   P5SEL |= BIT2|BIT3; //将IO配置为XT2功能  
    14.   UCSCTL6 &= ~XT2OFF; //使能XT2  
    15.   
    16.   UCSCTL4 = UCSCTL4&(~(SELA_7))|SELA_1; //先将ACLK配置为VLOCLK  
    17.   UCSCTL3 |= SELREF_2;                  //将REFCLK配置为REFCLK  
    18.   
    19.   while (SFRIFG1 & OFIFG){  
    20.     UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);         // 清除三类时钟标志位  
    21.                               // 这里需要清除三种标志位,因为任何一种  
    22.                               // 标志位都会将OFIFG置位  
    23.     SFRIFG1 &= ~OFIFG;                                  // 清除时钟错误标志位  
    24.   }  
    25.   UCSCTL4 = UCSCTL4&(~(SELS_7|SELM_7))|SELS_5|SELM_5;     //将SMCLK和MCLK时钟源配置为XT2  
    26.   while(1);  
    27. }  


    DCO模块详解
    DCO模块在MSP430F5XX系列芯片中非常重要,因为从MSP430F4XX开始,MSP430引用了FLL模块,FLL即锁相环,可以通过倍频的方式提高系统时钟频率,进而提高系统的运行速度。
    DCO模块运行需要参考时钟REFCLK,REFCLK可以来自REFOCLK、XT1CLK和XT2CLK,通过UCSCTL3的SELREF选择,默认使用的XT1CLK,但如果XT1CLK不可用则使用REFOCLK。
    DCO模块有两个输出时钟信号,级DCOCLK和DCOCLKDIV,其中,倍频计算公式如下:

    DCOCLK = D*(N+1)*(REFCLK/n)  
    DCOCLKDIV = (N+1)*(REFCLK/n)  
    其中:
    n即REFCLK输入时钟分频,可以通过UCSCTL3中的FLLCLKDIV设定,默认为0,也就是不分频;
    D可以通过UCSCTL2中的FLLD来设定,默认为1,也就是2分频;
    N可以通过UCSCTL2中的FLLN来设定,默认值为32。
    所以,系统上电后如果不做任何设置,DCOCLK的实际值为2097152,DCOCLKDIV的实际值为1048576。
    另外,配置芯片工作频率还需要配置DCORSEL和DCOx,DCORSEL和DCOx的具体作用如下:
    DCORSEL位于UCSCTL1控制寄存器中的4到6位,共3位,将DCO分为8个频率段。
    DCOx位于UCSCTL0中的8到12位,共5位,将DCORSEL选择的频率段分为32个频率阶,每阶比前一阶高出约8%,该寄存器系统可以自动调整,通常配置为0。
    DCORSEL和DCOx值的具体作用可以参考MSP430F5529的数据手册,阅读该手册相关部分可以找到如下表格:

    可以见,DCORESL的频率调节范围大致如下:

    DCORSEL = 0的调节范围约为0.20~0.70MHZ;  
    DCORSEL= 1的调节范围约为0.36~1.47MHZ;  
    DCORSEL = 2的调节范围约为0.75~3.17MHZ;  
    DCORSEL = 3的调节范围约为1.51~6.07MHZ;  
    DCORSEL = 4的调节范围约为3.2~12.3MHZ;  
    DCORSEL = 5的调节范围约为6.0~23.7MHZ;  
    DCORSEL = 6的调节范围约为10.7~39.7MHZ;  
    DCORSEL = 7的调节范围约为19.6~60MHZ。  
    理解了上面这些,可以理解TI官方例子中的代码了,官方代码中的相关部分如下:

    if (fsystem <= 630)            //           fsystem < 0.63MHz  
      UCSCTL1 = DCORSEL_0;  
    else if (fsystem <  1250)      // 0.63MHz < fsystem < 1.25MHz  
      UCSCTL1 = DCORSEL_1;  
    else if (fsystem <  2500)      // 1.25MHz < fsystem <  2.5MHz  
      UCSCTL1 = DCORSEL_2;  
    else if (fsystem <  5000)      // 2.5MHz  < fsystem <    5MHz  
      UCSCTL1 = DCORSEL_3;  
    else if (fsystem <  10000)     // 5MHz    < fsystem <   10MHz  
      UCSCTL1 = DCORSEL_4;  
    else if (fsystem <  20000)     // 10MHz   < fsystem <   20MHz  
      UCSCTL1 = DCORSEL_5;  
    else if (fsystem <  40000)     // 20MHz   < fsystem <   40MHz  
      UCSCTL1 = DCORSEL_6;  
    else  
      UCSCTL1 = DCORSEL_7;  
    都在前面讲到的范围内,由于前面的范围有重叠部分,例子代码中的值是TI的工程师根据上面这些参数选取的比较合理的值。
    到这里,我相信大家配合芯片手册和本文,都能明白DCO配置相关部分的原理了,下面是将DCO参考时钟选为XT1,并将DCOCLK倍频到25M的详细代码:

    1. #include  
    2.   
    3. void delay(){  
    4.   volatile unsigned int i;  
    5.   for(i = 0; i != 5000; ++i){  
    6.     _NOP();  
    7.   }  
    8. }  
    9.   
    10. void SetVcoreUp (unsigned int level)  
    11. {  
    12.   // Open PMM registers for write  
    13.   PMMCTL0_H = PMMPW_H;  
    14.   // Set SVS/SVM high side new level  
    15.   SVSMHCTL = SVSHE + SVSHRVL0 * level + SVMHE + SVSMHRRL0 * level;  
    16.   // Set SVM low side to new level  
    17.   SVSMLCTL = SVSLE + SVMLE + SVSMLRRL0 * level;  
    18.   // Wait till SVM is settled  
    19.   while ((PMMIFG & SVSMLDLYIFG) == 0);  
    20.   // Clear already set flags  
    21.   PMMIFG &= ~(SVMLVLRIFG + SVMLIFG);  
    22.   // Set VCore to new level  
    23.   PMMCTL0_L = PMMCOREV0 * level;  
    24.   // Wait till new level reached  
    25.   if ((PMMIFG & SVMLIFG))  
    26.     while ((PMMIFG & SVMLVLRIFG) == 0);  
    27.   // Set SVS/SVM low side to new level  
    28.   SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level;  
    29.   // Lock PMM registers for write access  
    30.   PMMCTL0_H = 0x00;  
    31. }  
    32.   
    33. void main(void) {  
    34.   WDTCTL = WDTPW+WDTHOLD;  
    35.   P1SEL &= ~BIT1;  
    36.   P1DIR |= BIT1;  
    37.     
    38.   P1SEL |= BIT0; //ACLK  
    39.   P1DIR |= BIT0;  
    40.   P2SEL |= BIT2; //SMCLK  
    41.   P2DIR |= BIT2;  
    42.   P7SEL |= BIT7; //MCLK  
    43.   P7DIR |= BIT7;  
    44.   
    45.   P5SEL |= BIT4|BIT5;  
    46.   UCSCTL6 |= XCAP_3;  
    47.   UCSCTL6 &= ~XT1OFF;  
    48.   
    49.   SetVcoreUp(1); //一次提高Vcore电压等级,具体请参考手册  
    50.   SetVcoreUp(2);  
    51.   SetVcoreUp(3);  
    52.   
    53.   __bis_SR_register(SCG0);  
    54.   UCSCTL0 = 0;  
    55.   UCSCTL1 = DCORSEL_6;  
    56.   UCSCTL2 = FLLD_1 | 380;  
    57.   __bic_SR_register(SCG0);  
    58.   __delay_cycles(782000);  
    59.   
    60.   /* 
    61.    * 默认状态下:ACLK=FLLREFCLK=XT1 SMCLK=MCLK=DCOCLKDIV XT2关闭 
    62.    * 为了不产生XT1LFOFFG,将ACLK和FLLREFCLK设置为REFOCLK 
    63.    * 并打开XT2OFF,否则XT2将处于无法使用状态 
    64.    * */  
    65.   //UCSCTL6 &= ~(XT2DRIVE0|XT2DRIVE1|XT2OFF);  
    66.   
    67.   while (SFRIFG1 & OFIFG) {                               // Check OFIFG fault flag  
    68.     UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);         // Clear OSC flaut Flags  
    69.     SFRIFG1 &= ~OFIFG;                                  // Clear OFIFG fault flag  
    70.   }  
    71.   
    72.   UCSCTL4 = UCSCTL4&(~(SELS_7|SELM_7))|SELS_3|SELM_3;  
    73.   
    74.   while(1){  
    75.     P1OUT ^= BIT1;  
    76.     delay();  
    77.   }  
    78. }


    ————————————————
    版权声明:本文为CSDN博主「wzx@seu」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/wzx104104104/article/details/109105687

  • 相关阅读:
    微信小程序毕业设计论文医院挂号预约系统+后台管理系统项目源代码
    视频监控/视频汇聚/安防视频监控平台EasyCVR配置集群后有一台显示离线是什么原因?
    Real-Time Rendering——8.2.3 Color Grading颜色分级
    Java基础错题集(一)
    【NLP】第 7 章:使用序列到序列神经网络进行文本翻译
    Java&C++题解与拓展——leetcode513.找树最下角的值【么的新知识】
    RFLA: Gaussian Receptive Field based Label Assignment for Tiny Object Detection
    C#设计模式---工厂方法模式
    C++ pair的介绍和使用输出
    数据分析,从了解你的数据开始,数据探索性分析工具包pandas-profiling
  • 原文地址:https://blog.csdn.net/qq_33301482/article/details/133899622