cc2530晶振與時鐘
CC2530有四個晶振,兩個內部(16M RC晶振,32K RC晶振),兩個外部(32.768K的石英晶振,32M的石英晶振),石英晶振的精度高,耗電大,啟動慢。RC晶振精度低一點,耗電小,啟動快。在上電時,預設是使用內部的兩個晶振,因為內部這兩個RC晶振速度快。外部的32.768石英晶振也可以不接。兩個低頻晶振不能同時上電,即不能同時起振。
cc2530資料手冊上SLEEPCMD這個暫存器的第2位(從第0位開始計)說明是錯誤,該位的正確說明,應當看cc2430的資料手冊SLEEP暫存器的第2位。當該位為0時,將兩個高頻晶振同時上電;該位為1時,將CLKCONCMD.OSC位沒有選擇的高頻晶振關閉。同樣的,cc2530資料手冊SLEEPSTA這個暫存器的第6位和第5位說明是錯誤,這兩位的正確說明,應當看cc2430的資料手冊SLEEP暫存器的第6位和5位。附圖如下:
cc2530的SLEEPCMD
CC2530的SLEEPSTA
對應cc2430中只有SLEEP暫存器
#include <iocc2530.h>
#include <string.h>
#define LED1 P1_0
#define uint16 unsigned int
void Hal_Init_Mcu(void)
{
SLEEPCMD &= ~0X04; //將兩個高頻的晶振同時上電(即同時開啟)
while(!(SLEEPSTA & 0x20) || !(SLEEPSTA & 0x40)); //等待兩個高頻晶振都穩定
asm("NOP");
{
uint16 i;
for(i=0;i<504;i++)
asm("NOP");
}
CLKCONCMD = 0X00;
SLEEPCMD |= 0X04;
}
void Hal_Init_Led(void)
{
P1DIR |= 0X01;
LED1 = 0;
}
void HAL_Set_MainClock(uint16 source)
{
register uint16 usc32k_bm = CLKCONCMD & 0X80; //將選擇的低頻晶振的值儲存
SLEEPCMD &= ~0X04; //將兩個高頻的晶振同時上電(即同時開啟)
while(!(SLEEPSTA & 0x20) || !(SLEEPSTA & 0x40)); //等待兩個高頻晶振都穩定
asm("NOP");
{
uint16 i;
for(i=0;i<504;i++)
asm("NOP");
}
if(source ==0)//選擇32M的石英晶振
CLKCONCMD = (usc32k_bm | 0X00);
else //選擇32M的RC晶振
CLKCONCMD = (usc32k_bm | 0X40 | (0X01<<3) | 0x01);
//等待設定穩定下來
uint16 cmd = CLKCONCMD;
while(1)
{
uint16 sta = CLKCONSTA;
if(cmd == sta)
break;
}
SLEEPCMD |= 0X04; //去掉沒有選擇的高頻晶振
}
void delay(uint16 n)
{
uint16 i,j;
for(j=0;j<15;j++)
for(i=0;i<n;i++);
}
void main(void)
{
Hal_Init_Mcu();
Hal_Init_Led();
while(1)
{
HAL_Set_MainClock(0);
for(int i=0;i<10;i++)
{
LED1 = !LED1;
delay(10000);
}
LED1 = 1;
delay(50000);
HAL_Set_MainClock(1);
for(int i=0;i<10;i++)
{
LED1 = !LED1;
delay(10000);
}
}
}
#include <iocc2530.h>
#include <string.h>
#define LED1 P1_0
#define uint16 unsigned int
void Hal_Init_Mcu(void)
{
SLEEPCMD &= ~0X04; //將兩個高頻的晶振同時上電(即同時開啟)
while(!(SLEEPSTA & 0x20) || !(SLEEPSTA & 0x40)); //等待兩個高頻晶振都穩定
asm("NOP");
{
uint16 i;
for(i=0;i<504;i++)
asm("NOP");
}
CLKCONCMD = 0X00;
SLEEPCMD |= 0X04;
}
void Hal_Init_Led(void)
{
P1DIR |= 0X01;
LED1 = 0;
}
void HAL_Set_MainClock(uint16 source)
{
register uint16 usc32k_bm = CLKCONCMD & 0X80; //將選擇的低頻晶振的值儲存
SLEEPCMD &= ~0X04; //將兩個高頻的晶振同時上電(即同時開啟)
while(!(SLEEPSTA & 0x20) || !(SLEEPSTA & 0x40)); //等待兩個高頻晶振都穩定
asm("NOP");
{
uint16 i;
for(i=0;i<504;i++)
asm("NOP");
}
if(source ==0)//選擇32M的石英晶振
CLKCONCMD = (usc32k_bm | 0X00);
else //選擇32M的RC晶振
CLKCONCMD = (usc32k_bm | 0X40 | (0X01<<3) | 0x01);
//等待設定穩定下來
uint16 cmd = CLKCONCMD;
while(1)
{
uint16 sta = CLKCONSTA;
if(cmd == sta)
break;
}
SLEEPCMD |= 0X04; //去掉沒有選擇的高頻晶振
}
void delay(uint16 n)
{
uint16 i,j;
for(j=0;j<15;j++)
for(i=0;i<n;i++);
}
void main(void)
{
Hal_Init_Mcu();
Hal_Init_Led();
while(1)
{
HAL_Set_MainClock(0);
for(int i=0;i<10;i++)
{
LED1 = !LED1;
delay(10000);
}
LED1 = 1;
delay(50000);
HAL_Set_MainClock(1);
for(int i=0;i<10;i++)
{
LED1 = !LED1;
delay(10000);
}
}
}