CC2530的时钟模块.docx
《CC2530的时钟模块.docx》由会员分享,可在线阅读,更多相关《CC2530的时钟模块.docx(31页珍藏版)》请在冰豆网上搜索。
CC2530的时钟模块
有两部分:
1、
CC2530学习之时钟与振荡器
分类:
CC2530学习杂记2011-10-2120:
09 1310人阅读 评论(3) 收藏 举报
timersystem工作
2011年10月21日
一、,时钟、振荡器
(1) TouseRFtransceiver,the32MHZ晶体振荡器mustbeselectedandstable.
(2) CLKCONCMD.OSC bitselectsthesourceofthe systemclock.系统时钟可以是32MHZ石英振荡器,也可以是16MHZRC振荡器。
(3) 改变CLKCONCMD.OSC bit并不能导致系统时钟的迅速改变。
有两个前提条件:
1,CLKCONSTA.OSC=CLKCONCMD.OSC (保持时钟的稳定)
2,CLKCONCMD.CLKSPDbit =系统时钟。
(thisisamirroroftheclkconcmd.oscbit).
(4)CLKCONCMD.TICKSPD 时间片的设置,体现了系统时钟从当前值改变到需要改变为的时钟的快慢。
ThefastestswitchingisobtainedwhenCLKCONCMD.TICKSPD等于000.
(5)32KHZ振荡器有两个:
32kHZXOSC和32KHZRCOSC.
32KRC0SC在复位后使能,别选作为32KHZ时钟源,具有较低耗能的特点,但是没有32KHZX0SC精确。
32khz振荡器用来驱动SleepTimer,产生看门狗时钟的滴答记号,在timer2中被用来作为选通脉冲。
只在系统时钟32MHZXOSC,才启动工作。
刚转换到32KHZX0SC时,振荡器需要500ms来稳定到准确地频率上。
(6))CLKCONCMD.TICKSPD寄存器控制了一个全局的分频器,作用于---Timer1,Timer3,和Timer4. CLKCONCMD.TICKSPD的值应该小于系统时钟频率,当CLKCONCMD.TICKSPD大于系统时钟时,CLKCONCMD.TICKSPD与系统时钟的值相同。
(7)振荡器和时钟的控制寄存器:
CLKCONCMD和CLKCONSTA.
2、
ZigBee研究之旅(四)---CC2530的时钟模块
CC2530的时钟模块
(cc2530_datasheet节选翻译如下)
******************************************************************
*作 者:
fulinux
*转载声明:
点击链接
******************************************************************
1.振荡器和时钟
CC2530设备有一个内部系统时钟,或者主时钟。
系统时钟源可以是从16MHzRC振荡器或一个32M晶体振荡器中的一个提供。
系统时钟源是由CLKCONCMDSRF控制寄存器。
还有一个32KHz的时钟源,来源可以是从RC振荡器或者32KHz的晶体振荡器中过来,同样是由CLKCONCMD寄存器控制。
CLKCONSTA寄存器是一个制度寄存器,用来获得当前系统时钟的状态。
时钟源可以在一个精度高的晶体振荡器和一个功耗低的RC振荡器中交替选择使用。
注意一点:
RF的收发操作是要以32MHz的晶体振荡器为时钟源才行。
2.振荡器
图中给出了时钟系统中可用的时钟源的一个全貌图。
设备中存在的两个高频振荡器:
*32MHz晶体振荡器
*16MHz的RC振荡器
32MHz的晶体振荡器启动时间对于某些应用来说可能太长了;因此设备可以先运行在16MHz的RC振荡器中运行直到晶体振荡器稳定后在使用32MHz晶体振荡器。
16MHz的RC振
荡器功耗低但是不是很准,所以不能为RF模块提供服务,只能用32MHz的晶体振荡器。
设备中存在的两个低频振荡器:
*32KHz晶体振荡器
*32KHzRC振荡器
32KHz的XOSC被设计的工作频率频率是32.768KHz并且可以为一些要求时钟准确子系统提供一个稳定的时钟信号。
32KHz的RCOSC当校准后可以运行在32.753KHz频率下。
校准
只能发生在当32MHzXOSC使能的情况下,可以通过使能SLEEPCMD.OSC32K_CALDIS位来关闭校准。
32KHzRC振荡器相对于32KHz XOSC晶体振荡器功耗低,应该用在可以降
低成本情况下。
两个振荡器不能同时工作。
3.系统时钟
系统时钟是由32MHzXOSC或者16MHzRCOSC两个时钟源驱动的。
CLKCONCMD.OSC位用来选择系统时钟源。
注意:
使用RF模块时,32MHz晶体振荡器必须被选上并且运行稳定。
注意:
改变CLKCONCMD.OSC位并不能立即导致系统时钟源的改变。
当CLKCONSTA.OSC=CLKCONCMD.OSC时时钟源的改变才会发挥作用。
这是因为设备在实际改变时钟源之前
需要稳定的时钟。
还有就是注意CLKCONCMD.CLKSPD位反应着系统时钟频率,因此是CLKACONCMD.OSC位的镜子。
一旦32MHz的XOSC被选中和稳定,例如,当CLKCONSTA.OSC
位从1切换到0时。
注意:
从16MHz到32MHz时钟源的改变符合CLKCONCMD.TICKSPD设置。
CLKCONCMD.TICKSPD设置的缓慢一些的话,当CLKCONCMD.OSC改变的话会导致实际的时钟源起作用的
时间会很长。
当CLKCONCMD.TICKSPD等于000时会获得最快的切换速度。
4.32KHz的振荡器
默认的或者复位后32KHzRCOSC使能并且被设置作为32KHz的时钟源。
其功耗低,但是相对于32KHz晶体振荡器而言精度不高,32KHz时钟源用来驱动睡眠定时器,产生看门狗的滴答值
和作为timer2计算睡眠定时器的一个闸门。
32KHz时钟源被寄存器CLKCONCMD.OSC32K位用来作为选择振荡器。
CLKCONCMD.OSC32K寄存器可以在任意时间写入,但是在16MHzRC
振荡器是活跃的系统时钟源之前是不会起作用的。
当系统时钟从16MHz改变为32MHz的晶体振荡器(CLKCONCMD.OSC从1到0)一旦32KHzRC振荡器被选中了它的的校验就启动了并且被执行。
在校准期间,32MHz晶体振荡器的一个分频量会被使用。
32KHzRCOSC振荡器校准后的结果是它会工作在32.753kHz上。
32kHzRC振荡器校准时间可能要2ms时间来完成。
可以设置SLEEPCMD.OSC32K_CALDIS位设置为1的话,会关闭校准。
在校准结束时,会在32KHz时钟源上产生一个额外的脉冲,会导致睡眠定时器增加1。
注意:
当切换到32KHz晶体振荡器后和从32KHz晶体振荡器被设置的PM3模式唤醒时,振荡器稳定到准确频率的时间在500ms以上。
睡眠定时器、看门狗定时器和时钟损失探测器在32KHz
晶体振荡器稳定之前不能使用。
5.振荡器和时钟寄存器
下面是振荡器和时钟寄存器的描述,所有寄存器的位会在进入PM2和PM3时保持不变,除非有异常情况发生。
6.定时器滴答值产生器
CLKCONCMD.TICKSPD寄存器控制timer1、timer3和timer4的全局预分频。
预分频的值设置范围在0.25MHz和32MHz之间。
需要注意的是如果CLKCONCMD.TICKSPD显示的频率高于系统时钟,则在CLKCONSTA.TICKSPD中的实际的预分频值表明是和系统时钟的值是一样的。
7.数据滞留
在PM2和PM3电源模式中,绝大多数的内部电路关闭了,然而,SRAM中任保留它的内容,内部寄存器的值也会保留。
保留数据的寄存器是CPU的寄存器、外部寄存器和RF寄存器,除非另一些位域值设置的比较特殊。
切换到PM2和PM3模式的现象对于软件而已是透明的。
注意在PM3模式下睡眠定时器的值不会保存。
******************************************************************
*作 者:
fulinux
*转载声明:
点击链接,如有不对之处,请指正
******************************************************************
/**********************************************************************************************************************************************************
*文件名:
main.c
×
*功能:
实验一系统时钟源的选择
*
*CC2530有1个内部的系统时钟。
时钟源可以是1个16MHz的RC振荡器,也可以是1个32MHz的晶体
*振荡器。
时钟控制是通过使用CLKCON特殊功能寄存器来执行的。
系统时钟也提供给所有的8051
*外设。
*
*32MHz晶体振荡器的启动时间对于某些应用而言太长了,因此CC2530可以运行在16MHzRC振荡器
*直到晶体振荡器稳定。
16MHzRC振荡器的功耗要少于晶体振荡器,但是由于它没有晶体振荡器
*精确,因此它不适用于射频收发器。
*
*CLKCONCMD.OSC位被用来选择系统时钟源。
注意:
要使用射频收发器,32MHz晶体振荡器必须被选择
*并且稳定。
*
*注意:
改变CLKCON.OSC位并不即刻生效。
这是因为在实际改变时钟源之前,被选择的时钟源要
*首先达到稳定。
还要注意:
CLKCONSTA.CLKSPD位将反映系统时钟频率,因此它是CLKCON.OSC位的
*“镜子”。
*
*当SLEEPSTA.XOSC_STB为1时,表示系统报告32MHz晶体振荡器稳定。
然而,这可能并不是实际情况,
×在选择32MHz时钟作为系统时钟源之前,应该等待一个额外的64us的安全时间,可以通过增加一
*条空指令"NOP"来实现。
如果不等待,可能会造成系统崩溃。
*
*未被选择作为系统时钟源的振荡器,通过设置SLEEP.OSC_PD为1(默认状态)将被设置为掉电模式。
*因此,当32MHz晶体振荡器被选择作为系统时钟源后,16MHzRC振荡器可能被关闭,反之亦然。
*当SLEEPCMD.OSC_PD为0时,这2个振荡器都被上电并运行。
*当32MHz晶体振荡器被选择作为系统时钟源并且16MHzRC振荡器也被上电时,根据供电电压和运
*行温度,16MHZRC振荡器将被不断校准以确保时钟稳定。
当16MHzRC振荡器被选择作为系统时钟
*源时,该校准不被执行。
*
*本实验将向用户演示选择不同的振荡器作为系统时钟源。
本文件中有led闪烁的子程序,用户
*可以观察在不同系统时钟源下led的闪烁情况。
*
*在hal.h文件中包含了和系统时钟相关的一些宏,用户使用这些宏可以简化对系统时钟的控制,
*提高代码的可读性,本实验中就使用了其中的一些宏。
*
*注意:
本实验可在以下目标板上进行:
*
*
*
*
*
*版本:
V1.0
*作者:
wuxianhai
*日期:
2011.2.12
*奥尔斯电子主页:
**********************************************************************************************************************************************************/
#include"hal.h"
#defineON0x01//LED状态
#defineOFF0x00
externvoidctrPCA9554LED(UINT8led,UINT8operation);
externvoidPCA9554ledInit();
/**************************************************************************************************
*函数名称:
halWait
*
*功能描述:
延时
*
*参数:
wait-延时时间
*
*返回值:
无
**************************************************************************************************/
voidhalWait(BYTEwait){
UINT32largeWait;
if(wait==0)
{return;}
largeWait=((UINT16)(wait<<7));
largeWait+=114*wait;
largeWait=(largeWait>>CLKSPD);
while(largeWait--);
return;
}
/**************************************************************************************************
*函数名称:
main
*
*功能描述:
反复选择不同的振荡器作为系统时钟源,并调用led控制程序,闪烁LED灯。
*
*参数:
无
*
*返回值:
无
**************************************************************************************************/
voidmain(void)
{
UINT8i;
PCA9554ledInit();
while
(1)
{
SET_MAIN_CLOCK_SOURCE(CRYSTAL);//设置系统时钟源为32MHz晶体振荡器(大约用时150us),关闭16MHzRC振荡器
for(i=0;i<10;i++)
{
ctrPCA9554LED(0,ON);
halWait(200);
ctrPCA9554LED(0,OFF);
halWait(200);
}
SET_MAIN_CLOCK_SOURCE(RC);//选择16MHzRC振荡器,关闭32MHz晶体振荡器
PCA9554ledInit();
halWait(200);
for(i=0;i<10;i++)
{
ctrPCA9554LED(1,ON);
halWait(200);
ctrPCA9554LED(1,OFF);
halWait(200);
}
}
}
/**********************************************************************************************************
*文件名:
iic.C
*功能:
实验二GPIO控制实验
*该实验采用CC2530的I/O口(P1.0和P1.1)模拟IIC总线的SCL和SDA,然后通过IIC总线形式控制GPIO扩展芯片
*PCA9554,最后通过扩展的IO来控制LED的亮灭。
*
*硬件连接:
将OURS的CC2530RF模块插入到普通电池板或智能电池板上。
*
*P1.0------SCL
*P1.1------SDA
*
*版本:
V1.0
*作者:
WUXIANHAI
*日期:
2011.1.18
*奥尔斯电子主页:
**************************************************************************************************************/
#include"ioCC2530.h"
#include"hal_mcu.h"
#defineSCLP1_0//IIC时钟线
#defineSDAP1_1//IIC数据线
//定义IO方向控制函数
#defineIO_DIR_PORT_PIN(port,pin,dir)\
do{\
if(dir==IO_OUT)\
P##port##DIR|=(0x01<<(pin));\
else\
P##port##DIR&=~(0x01<<(pin));\
}while(0)
#defineOSC_32KHZ0x00//使用外部32K晶体振荡器
//时钟设置函数
#defineHAL_BOARD_INIT()\
{\
uint16i;\
\
SLEEPCMD&=~OSC_PD;/*开启16MHzRC和32MHzXOSC*/\
while(!
(SLEEPSTA&XOSC_STB));/*等待32MHzXOSC稳定*/\
asm("NOP");\
for(i=0;i<504;i++)asm("NOP");/*延时63us*/\
CLKCONCMD=(CLKCONCMD_32MHZ|OSC_32KHZ);/*设置32MHzXOSC和32K时钟*/\
while(CLKCONSTA!
=(CLKCONCMD_32MHZ|OSC_32KHZ));/*等待时钟生效*/\
SLEEPCMD|=OSC_PD;/*关闭16MHzRC*/\
}
#defineIO_IN0//输入
#defineIO_OUT1//输出
uint8ack;//应答标志位
uint8PCA9554ledstate=0;//所有LED当前状态
/******************************************************************************
*函数名称:
QWait
*
*功能描述:
1us的延时
*
*参数:
无
*
*返回值:
无
*****************************************************************************/
voidQWait()
{
asm("NOP");asm("NOP");
asm("NOP");asm("NOP");
asm("NOP");asm("NOP");
asm("NOP");asm("NOP");
asm("NOP");asm("NOP");
asm("NOP");
}
/******************************************************************************
*函数名称:
Wait
*
*功能描述:
ms的延时
*
*参数:
ms-延时时间
*
*返回值:
无
*****************************************************************************/
voidWait(unsignedintms)
{
unsignedcharg,k;
while(ms)
{
for(g=0;g<=167;g++)
{
for(k=0;k<=48;k++);
}
ms--;
}
}
/******************************************************************************
*函数名称:
Start_I2c
*
*功能描述:
启动I2C总线,即发送I2C起始条件.
*
*参数:
无
*
*返回值:
无
*****************************************************************************/
voidStart_I2c()
{
IO_DIR_PORT_PIN(1,0,IO_OUT);//设置P1.0为输出
IO_DIR_PORT_PIN(1,1,IO_OUT);//设置P1.1为输出
SDA=1;/*发送起始条件的数据信号*/
asm("NOP");
SCL=1;
QWait();/*起始条件建立时间大于4.7us,延时*/
QWait();
QWait();
QWait();
QWait();
SDA=0;/*发送起始信号*/
QWait();/*起始条件锁定时间大于4μs*/
QWait();
QWait();
QWait();
QWait();
SCL=0;/*钳住I2C总线,准备发送或接收数据*/
asm("NOP");
asm("NOP");
}
/******************************************************************************
*函数名称:
Stop_I2c
*
*功能描述:
结束I2C总线,即发送I2C结束条件.
*
*参数:
无
*
*返回值:
无
*****************************************************************************/
voidStop_I2c()
{
IO_DIR_PORT_PIN(1,0,IO_OUT);//设置P1.0为输出
IO_DIR_PORT_PIN(1,1,IO_OUT);//设置P1.1为输出
SDA=0;/*发送结束条件的数据信号*/
asm("NOP");/*发送结束条件的时钟信号*/
SCL=1;/*结束条件建立时间大于4μs*/
QWait();
QWait();
QWait();
QWait();
QWait();
SDA=1;/*发送I2C总线结