1. 程式人生 > >cc2530晶振與時鐘

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);
    }
  }
  
}