×
单片机 > 单片机程序设计 > 详情

MSP430时钟配置

发布时间:2020-08-27 发布时间:
|

大家都知道MSP430是一款低功耗的单片机,超低功耗一直都是MSP430系列单片机的口号,为了适应各种功耗要求,比如在用电池供电的场合下,对于功耗是个严峻的挑战,所以MSP430单片机可以配置3种时钟振荡器,这3种时钟振荡器分别为:低频时钟源LFXT1CLK、高频时钟源XT2CLK、数字控制RC振荡器DCOCLK。其中DCOCLK是在单片机内部,实际上就是RC振荡器,并且可编程。配置在保持默认时,时钟频率大概在1MHz左右(这个是实际测试出来的),规格书有的讲在800KHz左右。在MSP430的时钟模块就有3个,分别为:辅助时钟ACLK 、主时钟MCLK 、子系统时钟SMCLK。


下面我来看这3个时钟模块的时钟源可以来自于哪些:

1. ACLK:LFXT1CLK信号经1/2/4/8分频后得到的,主要用作低速外围的时钟。

2. MCLK:LFXT1CLK,XT2CLK,DCOCLK的三者之一决定,由软件选择,然后经1/2/4/8分频后得到,主要用于CPU和系统。

3. SMCLK:LFXT1CLK和DCOCLK,或者XT2CLK与DCOCLK决定,然后经1/2/4/8分频后得到,主要用于高速外围模块,比如SPI模块等。


下面我们就看如何配置时钟:

MSP430的时钟模块由DCOCTL,BCSCTL1,BCSCTL2,IFG1这几个寄存器来确定,具体的功能如下所示:


1. DCOCTL:DCO Control Register,地址为56H,初始值为60H

 

BIT:DCO0~DCO2:定义了8种频率之一,而频率由注入直流发生器的电流定义

BIT:MOD0~MOD4:频率的微调


2. BCSCTL1:Basic Clock System Control Register 1,地址为58H,初始值为84H

 

BIT:XT2OFF:控制XT2振荡器的开启(XT2OFF=0)与关闭(XT2OFF=1)

BIT:XTS:选择LFXT1工作在低频晶体模式(XTS=0)还是高频晶体模式(XTS=1)

BIT:DIVA0~DIVA1:选择ACLK的分频系数。DIVA=0,1,2,3(DIVA_0,DIVA_1...),ACLK的分频系数分别为:1,2,4,8

BIT:RSEL2~RSEL0:选择某个内部电阻以决定标称频率(0最低,7最高)


3. BCSCTL2:Basic Clock System Control Register 2,地址为58H,初始值为00H


BIT:SELM0~SELM1:选择MCLK的时钟源,00或者01:DCOCLK;10:XT2CLK;11:LFXT1CLK

BIT:DIVM0~DIVM1:选择MCLK的分频因子,DIVM=0,1,2,3,对应MCLK的分频因子为1,2,4,8

BIT:SELS:选择SMCLK的时钟源,0:DCOCLK;1:XT2CLK/LFXTCLK

BIT:DIVS0~DIVS1:DIVS=0,1,2,3,对应SMCLK的分频因子为1,2,4,8

BIT:DCOR:0—选择内部电阻,1—选择外部电阻


4. IFG1:Interrupt Flag Register 1


BIT:OFIE:振荡器故障中断标志位 0:没有故障;1:有故障


详细的看了这几个寄存器后,感觉是不是还是搞不懂是吧。没关系很正常,下面我们就来看DCO是如何配置:

1.0 设置BCSCTL2寄存器中的DCOR来选择是外部电阻还是内部电阻,以确定一个基准频率。

2.0 通过BCSCTL1寄存器的RSELx来进行分频,确定时钟频率。

3.0 通过DCOCTL寄存器中DCOx在标称频率基础上分段粗调,选择频率。

4.0 通过DCOCTL寄存器中MODx的值对频率进行细调,选择DCOx与DCOx+1之间的频率。


例子:

DCOCTL初始值为60H,即DCOCTL |= DCO1 + DCO2;

DCOCTL |= DCO0 + DCO1 + DCO2;// Max DCO

//MOD0~MOD4:Modulation Bit,频率的微调一般保持默认即可

//系统默认情况下,RSELx=4


下面我们再来看如何配置外面高速时钟:

由于在PUC信号后,默认情况下由DCOCLK作MCLK与SMCLK的时钟信号,DCOCTL初始值为60H,频率比较低,所有需要高速运行的则要将MCLK的时钟源另外设置为LFXT1或者XT2,设置的一般顺序如下:

1.0 清OSCOFF/XT2

2.0 清OFIFG

3.0 延时等待至少50us

4.0 再次检查OFIFG,如果仍置位,则重复(1)~(4)步,直到OFIFG=0为止

5.0 设置BCSCTL2的相应SELM


例子:一般的初始化程序

void Clock_Init(void)

{

    unsigned int i;

    BCSCTL1=0x00;//XT2开启,LFXTCLK为低频模式,ACLK分频为0

    do

    {

        IFG1&=~OFIFG;

        for(i=0x20;i>0;i--);

    }

    while((IFG1&OFIFG)==OFIFG);//当OSCFault=1 即晶振不起振则等待

    BCSCTL2=0X00;

    BCSCTL2|=SELM1;//MCLK 时钟为XT2,

    BCSCTL2|=SELS;//SMCLK时钟为XT2

}


这个例子我为什么说一般的初始化咧,有个位置就是在判断晶振状态的while语句,如果外部晶振的真的有问题那程序是不是就一直死在此地方?我就想问下,内部没有问题为何不切换到内部?虽然内部时钟比较慢,但是我系统好歹可以运行,所以在我写的程序里都加入了时钟状态判断时间,下面就是我用的初始化,当然这只是个用法,大家如果还有什么更好的方法可以贴出来,分享分享


//系统时钟初始化

//MCLK=16MHz

//SMCLK=8MHz

//ACLK=32.678KHz

void Clock_Init(void)

{

        unsigned int time = 10000;//外部时钟在这个时间内如果还是不能起振则选择内部时钟

        

        BCSCTL1 &= 0x00;//开启XT2振荡器,LFXT1工作在低频晶体模式,ACLK的分频系数0

        do

        {

                IFG1 &= ~OFIFG;//清OFIFG标记

                __delay_cycles(100);//在外部晶振还没有起振时,时钟来源于内部大概1MHz的DCO

        }

        while((IFG1 & OFIFG) && time--);//查询时钟切换成功

        if(time == 0)//外部时钟有问题

        {

                BCSCTL1 |= XT2OFF;//关闭XT2振荡器

        }

        else//切换成功

        {

                BCSCTL2 &= 0x00;

                BCSCTL2 |= SELM1+SELS+DIVS0;//MCLK与SMCLK的时钟源为XT2,SMCLK的分频系数2 

        }                

}

关键字:MSP430  时钟配置  分频系数

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
如何为单片机选择合适的负载电容