1. 程式人生 > >F28027第三節課---系統時鐘(二)

F28027第三節課---系統時鐘(二)

今天還是繼續學習時鐘

今天看晶片手冊的時候,發現自己昨天好敷衍。。今天必須要來做點補充,不然虛的慌

第一、安全裝置watchdog

首先看下watchdog整體裝置:


看門狗要復位輸出脈衝訊號,從Generate Output Pulsemo模組來看,有兩個控制條件:SCSR.WDENINT(選擇輸出訊號)和輸入一個有邊沿跳變的脈衝訊號(上圖所示1),這裡我們就不重點討論WDENINT取值了,因為我們現在要做的是關閉看門狗,無復位訊號輸出。

上圖所示的方框1,是一個二輸入或門,也就是方框2或者看門狗計數器模組任何一個有高電平的跳變訊號,或門輸出就是一個高脈衝訊號,也就是有復位訊號產生,這顯然和我們的本意是不相符的,我們現在要做的是使方框2和看門狗計數器都輸出低電平。

對於方框2,是一個異或門,也就是當兩端輸入的電平是一樣時,輸出為低電平,否則輸出高電平。通過上面的分析,我們需要該異或門輸出低電平,也就是兩端輸入保持一直,就需要WDCR.WDCHK=101B。

對於看門狗計數器,有一個輸入訊號和一個復位控制訊號,也就是有兩種辦法讓計數器輸出保持低電平:無輸入訊號和週期性寫復位訊號。當看門狗使能位WDCR.WDDIS=1,使能禁止,就會導致無輸入訊號;週期性寫復位訊號,也就是看門狗復位金鑰暫存器WDKEY先寫一個0x55,然後再寫一個0xAA,就會產生一個復位訊號。在這裡我有個疑問,金鑰暫存器的輸出連到一個單邊先取反再或的一個二輸入或門,由於或門的另一端是直連一個高電平,然後取反,也就是這端輸入始終保持低電平,或門的輸出值也就是等於金鑰暫存器的輸出值,那既然這樣的話,這個或門在這裡有什麼其他的神奇作用呢?歡迎各路大神吐槽指點。

好了,囉嗦到這裡,昨天關閉看門狗那一條語句SysCtrlRegs.WDCR= 0x0068也就很清晰明瞭了,那繼續下一個時鐘問題。

第二、時鐘源

廢話不多說,還是先上圖,再一步一步的分析:


圖中這麼多圈圈框框的,有沒有暈暈的感覺,昨天我就是看這個圖特煩躁(還沒有圈圈框框),走向繞來繞去的,今天反省了下,靜下心好好的看了下這個結構圖,還是so easy的嘛,就是幾個開關選擇器而已,來,一起來看下怎麼簡單:

首先,該晶片總共可以有四個時鐘源,內部振盪器1、內部振盪器2、晶體振盪器、外部時鐘輸入,這四個時鐘源具體接入方法大家直接看上面這個圖就知道了,我就不囉嗦了,其中INTOSCnTRIM是對內部10M時鐘訊號進行粗調和細調的。

上面所有的圈圈框框,除了XCLK[XCLKINSEL]控制訊號以外,其他都是由CLKCTL時鐘控制暫存器控制的。

假設我們現在需要以內部振盪器1為時鐘源,那就要關閉內部振盪器2、晶體振盪器、外部輸入時鐘。

先來操作最簡單的,關閉晶體振盪器和外部輸入時鐘,如上圖的左下角,也就是XTALOSCOFF=1、XCLKINOFF=1,這兩個時鐘源模組輸出訊號為低電平了,也就是左下角那個異或門輸出為低電平;

再來關閉內部振盪器2,只要INTOSC2OFF控制訊號為低電平,內部振盪器2就關閉了。

最後就是輸出內部振盪器1的時鐘訊號。最重要的是開啟內部振盪器的控制訊號INTOSC1OFF=0,然後就是把該訊號送到CPU時鐘模組,時鐘模組一般由PLL鎖相環電路構成,所以我們只要把時鐘基準訊號送到PLL模組,也就是方框2,使OSCCLKSRCSEL=0,其他幾個輸出訊號是watchdog和timer2的,若需要,開啟相應的開關狀態即可。

