CC2541藍牙學習——時鍾設置


CC2541有四個振盪器,分別是:

  • 32MHz外部晶振
  • 16MHz內部RC振盪器
  • 32kHz外部晶振
  • 32kHz內部RC振盪器
由此可以看出,CC2541內部自帶了振盪器,也就是說即使外部電路不接振盪器,CC2541也可以工作,答案是肯定的,但是作為無線RF收發,只能使用外部32MHz晶振,除非准備將CC2541當做一個普通的增強型51單片機來用,否者32MHz外部晶振是必不可少的,那么這4個晶振有什么區別和用途呢?
32MHz的外部晶振有兩個作用:為內部時鍾提供時鍾源和用於RF收發器
16MHz的RC內部振盪器的作用:為內部時鍾提供時鍾源,注意它不可以用於RF收發器操作
16MHz的RC內部振盪器功耗小但是精度差,這也是它不能用於RF收發器的原因。
32kHz外部晶振運行在32.768KHz上,32kHz內部RC振盪器運行在32.753kHz,這兩個時鍾主要使用在Sleep Timer 和Watchdog Timer上,其中內部的32kHz振盪器功耗小,但是精度低,這兩個隨意選擇一個,但不能同時使用,言外之意就是如果要求精度不高的時候電路中可以不接外部32kHz晶振。
 
注意:系統上電,默認的是使用內部16Mhz時鍾和內部32kHz振盪器
 
怎么選擇這四個振盪器呢? 由CLKONCMD時鍾控制命令寄存器選擇,CLKONCMD寄存器定義如下:

解釋下CLKONCMD這個寄存器
OSC32K:32kHz選擇位
OSC:主時鍾選擇位
TICKSPD:對主時鍾進行分頻,控制定時器1、定時器3 和定時器4 的全局時鍾划分。分頻器值的設置可以從0.25 MHz 到32 MHz 。注意如果CLKCONCMD.TICKSPD 表示頻率高於系統時鍾,CLKCONSTA.TICKSPD 中指明的實際分頻器值和系統時鍾相同。簡言之:定時器1、3、4的時鍾。
CLKSPD:對主時鍾進行分頻,分頻后的頻率作為主時鍾,類似於PLL,一般這個值設為000,即主時鍾為32Mhz
 
當選擇32MHz晶振作為主時鍾源時(CLKONCMD.OSC = 0),內部時鍾並不是一下子變為32Mhz,內部首先選擇16MHz RC振盪器使系統運行起來,當32MHz晶振穩定以后才使用32MHz晶振作為主時鍾。判斷是否穩定的依據是看“CLKONSTA時鍾控制狀態寄存器”,定義如下
 

CLKONSTA.OSC == 1時才能說明32Mhz時鍾已經穩定。所以在程序里,要加一個等待的語句,防止時鍾未穩定的程序執行錯誤。
 
時鍾初始化代碼如下。
 
 
 1 /****************************************************************
 2 *函 數 名:InitClock
 3 *功    能:系統時鍾初始化
 4 *入口參數:無
 5 *出口參數:無
 6 *****************************************************************/
 7 void InitClock(void)
 8 {
 9 CLKCONCMD &= ~0x40; // 設置系統時鍾源為 32MHZ晶振
10 while(CLKCONSTA & 0x40); // 等待晶振穩定 
11 CLKCONCMD &= ~0x47; // 設置系統主時鍾頻率為 32MHZ
12 }

但是實際調試時,調用該函數,總是得不到32MHz的時鍾,16MHz的工作時鍾始終不變,找了很久,不知道為什么,調試的時候程序一直停在第10行代碼那。后來用饅頭科技的時鍾程

序,調試成功,系統工作時鍾變為32MHz,以后就用這個程序了,程序代碼如下:

 1 /****************************************************************
 2 *函 數 名:SysStartXOSC
 3 *功    能:系統時鍾初始化
 4 *入口參數:無
 5 *出口參數:無
 6 *****************************************************************/
 7 void SysStartXOSC(void)
 8 {
 9     SLEEPCMD &= ~0x04;                      // 啟動所有晶振
10     while (!(SLEEPSTA & 0x40));             // 等待晶振穩定
11 
12     CLKCONCMD = (CLKCONCMD & 0x80) | 0x49;  // 使用16M晶振作為主時鍾
13     while ((CLKCONSTA & ~0x80) != 0x49 );   // 等待主時鍾切換到16M晶振
14 
15     CLKCONCMD = (CLKCONCMD & ~0x80) ;       // 使用外部32K晶振作為休眠時鍾
16     while ( (CLKCONSTA & 0x80) != 0 );      // 等待睡眠時鍾切換到外部32K晶振
17 
18     CLKCONCMD = (CLKCONCMD & 0x80) ;        // 使用32M晶振作為主時鍾
19     while ( (CLKCONSTA & ~0x80) != 0 );     // 等待主時鍾切換到32M晶振
20 
21     SLEEPCMD |= 0x04;                       // 關閉未使用的晶振
22 }

 

 
 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM