(1)时钟的概念
有问题发送邮件至468078841@qq.com
时钟是生活中常用的一种计时器,人们通过它来记录时间。我们见过的包括有,日晷、沙漏、机械钟、石英钟。这时候就存在一个问题 ,那就是如何去衡量一小时呢,如果我们使用现在最常见的手表记时,那么一个小时就是六十分钟,对于小时这个单位来说,他只能算一个单位,迈了一步,相对于分钟来说,那就是六十个单位,迈了六十步,所以说时钟的概念一定要理解清楚。
在我们的cc2530中就有很多时钟,这时候就可以得知,当我们给cc2530设置了不同的时钟,那么其记时的单位也不一样,同样的六十个单位,但表达就是不一样长短的时间。(在这里可以理解二个身高不一样高的人,他们去测十米的长度,个子高的步数就短,个子矮的步子就多)可以理解为改变时钟为使用不同的度量衡。
二.cc2530时钟源
(一) 2个高频振荡器
振荡器(英文:oscillator)是用来产生重复电子讯号(通常是正弦波或方波)的电子元件。
1.32 MHz 晶振
2.16 MHzRC振荡器
TIP
(1)32MHz晶振启动时间对一些应用程序来说可能比较长
(2)16MHzRC振荡器功耗低于晶振,但是由于不像晶振那么精确,不能用于RF收发器操作
(一)系统时钟是从所选的主系统时钟源获得的,主系统时钟源可以是32 MHz XOSC 或16 MHz RCOSC。注意要使用RF 收发器,必须选择高速且稳定的32 MHz 晶振。
(二)2个低频振荡器
1.32 kHz 晶振
2.32 kHzRC振荡器
TIP
(1)这两个32kHz振荡器不能同时运行
(2)默认复位后32 kHz RCOSC 使能,被选为32 kHz 时钟源。RCOSC 功耗较少,但是不如32 kHz XOSC 精确。所选的32 kHz 时钟源驱动睡眠定时器,为看门狗定时器产生标记,当计算睡眠定时器睡眠时间的时候用作定时器2 的一个选通命令。选择哪个振荡器用作32 kHz 时钟源是通过CLKCONCMD.OSC32K 寄存器位执行的。
(3)注意改变CLKCONCMD.OSC 位不会立即改变系统时钟。时钟源的改变首先在CLKCONSTA.OSC =CLKCONCMD.OSC 的时候生效。这是因为在实际改变时钟源之前需要有稳定的时钟。还要注意CLKCONCMD.CLKSPD 位反映系统时钟的频率,因此是CLKCONCMD.OSC 位的映像。选择了32 MHz XOSC 且稳定之后,即当CLKCONSTA.OSC 位从1 变为0,16 MHz RC 振荡器就被校准
三.cc2530时钟寄存器
通过前面的学习我们知道了要想使cc2530的芯片引脚行使某功能,就必须要通过寄存器对引脚进行初始化,在这里我们将提到时钟的二个相关的寄存器。
(一)CLKCONCMD时钟控制寄存器
我们通过对CLKCONCMD(可写可读)寄存器进行写入时钟的选择详
看下图:
1.CLKCONCMD.OSC 位是改变主系统时钟的源。
2.时器3和定时器4的所有定时器功能都是基于主要的8位计数器建立的。计数器在每个时钟边沿递增或递减。活动时钟边沿的周期由寄存器位CLKCONCMD.TICKSPD[2:0]定义,由TxCTL.DIV[2:0](其中x指的是定时器号码, 3或4)设置的分频器值进一步划分。计数器可以作为一个自由运行计数器,倒计数器,模计数器或正/倒计数器运行
简略
练习
(1)使用外部时钟源,工作频率8M
分析:外部时钟源是要让第六位置0 让2-0位位 010
//先改变时钟源
CLKCONCMD &= ~0x40; //0x40 = 0100 0000 取反第六位为0
//再改变分频
//因为是要将2-0设置为010 未了不耽误其他位 我们将分二步进行
CLKCONCMD |= 0x02;//置1
CLKCONCMD &= ~0x05; //0000 0101 取反1111 1010
(2)使用内部时钟源 8M
分析:内时钟源是要让第六位置1 让2-0位位 001
CLKCONCMD |= 0x40; //0100 0000 内部时钟源
//8M是001
CLKCONCMD |= 0x01;//置1
CLKCONCMD &= ~0x06 ;//置0 这一步是为了确定全面置0
(二)CLKCONSTA (只能读)时钟控制状态
通过检测CLKCONSTA寄存器来判断系统主时钟源是否改变。
在前面我们讲过改变CLKCONCMD.OSC 位不会立即改变系统时钟也就是表格中的第六位,这样的话我们必须要通过CLKCONSTA寄存器状态来判断我们是否改变了时钟源,对是上面的代码进行完善;
(1)使用外部时钟源,工作频率8M
分析:外部时钟源是要让第六位置0 让2-0位位 010
//先改变时钟源 //这里成功 那么CLKCONCMD状态为X0XX XXXX
CLKCONCMD &= ~0x40; //0x40 = 0100 0000 取反第六位为0
while(CLKCONCMD & 0x40); //如果第六位成功X0XX XXXX & 0100 0000 为假 跳出while
//再改变分频
//因为是要将2-0设置为010 未了不耽误其他位 我们将分二步进行
CLKCONCMD |= 0x02;//置1
CLKCONCMD &= ~0x05; //0000 0101 取反1111 1010
(2)使用内部时钟源 8M
分析:内时钟源是要让第六位置1 让2-0位位 001
CLKCONCMD |= 0x40; //0100 0000 内部时钟源
while(!(CLKCONCMD & 0x40))
//8M是001
CLKCONCMD |= 0x01;//置1
CLKCONCMD &= ~0x06 ;//置0 这一步是为了确定全面置0
四.cc2530的时钟实战
题目要求
使用外部时钟源,32M;使用内部时钟源 8M,在相同的LED灯闪烁代码下进行对比;
#include "ioCC2530.h" //引入头文件 类似C语言 #include"stdio.h"
#define D4 P1_0 //宏 定义引脚为端口 方便记忆
#define D2 P1_1
#define D3 P1_2
enum Clock_RC{RC_32MHz,RC_8MHz}; // 定义系统时钟源(主时钟源)枚举类型
void LED_INIT(void); //函数申明 这里建议书写规范
void LED_blink(void);
void delay(unsigned int time);
void SystemClockSourceSelect(enum Clock_RC source);
void delay(unsigned int time) //延时函数 这里是为了让程序多执行几次for循环 让函数延时
{
for(unsigned char j = 0; j < time;j++)
{
for(unsigned int i = 0; i < time; i++)
{
}
}
}
void LED_blink(void)
{
D4 = !D4;
D2 = !D2;
D3 = !D3;
delay(200);
}
void SystemClockSourceSelect(enum Clock_RC source)
{
if(source == RC_32MHz)
{
CLKCONCMD &= ~0x40; //0x40 = 0100 0000 取反第六位为0
while(CLKCONCMD & 0x40); //如果第六位成功X0XX XXXX & 0100 0000 为假 跳出while
CLKCONCMD &= ~0x07;
}
else if(source == RC_8MHz)
{
CLKCONCMD |= 0x40; //0100 0000 内部时钟源
while(!(CLKCONCMD & 0x40))
//8M是001
CLKCONCMD |= 0x01;//置1
CLKCONCMD &= ~0x06 ;//置0 这一步是为了确定全面置0
}
else
{
}
}
void LED_INIT(void) //LED初始化函数
{
P1SEL &= ~0x07; // P1SEL &= ~(0000 0111)P1SEL &= (1111 1000)
P1DIR |= 0x07;
P1 = 0x07;
}
void main(void)
{
LED_INIT(); //初始化
int number;
while(1)
{
SystemClockSourceSelect(RC_32MHz);
for(number = 0 ; number < 8 ; number++)
{
LED_blink();
}
SystemClockSourceSelect(RC_8MHz);
for(number = 0 ; number < 8 ; number++)
{
LED_blink();
}
}
}
课后小练:分别选择32MHz晶体振荡器和16MHz RC完成上述题目
``
[zigbee菜鸟笔记(六)定时器-自由模式点击进入](https://blog.csdn.net/Aviciit/article/details/108145756)