至此,昨天打醬油的東西全部複習了一遍。

第三、PLL鎖相環

剛才第二點最後也說了,時鐘源基準訊號是送到PLL鎖相環電路進行相應的調理之後才能作為系統時鐘的,PLL鎖相環電路場景分為兩種:正常模式和跛行模式。

簡單來說(還是習慣性的先上圖),PLL工作模式如下:


從圖中看,主要由兩個暫存器控制PLL鎖相環裝置:PLLCR、PLLSTS,下面我們來看下這兩個暫存器:

先看簡單的PLLCR:



從上面很直觀明瞭的知道,PLLCR[DIV]和PLLSTS[DIVSEL]組合起來進行時鐘調理,獨立看是沒有意義的。

那我們現在來看下PLLSTS的暫存器結構:




這又是噼裡啪啦一大串英文解說,每當這個時候,恨不得自己身邊坐著一個英語過八級的漂亮女朋友,可惜陪我的只有有道詞典,關鍵還翻譯的不準確,只能半翻譯半猜測了。

吐槽完了,我們再來看最開始那個PLL流轉圖,我們用到只是PLLSTS[OSCOFF]和PLLSTS[PLLOFF],其中OSCOFF是PLL時鐘選擇控制位,而PLLOFF是PLL的使能位,PLLSTS[DIVSEL]和PLLCR[DIV]是配合使用的。有點要注意的是,在寫入 PLLCR 前,PLLSTS[DIVSEL] 必須為 0,而只有當 PLLSTS[PLLOCKS]=1 時才應被改變。

說了那麼多廢話,最後來一個PLL鎖相環調整電路的整體流程思路(當然來自晶片手冊):


簡單的複述下流程:

1、檢查PLLSTS[MCLKSTS]位是否為1,為1說明CPU工作在跛行模式,要趕緊做出相應的調整了;

2、當PLLSTS[MCLKSTS]位恢復為0後,檢查PLLSTS[DIVSEL]是否為2或者3,如果是,直接把PLLSTS[DIVSEL]設定為0

3、當上一步檢查到PLLSTS[DIVSEL]不為2或者3時,把PLLSTS[MCLKOFF]設為1,關閉振盪器故障檢測,這樣就不會在調整PLLCR期間再次進入跛行模式;

4、設定PLLCR[DIV]的值;

5、檢查PLLSTS[PLLLOCKS]值是否為1,也就是PLLCR是否完成寫入鎖定;

6、當完成PLL完成鎖定後,開啟振盪器故障檢測;

7、如果有需要,調整PLLSTS[DIVSEL]的值,但是有點需要注意,PLLSTS[DIVSEL]調整為1或2時,可以直接設定,當調整為3時,先調整到2,再調整到3。

流程也講完了,現在我們來看下示例程式:

InitPll(12,2);

