What
上一节中提到了延时函数,延时函数的基本原理就是CPU每执行一条语句需要一定固定的时间,而提供这个时间基准的就是单片机的时钟信号。
时钟信号来源于一定的时钟源,它们是时钟源经过被选择和分频产生的。时钟源由一定的硬件电路产生,例如晶振和其他各种振荡器。时钟源类似于人体的心脏、汽车的发动机。
而在G2553中共有3种时钟源和3种时钟信号
G2553的时钟源:
- LFXT1CLK: 低速/高速晶振源,通常接32.768khz;
- DCOCLK: 内部晶振,由RC 震荡回路构成;
- VLOCLK: 片内超低功耗、12KHz 的低频振荡器。
G2553的3种系统时钟信号:
- ACLK,辅助时钟,通常由LFXT1CLK 或VLO 作为时钟源,可1、2、4、8 分频,可做外设时钟;一般是由32.768KHz 晶体直接产生的低频时钟,也可以是片内超低功耗12KHz 的内部振荡器VLOCK,用于产生节拍时基,或和定时器配合间歇唤醒CPU。
- MCLK(Main CLK): 主时钟单元,通常由LFXT1CLK、VLO或DCO 作为时钟源,可1、2、4、8 分频,用于CPU 和系统;是专门为CPU 运行提供时钟,MCLK 配置的越高,CPU 执行速度就越快。MCLK 一般都设在1MHz 以上发挥CPU 性能。
- SMCLK, 子系统时钟,通常由LFXT1CLK、VLO 或DCO 作为时钟源,可1、2、4、8 分频,可做外设时钟;单片机内部某些设备需要高速时钟(如定时器、ADC 等),SMCLK 为这些需要高速工作的设备提供时钟源,并且SMCLK 是独立于MCLK 的;当关闭主时钟MCLK让CPU 停止工作时,子系统时钟SMCLK 仍然可以开启,从而让外设继续工作。
需要注意:
- 内部的振荡器DCO 和VLO 提供的时钟频率不是很精确,随外部环境变化较大;
- 使用超低功耗低频振荡器VLO 可以很大程度地降低系统功耗;
- 系统上电后默认使用的是DCO 时钟。
- PUC(Power-Up Clear) 后MSPG430G2253 默认的MCLK 和SMCLK 为1.1MHz 左右的DCOCLK。
How
DCO是数字振荡控制器,因此DCO的频率可以通过软件程序赋值相应寄存器来控制,所以基本时钟配置所涉及到的范围大概为:DCO时钟源的频率配置;各时钟信号选择何种时钟源;需要做怎样的分频。
DCO频率配置
对G2553来说,单片机在生产时其内部就已经预置好了一定时钟频率的配置,用户只需要根据数据表的寄存器配置要求配置即可更加方便快捷地得到相应常用的频率。
其他基本配置
对于其他基本时钟寄存器配置及功能可见用户指南280~284页。
举例
#include <msp430.h>
void Delay_ms(unsigned cnt)
{
unsigned int i,j;
for(j=0;j<cnt;j++)
{
i=1000/6;
while(i--);
}
}
int main(void)
{
WDTCTL = WDTPW +WDTHOLD; // 关闭看门狗
//1Mhz
if (CALBC1_1MHZ==0xFF) // If calibration constant erased
{
while(1); // do not load, trap CPU!!
}
DCOCTL = 0; // Select lowest DCOx and MODx settings
BCSCTL1 = CALBC1_1MHZ; // Set range
DCOCTL = CALDCO_1MHZ; // Set DCO step + modulation */
/*//8Mhz
if (CALBC1_8MHZ==0xFF) // If calibration constant erased
{
while(1); // do not load, trap CPU!!
}
DCOCTL = 0; // 设置DCOx和MODx
BCSCTL1 = CALBC1_8MHZ;
DCOCTL = CALDCO_8MHZ; // 设置DCO频率为8M */
/* //12Mhz
if (CALBC1_12MHZ==0xFF) // If calibration constant erased
{
while(1); // do not load, trap CPU!!
}
DCOCTL = 0; // Select lowest DCOx and MODx settings
BCSCTL1 = CALBC1_12MHZ; // Set range
DCOCTL = CALDCO_12MHZ; // Set DCO step + modulation*/
/*//16Mhz
if (CALBC1_16MHZ==0xFF) // If calibration constant erased
{
while(1); // do not load, trap CPU!!
}
DCOCTL = 0; // Select lowest DCOx and MODx settings
BCSCTL1 = CALBC1_16MHZ; // Set range
DCOCTL = CALDCO_16MHZ; // Set DCO step + modulation*/
BCSCTL1|=DIVA_3;
BCSCTL2|=DIVS_3;
P1DIR |= (BIT0+BIT1+BIT4); // 设置P1.0,1 和 P1.4 为输出
P1SEL |= (BIT0+BIT4); // 设置P1.0为ACLK输出, p1.4为SMCLK输出
while(1)
{
P1OUT|=(BIT4+BIT1+BIT0); //间断给P1.0/1/4赋值1和0,然而P1.4/1不是数字I/O功能,所以没有什么卵用,它们不由MCLK控制
Delay_ms(1000);
P1OUT&=~(BIT4+BIT1+BIT0);
Delay_ms(1000);
}
}
效果如下
基本时钟配置效果
Task
编写LED1闪灯程序,编写延迟函数,延时时间1s,实现循环间隔1s的亮灭。
没什么好分析的直接上代码
#include "io430.h"
void Delay_ms(unsigned cnt)
{
unsigned int i,j;
for(j=0;j<cnt;j++)
{
i=1000/6;
while(i--);
}
}
int main( void )
{
// Stop watchdog timer to prevent time out reset
WDTCTL = WDTPW + WDTHOLD;
DCOCTL=0;
BCSCTL1=CALBC1_1MHZ;
DCOCTL=CALDCO_1MHZ;
P1DIR|=BIT0;
P1OUT&=~BIT0;
while(1)
{
P1OUT^=BIT0;
Delay_ms(1000);
}
}
这个task还可以用后面定时器中断来处理,之后再说。
sao话一下
还记得电影《大鱼海棠》里的一句台词吗?这短短的一生我们最终都会失去,你不妨大胆一些,老子整把AK,给你龟儿弄把来福,rnw,做大做强,再创辉煌。