MSP430时钟配置.docx
《MSP430时钟配置.docx》由会员分享,可在线阅读,更多相关《MSP430时钟配置.docx(12页珍藏版)》请在冰豆网上搜索。
![MSP430时钟配置.docx](https://file1.bdocx.com/fileroot1/2022-11/25/c19a38ce-f964-4e41-ad6e-97233bd6588b/c19a38ce-f964-4e41-ad6e-97233bd6588b1.gif)
MSP430时钟配置
本实验的目的是了解用于执行对MSP430ValueLine设备的初始化过程的步骤。
在这个练习中,您将编写初始化代码,并运行该设备使用各种时钟资源。
时钟介绍:
1、在MSP430单片机中一共有三个时钟源:
一个LFXT1CLK,为低速/高速晶振源,通常接32.768khz,也可以接(400khz~8Mhz);
一个为XT2CLK,外接标准高速晶振,通常是接8Mhz,也可以接(400khz~8Mhz);
还有一个叫DCOCLK,为内部晶振,有RC震荡回路构成。
2、在MSP430单片机内部一共有三个时钟系统:
一个为ACLK(Auxiliaryclock),通常由LFXT1CLK作为时钟源,可以通过软件控制改时钟的分频系数树;
一个为MCLK(MainCLK)一听就知道是主时钟单元,为系统内核提供时钟,它可以通过软件从三个时钟源选择;
还有一个为SMCLK(Sub-Mainclock),称作系统子时钟,也是可以由软件选择时钟源。
BasicClockModuleRegisters(基础时钟寄存器)
DCOcontrolregister
Basicclocksystemcontrol1
Basicclocksystemcontrol2
Basicclocksystemcontrol3
SFRinterruptenableregister1
SFRinterruptflagregister1
3、MSP430的时钟设置包括3个寄存器,DCOCTL、BCSCTL1、BCSCTL2、BCSCTL3
DCOCTL,DCO控制寄存器,地址为56H,初始值为60H
DCO2
DCO1
DCO0
MOD4
MOD3
MOD2
MOD1
MOD0
DCO0~DCO2:
DCOSelectBit,定义了8种频率之一,而频率由注入直流发生器的电流定义。
MOD0~MOD4:
ModulationBit,频率的微调。
一般不需要DCO的场合保持默认初始值就行了。
BCSCTL1,BasicClockSystemControl1,地址为57H,初始值为84H
XT2OFF
XTS
DIVA1
DIVA0
XT5V
RSEL2
RSEL1
RSEL0
RSEL0~RSEL2:
选择某个内部电阻以决定标称频率.0最低,7最高。
XT5V:
1.
DIVA0~DIVA1:
选择ACLK的分频系数。
DIVA=0,1,2,3,ACLK的分频系数分别是1,2,4,8;
XTS:
选择LFXT1工作在低频晶体模式(XTS=0)还是高频晶体模式(XTS=1)。
XT2OFF:
控制XT2振荡器的开启(XT2OFF=0)与关闭(XT2OFF=1)。
正常情况下把XT2OFF复位就可以了.
BCSCTL2,BasicClockSystemControl2,地址为58H,初始值为00H
SEM1
SELM0
DIVM1
DIVM0
SELS
DIVS1
DIVS0
DCOR
DCOR:
EnableExternalResistor.0,选择内部电阻;1,选择外部电阻
DIVS0~DIVS1:
DIVS=0,1,2,3对应SMCLK的分频因子为1,2,4,8
SELS:
选择SMCLK的时钟源,0:
DCOCLK;1:
XT2CLK/LFXTCLK.
DIVM0~1:
选择MCLK的分频因子,DIVM=0,1,2,3对应分频因子为1,2,4,8.
SELM0~1:
选择MCLK的时钟源,0,1:
DCOCLK,2:
XT2CLK,3:
LFXT1CLK
我用的时候一般都把SMCLK与MCLK的时钟源选择为XT2。
其它:
1.LFXT1:
一次有效的PUC信号将使OSCOFF复位,允许LFXT1工作,如果LFXT1信号没有用作SMCLK或MCLK,可软件置OSCOFF关闭LFXT1.
2.XT2:
XT2产生XT2CLK时钟信号,如果XT2CLK信号没有用作时钟MCLK和SMCLK,可以通过置XT2OFF关闭XT2,PUC信号后置XT2OFF,即XT2的关闭的。
3.DCO振荡器:
振荡器失效时,DCO振荡器会自动被选做MCLK的时钟源。
如果DCO信号没有用作SMCLK和MCLK时钟信号时,可置SCG0位关闭DCO直流发生器。
4.在PUC信号后,由DCOCLK作MCLK的时钟信号,根据需要可将MCLK的时钟源另外设置为LFXT1或XT2,设置顺序如下:
(1)清OSCOFF/XT2
(2)清OFIFG
(3)延时等待至少50uS
(4)再次检查OFIFG,如果仍置位,则重复
(1)-(4)步,直到OFIFG=0为止。
(5)设置BCSCTL2的相应SELM。
实例分析:
1、CPU运行在VLO时钟下:
(超低频振荡器(VLO)与数控振荡器(DCO)是两个独立的时钟系统)这是最慢的时钟,在约12千赫兹下运行。
因此,我们将通过可视化的LED闪烁的红色慢慢地在约每3秒钟率。
我们可以让时钟系统默认这种状态,设置专门来操作VLO。
我们将不使用任何ALCK外设时钟在此实验室工作,但你应该认识到,ACLK来自VLO时钟。
(F2xx增加了一个新的超低功耗晶振VLO(12kHz),具有500nA的待机模式。
他的使用与LFXT1互斥。
BCSCTL3|=LFXT1S1;//ACLK来源于VLO)
#include
voidmain(void)
{
WDTCTL=WDTPW+WDTHOLD;关闭看门狗定时器
P1DIR=0x40;配置输出
P1OUT=0;关闭LED
BCSCTL3|=LFXT1S_2;
IFG1&=~OFIFG;清除OSCFault标志
__bis_SR_register(SCG1+SCG0);关闭DCO
BCSCTL2|=SELM_3+DIVM_3;
while
(1)
{
P1OUT=0x40;开启LED
_delay_cycles(100);
P1OUT=0;关闭LED
_delay_cycles(5000);
}
}
2、CPU运行在晶振(32768Hz)时钟下:
晶体频率为32768赫兹,约3倍的VLO。
如果我们在前面的代码中使用晶振,指示灯应闪烁大约每秒一次。
你知道为什么32768赫兹是一个标准?
这是因为这个数字是2的15次方,因此很容易用简单的数字计数电路,以每秒一次获得率——手表和其他时间时基。
认识到ACLK来自外部晶振时钟。
#include
voidmain(void)
{
WDTCTL=WDTPW+WDTHOLD;关闭看门狗定时器
P1DIR=0x41;和P1.6配置输出
P1OUT=0x01;开启P1.0
BCSCTL3|=LFXT1S_0;晶振
while(IFG1&OFIFG)
{
IFG1&=~OFIFG;清除OSCFault标志
_delay_cycles(100000);为可见的标志延时
}
P1OUT=0;关闭P1
__bis_SR_register(SCG1+SCG0);关闭DCO
BCSCTL2|=SELM_3+DIVM_3;
while
(1)
{
P1OUT=0x40;开启LED
_delay_cycles(100);
P1OUT=0;关闭LED
_delay_cycles(5000);
}
}
3、CPU运行在晶振(32768Hz)和DCO时钟下:
最慢的频率,我们可以运行DCO约在1MHz(这也是默认速度)。
因此,我们将开始切换MCLK到DCO下。
在大多数系统中,你会希望ACLK上运行的VLO或32768赫兹晶振。
由于ACLK在我们目前的代码是在晶体上运行,我们会打开DCO计算。
#include
voidmain(void)
{
WDTCTL=WDTPW+WDTHOLD;关闭看门狗定时器
if(CALBC1_1MHZ==0xFF||CALDCO_1MHZ==0xFF)
{
while
(1);挂起
}
BCSCTL1=CALBC1_1MHZ;
DCOCTL=CALDCO_1MHZ;设置DCO模式
P1DIR=0x41;和P1.6配置输出
P1OUT=0x01;开启
BCSCTL3|=LFXT1S_0;
while(IFG1&OFIFG)
{
IFG1&=~OFIFG;清除OSCFault标志
_delay_cycles(100000);为可见标志延时
}
P1OUT=0;关闭
//__bis_SR_register(SCG1+SCG0);关闭DCO
BCSCTL2|=SELM_0+DIVM_3;
while
(1)
{
P1OUT=0x40;开启
_delay_cycles(100);
P1OUT=0;关闭
_delay_cycles(5000);
}
}
4、CPU运行在DCO时钟下:
最慢的频率,我们可以运行DCO约在1MHz(这也是默认速度)。
因此,我们将开始切换MCLK到DCO下。
在大多数系统中,你会希望在VLO或者是晶振下运行ACLK。
由于ACLK在我们目前的代码是在VLO上运行,我们会打开DCO运行。
#include
voidmain(void)
{
WDTCTL=WDTPW+WDTHOLD;关闭看门狗定时器
if(CALBC1_1MHZ==0xFF||CALDCO_1MHZ==0xFF)
{
while
(1);挂起
}
BCSCTL1=CALBC1_1MHZ;
DCOCTL=CALDCO_1MHZ;设置DCO模式
P1DIR=0x40;配置输出
P1OUT=0;关闭
BCSCTL3|=LFXT1S_2;
IFG1&=~OFIFG;清除OSCFault标志
//__bis_SR_register(SCG1+SCG0);关闭DCO
BCSCTL2|=SELM_0+DIVM_3;
while
(1)
{
P1OUT=0x40;关闭
_delay_cycles(100);
P1OUT=0;开启
_delay_cycles(5000);
}
}
以下将会分析上面4个例子的代码细微差别:
首先让我们看一下msp430x20x2.h这个文件中的内容,由于头文件信息量很大这里就只简单说明和以上四个代码有关的部分,其余请大家自行阅读。
一、WDTCTL=WDTPW+WDTHOLD;//关闭看门狗定时器(例1、2、3、4)
头文件中的相关说明如下:
/************************************************************
*WATCHDOGTIMER
************************************************************/
#define__MSP430_HAS_WDT__/*DefinitiontoshowthatModuleisavailable*/
SFR_16BIT(WDTCTL);/*WatchdogTimerControl*/
/*Thebitnameshavebeenprefixedwith"WDT"*/
#defineWDTIS0(0x0001)
#defineWDTIS1(0x0002)
#defineWDTSSEL(0x0004)
#defineWDTCNTCL(0x0008)
#defineWDTTMSEL(0x0010)
#defineWDTNMI(0x0020)
#defineWDTNMIES(0x0040)
#defineWDTHOLD(0x0080)
#defineWDTPW(0x5A00)
这个指令设置密码(WDTPW)和停止位定时器(WDTHOLD),所有的WatchDog配置都需要在WDTPW的辅助下完成。
举例如下:
A、间隔时间由Bit0-2位编码:
1、看门狗的时钟由FSMCLK(假设为1MHz)
#defineWDT_MDLY_32(WDTPW+WDTTMSEL+WDTCNTCL)/*32msinterval(default)*/
#defineWDT_MDLY_8(WDTPW+WDTTMSEL+WDTCNTCL+WDTIS0)/*8ms"*/
#defineWDT_MDLY_0_5(WDTPW+WDTTMSEL+WDTCNTCL+WDTIS1)/*0.5ms"*/
#defineWDT_MDLY_0_064(WDTPW+WDTTMSEL+WDTCNTCL+WDTIS1+WDTIS0)/*0.064ms"*/
2、看门狗的时钟由FACLK(假设为32KHz)
#defineWDT_ADLY_1000(WDTPW+WDTTMSEL+WDTCNTCL+WDTSSEL)/*1000ms"*/
#defineWDT_ADLY_250(WDTPW+WDTTMSEL+WDTCNTCL+WDTSSEL+WDTIS0)/*250ms"*/
#defineWDT_ADLY_16(WDTPW+WDTTMSEL+WDTCNTCL+WDTSSEL+WDTIS1)/*16ms"*/
B、看门狗模式——在过期时间后重启:
1、看门狗的时钟由FSMCLK(假设为1MHz)
#defineWDT_MRST_32(WDTPW+WDTCNTCL)/*32msinterval(default)*/
#defineWDT_MRST_8(WDTPW+WDTCNTCL+WDTIS0)/*8ms"*/
#defineWDT_MRST_0_5(WDTPW+WDTCNTCL+WDTIS1)/*0.5ms"*/
#defineWDT_MRST_0_064(WDTPW+WDTCNTCL+WDTIS1+WDTIS0)/*0.064ms"*/
2、看门狗的时钟由FACLK(假设为32KHz)
#defineWDT_ARST_1000(WDTPW+WDTCNTCL+WDTSSEL)/*1000ms"*/
#defineWDT_ARST_250(WDTPW+WDTCNTCL+WDTSSEL+WDTIS0)/*250ms"*/
#defineWDT_ARST_16(WDTPW+WDTCNTCL+WDTSSEL+WDTIS1)/*16ms"*/
#defineWDT_ARST_1_9(WDTPW+WDTCNTCL+WDTSSEL+WDTIS1+WDTIS0)/*1.9ms"*/
二、P1DIR=0x40;//P1.6配置输出
P1OUT=0;//P1关闭(例1、2、3、4)
其中DIR和P1OUT分别配置IO口的方向和输出值,这里不在赘述,请参考手册。
三、BCSCTL3|=LFXT1S_2;//LFXT1=VLO(例1和例4)
BCSCTL3|=LFXT1S_0;//LFXT1=32768Hz(例2和例3)
/************************************************************
*BasicClockModule
************************************************************/
#define__MSP430_HAS_BC2__
/*DefinitiontoshowthatModuleisavailable*/
SFR_8BIT(DCOCTL);/*DCOClockFrequencyControl*/
SFR_8BIT(BCSCTL1);/*BasicClockSystemControl1*/
SFR_8BIT(BCSCTL2);/*BasicClockSystemControl2*/
SFR_8BIT(BCSCTL3);/*BasicClockSystemControl3*/
#defineMOD0(0x01)/*ModulationBit0*/
#defineMOD1(0x02)/*ModulationBit1*/
#defineMOD2(0x04)/*ModulationBit2*/
#defineMOD3(0x08)/*ModulationBit3*/
#defineMOD4(0x10)/*ModulationBit4*/
#defineDCO0(0x20)/*DCOSelectBit0*/
#defineDCO1(0x40)/*DCOSelectBit1*/
#defineDCO2(0x80)/*DCOSelectBit2*/
#defineLFXT1OF(0x01)
/*Low/highFrequencyOscillatorFaultFlag*/
#defineXT2OF(0x02)
/*Highfrequencyoscillator2faultflag*/
#defineXCAP0(0x04)/*XIN/XOUTCap0*/
#defineXCAP1(0x08)/*XIN/XOUTCap1*/
#defineLFXT1S0(0x10)/*Mode0forLFXT1(XTS=0)*/
#defineLFXT1S1(0x20)/*Mode1forLFXT1(XTS=0)*/
#defineXT2S0(0x40)/*Mode0forXT2*/
#defineXT2S1(0x80)/*Mode1forXT2*/
#defineXCAP_0(0x00)/*XIN/XOUTCap:
0pF*/
#defineXCAP_1(0x04)/*XIN/XOUTCap:
6pF*/
#defineXCAP_2(0x08)/*XIN/XOUTCap:
10pF*/
#defineXCAP_3(0x0C)/*XIN/XOUTCap:
12.5pF*/
#defineLFXT1S_0(0x00)
/*Mode0forLFXT1:
Normaloperation*/
#defineLFXT1S_1(0x10)/*Mode1forLFXT1:
Reserved*/
#defineLFXT1S_2(0x20)/*Mode2forLFXT1:
VLO*/
#defineLFXT1S_3(0x30)
/*Mode3forLFXT1:
Digitalinputsignal*/
#defineXT2S_0(0x00)/*Mode0forXT2:
0.4-1MHz*/
#defineXT2S_1(0x40)/*Mode1forXT2:
1-4MHz*/
#defineXT2S_2(0x80)/*Mode2forXT2:
2-16MHz*/
#defineXT2S_3(0xC0)
/*Mode3forXT2:
Digitalinputsignal*/
四、__bis_SR_register(SCG1+SCG0);//关闭DCO
__bis_SR_register()是在intrinsics.h这个头文件中定义了,实现的功能是将SR中的位置零。
关于头文件中的代码作用
#ifdef__cplusplus
extern"C"
{
#endif
#ifdef__cplusplus
}
#endif/*extern"C"*/
一般用于将C++代码以标准C形式输出(即以C的形式被调用),这是因为C++虽然常被认为是C的超集,但是C++的编译器还是与C的编译器不同的。
C中调用C++中的代码这样定义会是安全的。
五、BCSCTL2|=SELM_3+DIVM_3;//MCLK=VLO/8
BCSCTL2|=SELM_3+DIVM_3;//MCLK=32768/8
BCSCTL2|=SELM_0+DIVM_3;//MCLK=DCO
BCSCTL2|=SELM_0+DIVM_3;//MCLK=DCO/8
MSP430中有如下定义:
#defineRSEL0(0x01)/*RangeSelectBit0*/
#defineRSEL1(0x02)/*RangeSelectBit1*/
#defineRSEL2(0x04)/*RangeSelectBit2*/
#defineRSEL3(0x08)/*RangeSelectBit3*/
#defineDIVA0(0x10)/*ACLKDivider0*/
#defineDIVA1(0x20)/*ACLKDivider1*/
#defineXTS(0x40)
/*LFXTCLK0:
LowFreq./1:
HighFreq.*/
#defineXT2OFF(0x80)/*EnableXT2CLK*/
#defineDIVA_0(0x00)/*ACLKDivider0:
/1*/
#defineDIVA_1(0x10)/*ACLKDivider1:
/2*/
#defineDIVA_2(0x20)/*ACLKDivider2:
/4*/
#defineDIVA_3(0x30)/*ACLKDivider3:
/8*/
#defineDIVS0(0x02)/*SMCLKDivider0*/
#defineDIVS1(0x04)/*SMCLKDivider1*/
#defineSELS(0x08)
/*SMCLKSourceSelect0:
DCOCLK/1:
XT2CLK/LFXTCLK*/
#defineDIVM0(0x10)/*MCLKDivider0*/
#defineDIVM1(0x20)/*MCLKDivider1*/
#defineSELM0(0x40)