void InitPll(Uint16 val, Uint16 divsel)
{
   volatile Uint16 iVol;


   // Make sure the PLL is not running in limp mode
   if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 0)
   {
      EALLOW;
      // OSCCLKSRC1 failure detected. PLL running in limp mode.
      // Re-enable missing clock logic.
      SysCtrlRegs.PLLSTS.bit.MCLKCLR = 1;
      EDIS;
      // Replace this line with a call to an appropriate
      // SystemShutdown(); function.
      asm("        ESTOP0");     // Uncomment for debugging purposes
   }

   // DIVSEL MUST be 0 before PLLCR can be changed from
   // 0x0000. It is set to 0 by an external reset XRSn
   // This puts us in 1/4
   if (SysCtrlRegs.PLLSTS.bit.DIVSEL != 0)
   {
       EALLOW;
       SysCtrlRegs.PLLSTS.bit.DIVSEL = 0;
       EDIS;
   }

   // Change the PLLCR
   if (SysCtrlRegs.PLLCR.bit.DIV != val)
   {
      EALLOW;
      // Before setting PLLCR turn off missing clock detect logic
      SysCtrlRegs.PLLSTS.bit.MCLKOFF = 1;
      SysCtrlRegs.PLLCR.bit.DIV = val;
      EDIS;

      // Optional: Wait for PLL to lock.
      // During this time the CPU will switch to OSCCLK/2 until
      // the PLL is stable.  Once the PLL is stable the CPU will
      // switch to the new PLL value.
      //
      // This time-to-lock is monitored by a PLL lock counter.
      //
      // Code is not required to sit and wait for the PLL to lock.
      // However, if the code does anything that is timing critical,
      // and requires the correct clock be locked, then it is best to
      // wait until this switching has completed.

      // Wait for the PLL lock bit to be set.

      // The watchdog should be disabled before this loop, or fed within
      // the loop via ServiceDog().

      // Uncomment to disable the watchdog
      DisableDog();

      while(SysCtrlRegs.PLLSTS.bit.PLLLOCKS != 1)
      {
          // Uncomment to service the watchdog
          // ServiceDog();
      }

      EALLOW;
      SysCtrlRegs.PLLSTS.bit.MCLKOFF = 0;
      EDIS;
    }

    // If switching to 1/2
    if((divsel == 1)||(divsel == 2))
    {
        EALLOW;
        SysCtrlRegs.PLLSTS.bit.DIVSEL = divsel;
        EDIS;
    }

    // If switching to 1/1
    // * First go to 1/2 and let the power settle
    //   The time required will depend on the system, this is only an example
    // * Then switch to 1/1
    if(divsel == 3)
    {
        EALLOW;
        SysCtrlRegs.PLLSTS.bit.DIVSEL = 2;
        DELAY_US(50L);
        SysCtrlRegs.PLLSTS.bit.DIVSEL = 3;
        EDIS;
    }
}

經過之前的流程分析,程式分析起來是不是很簡單了,呵呵,我提兩個點:當檢查到跛行模式後,強制把MCLKCLR置1,就是為了退出時鐘檢測電路;另外,他的程式沒有檢測PLLSTS[DIVSEL]是否為2或3,而是直接檢測是否為0,然後在處理子函式中關閉檢測電路。

第四、外設時鐘

對於外設時鐘這點還真的沒什麼好講的,當暫存器對應的位置1時,就是使能輸出,否則就是使能禁止,直接貼圖了:





上面那幾個貼圖是外設時鐘控制暫存器的,不同的暫存器不同的位對應不同的外設

還有一個低速外設時鐘預分頻器暫存器LOSPCP


貼圖貼完了,再看示例程式了:

void InitPeripheralClocks(void)
{
   EALLOW;

// LOSPCP prescale register settings, normally it will be set to default values

   GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 3;  // GPIO18 = XCLKOUT
   SysCtrlRegs.LOSPCP.all = 0x0002;

// XCLKOUT to SYSCLKOUT ratio.  By default XCLKOUT = 1/4 SYSCLKOUT
   SysCtrlRegs.XCLK.bit.XCLKOUTDIV=2; // Set XCLKOUT = SYSCLKOUT/1

// Peripheral clock enables set for the selected peripherals.
// If you are not using a peripheral leave the clock off
// to save on power.
//
// Note: not all peripherals are available on all 2802x derivates.
// Refer to the datasheet for your particular device.
//
// This function is not written to be an example of efficient code.

   SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1;       // ADC
   SysCtrlRegs.PCLKCR3.bit.COMP1ENCLK = 1;     // COMP1
   SysCtrlRegs.PCLKCR3.bit.COMP2ENCLK = 1;     // COMP2
   SysCtrlRegs.PCLKCR3.bit.CPUTIMER0ENCLK = 1; // CPU Timer-0
   SysCtrlRegs.PCLKCR3.bit.CPUTIMER1ENCLK = 1; // CPU Timer-1
   SysCtrlRegs.PCLKCR3.bit.CPUTIMER2ENCLK = 1; // CPU Timer-2
   SysCtrlRegs.PCLKCR1.bit.ECAP1ENCLK = 1;     // eCAP1
   SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1;     // EPWM1
   SysCtrlRegs.PCLKCR1.bit.EPWM2ENCLK = 1;     // EPWM2
   SysCtrlRegs.PCLKCR1.bit.EPWM3ENCLK = 1;     // EPWM3
   SysCtrlRegs.PCLKCR1.bit.EPWM4ENCLK = 1;     // EPWM4
   SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1;    // GPIO
   SysCtrlRegs.PCLKCR0.bit.HRPWMENCLK=1;       // HRPWM
   SysCtrlRegs.PCLKCR0.bit.I2CAENCLK = 1;      // I2C
   SysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 1;      // SCI-A
   SysCtrlRegs.PCLKCR0.bit.SPIAENCLK = 1;      // SPI-A

   SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;      // Enable TBCLK within the EPWM

   EDIS;
}

是不是都能看的明白,雖然要翻閱晶片手冊,但至少能明白每個語句的含義了,方便直接後續調整了。

到這裡,我們就把F2802x_SysCtrl.c檔案全部講完了,有沒有收穫,我有點,但是好睏現在,又是兩點,白天太忙,沒時間讓我做小動作,菊花廠的工作還是很繁忙的,關鍵是我白天的工作和晚上的學習完全沒關聯,長久下去會不會人格分裂,好擔心,去洗澡壓壓驚了。

菜鳥交流qq群107691092

相關推薦

F28027三節---系統時鐘

今天還是繼續學習時鐘 今天看晶片手冊的時候,發現自己昨天好敷衍。。今天必須要來做點補充,不然虛的慌 第一、安全裝置watchdog 首先看下watchdog整體裝置: 看門狗要復位輸出脈衝訊號,從Generate Output Pulsemo模組來看,有兩個控制條件:SC

F28027第二節---系統時鐘

本來今天打算學習GPIO的,但看了相關的文件和案例後,發現跟系統的時鐘有關聯,所以今天先學習時鐘這章節 我是一個比較浮躁的人,需要什麼看什麼,所以直接翻開案例文件,主函式第一個條語句就是InitSysCtrl(),所以今晚先分析F2802x_SysCtrl.c這個檔案 首先

Akka併發程式設計——三節:Actor模型

本節主要內容: Actor API解析 1. Actor API解析 Actor中的主要成員變數和方法定義如下: package akka.actor trait Actor extends scala.AnyRef { type Rec

Machine Learning九講【推薦系統】-- 協同過濾

一、Collaborative Filtering(協同過濾) 協同過濾能夠自行學習所需要使用的特徵。 來看下面的例子: 在之前講的基於內容的推薦系統中,我們需要事先建立特徵並知道特徵值,這是比較困難的。 假設我們某一使用者的喜好,即假如Alice、Bob喜歡romance的電影,carol

第二篇 六章建築裝修和保溫系統檢查

alt 系統 第二篇 等級 分享圖片 img 裝修 image 分享 裝修材料分4個等級, 保溫材料分3個等級 第二篇 第六章建築裝修和保溫系統檢查(二)

Linux系統管理網絡服務

網絡服務 linux redhat 紅帽 點擊下載:Linux系統管理(二)(網絡服務)本文出自 “飛奔的魚兒” 博客,請務必保留此出處http://feiyuer.blog.51cto.com/6967044/1931978Linux系統管理(二)(網絡服務)

ext2文件系統學習—— 目錄磁盤結構

echo free 文件格式 htm file 目錄結構 bitmap 點號 name 創建鏡像、mount等操作和上一篇一樣,測試目錄結構如下: 一些文件系統信息如下: Block size: 1024 Inodes per group: 1

Android sensor 系統框架

port amp cap 錯誤 str 註釋 hardware war cas 連載上一篇http://www.cnblogs.com/hackfun/p/7327320.html (D) 如何加載訪問.so庫 在前一篇博客http://www.cnblogs.co

Android入門之文件系統操作文件操作相關指令

-h tools strong abc his art 為什麽 重命名 path (一)獲取總根 [java] view plain copy File[] fileList=File.listRoots(); //返回fileList.length為1 /

高並發秒殺系統方案

nco home null public web IT pro mage 項目 項目框架搭建: DemoController: package com.imooc.miaosha.controller; import org.springframewor

《Kubernetes權威指南2版》學習一個簡單的例子

stop 輸入 rtu gist 用戶名 server 遠程 dock netstat 1: 安裝VirtualBox, 並下載CentOS-7-x86_64-DVD-1708.iso, 安裝centOS7,具體過程可以百度。 2:開啟centOS的SSH, 步驟如下:

Linux操作系統基礎

Linux文件管理 文件系統和目錄結構 文件和目錄被組成成一個單根倒置樹結構。根文件系統rootfs root filesystem rootfs:/etc/,/usr,/var,/root,/home,/dev 文件系統分層結構

【轉載】Vue 2.x 實戰之後臺管理系統開發

null element asc 其他 就會 ans 目錄 asi all 2. 常見需求 01. 父子組件通信 a. 父 -> 子(父組件傳遞數據給子組件) 使用 props,具體查看文檔 - 使用 Prop 傳遞數據(cn.vuejs.org/v2/guide

Windows核心編程之核心總結四章 進程2018.6.17)

函數的參數 設置 函數詳解 可執行文件 一次 HA AC 關聯 原型 學習目標 上一節我們了解了進程、入口函數和進程實例句柄等內容,在進入進程的命令行學習前,有一個全局變量初始化問題需要測試一波。本節的學習目標如下:1.測試C/C++運行庫啟動函數初始化哪些全局變量2.進程

Linux文件系統學習之重要數據結構1

class targe html evel 系統結構 會有 集合 spec lan 轉載自:https://blog.csdn.net/wudongxu/article/details/6436894 《Linux內核設計與實現》 http://www.ibm.com/

Pthon學習之路 四篇 Python基礎

pri bsp programs -s alt 如果 lex class 算數運算 1.運算符:+ - *(乘法) /(除法) %(求余) //(求商) **(求冪) 2.成員運算:in not in:判斷單個字符或者子序列在不在字符串中。(n

基於中臺思想的物流系統設計:構建物流訂單能力

一、引言 物流訂單能力作為基礎能力,需要設計一套穩定的訂單模型,以及一套能夠在高併發環境下持續可用的介面。這些介面作為原子介面,供上層業務複用。上層業務無論多麼複雜,通過這些原子介面,最終都會收斂到穩定的訂單模型中來,這也是區分基礎能力和產品服務的一個重要的邊界。 本文通過以下5點來介紹如何構建一套物流訂

「iOS開發」關於一對一視訊聊天直播系統技術處理

針對視訊直播的實時流網路 LiveNet 和完整的直播雲解決方案,很多開發者對這個網路和解決方案的細節和使用場景非常感興趣。 結合實時流網路 LiveNet 和直播雲解決方案的實踐,我們將用一系列文章,更系統化地介紹當下大熱的視訊直播各環節的關鍵技術,幫助視訊直播創業者們更全面、深入地瞭解視訊直播技術,更好

「iOS開發」關於一對一視頻聊天直播系統技術處理

包含 live 能力 white 檢測 google 深入 防盜 視頻內容 針對視頻直播的實時流網絡 LiveNet 和完整的直播雲解決方案,很多開發者對這個網絡和解決方案的細節和使用場景非常感興趣。 結合實時流網絡 LiveNet 和直播雲解決方案的實踐,我們將用一系列文

python基礎教程三版)學習筆記

第二章 列表和元組 2.1序列概述 Python內建的序列包括列表、元組、字串、Unicode字串、buffer物件和xrange物件等,本章僅介紹列表和元組。 列表和元組的主要不同在於,列表的元素是可以修改的,而元組不可以單獨更改其中的單個元素,但可以更改元組的整體內容。 在序列中,每個元素都有編