整篇文章的結構如下:
一、直接把時鐘管理用到的寄存器羅列出來進行分析。
二、對其中的一些原理性的東西做介紹。
三、對於在後面編寫串口時會出現的問題注意點提出說明。
四、LED 代碼
一、在時鐘管理中會用到的寄存器有以下一些。
LOCKTIME,MPLLCON,UPLLCON,CLKCON,CLKSLOW,CLKDIVN,CAMDIVN。
LOCKTIME:是對於配置好鎖相環之後需要延時的一段時間,這時爲了上鎖穩定。其中包括兩部分
①U_LTIME:這是UCLK(USB專用的一個時鐘)配置好後需要的延時時間。
②M_LTIME:這時FCLK(系統時鐘即CPU的頻率),HCLK(一些高速設備所用到時鐘),PCLK(低速設備所用到的時鐘)這三者配置好後需要的上鎖延時。
MPLLCON:是配置外部晶振與系統時鐘之間關係的一個寄存器。之間的關係如下。
一定要要按照公式進行嚴格的計算,比如MPLLCON = 0;MPLLCON |= (0x38<<12)|(0x2<<4)|(0x3);這樣MDIV=56 ,PDIV = 2, SDIV=3. mpll = (2*64*12)/(4*8)=48MHZ;
UPLLCON:是配置USB使用的時鐘的配置寄存器。配置方式與計算方式
其中對應的位與MPLLCON相同。(現在還沒有使用到)
CLKCON:就是按照對應的位配置哪些設備的時鐘使能了,對應的時鐘更夠給他提供對應的心跳。
CLKSLOW:可以對UPLL或者MPLL進行開關,也能對他們進行頻率的減小。按照默認數值就行。
CLKDIVN:這是時鐘分頻寄存器。
可以看出來,僅僅只有HCLK會受CAMDIVN的影響,但是HCLK被影響後,會間接的對PCLK產生影響,
CAMDIVN:相機時鐘分頻寄存器。
CLKDIVN與CAMDIVN聯合起來進行時鐘的分頻,推薦把HCLK配置到00,或者01上,這樣就可以實現由CLKDIVN來分頻。
在上面得到48MHZ的頻率後,現在繼續配置。CLKDIVN = 0; CLKDIVN |=0x1;進行這樣的配置。CAMDIVN=0;
最後可以得到FCLK=48M, HCLK = 48M, PCLK = 24M,
二、對其中的一些原理性的東西做介紹。
頻率是如何進行產生與分頻的。
在板子中有兩個鎖相環路。
第一個就是MPLL,這是對外部晶振(時鐘)進行倍頻,因爲高頻晶振價格高,所以就用鎖相環路來進行倍頻。
從圖中也能看出來,倍頻後的頻率沒有進過分頻就直接進入到了FCLK這裏了。
倍頻後,再經過分頻就能得到HCLK與PCLK了。所以形成我們使用的頻率要進過兩步
①倍頻,②分頻。
第二鎖相環路是UPLL,專門來爲USB提高時鐘的,不作分析。
三、對於在後面編寫串口時會出現的問題注意點提出說明。
注意①S3C2440中文檔有誤
比如我們看第一個 MDIV = 56---->m=64;PDIV=2------->p=4;SDIV=2------->s=2;按照公式計算出來頻率是96MHZ
(對於這個地方我理解是因爲MPLL得出來的頻率就是FCLK的頻率,所以在測試的時候把SDIV改成3纔得到48M,不知道這裏理解正確沒有,如果有錯,還希望指正)所以配置的時候,最好按照自己計算出的數字去配置。
注意② 系統在初始化代碼中會進行時鐘的配置,
在後面配置的時候可以先進行一下清零在重新配置,不要按照手冊上的初始值進行與或操作來進行配置,因爲初始化代碼已經改變這些時鐘的初始值了。
四、LED代碼
led.C代碼
#include <S3C2440.H>
#include "led.h"
//
void Led_Delay(void)
{
int i,j;
for(i=0;i<5000;i++)
{
for(j=0;j<50;j++);
}
}
//
void Led_Init(void)
{
//GPB5-8都配置爲輸出
GPBCON &=~(0x3FC00);
GPBCON |=(1<<10)|(1<<12)|(1<<14)|(1<<16);
}
void Led(unsigned char num)
{
GPBDAT |= 0x1E0;
switch(num)
{
case 1:
GPBDAT &=~(0x20);break;
case 2:
GPBDAT &=~(0x40);break;
case 3:
GPBDAT &=~(0x80);break;
case 4:
GPBDAT &=~(0x100);break;
}
Led_Delay();
GPBDAT |= 0x1E0;
}
void Led_Test(void)
{
unsigned char i;
for(i=1;i<5;i++)
{
Led(i);
}
}
LED.H的代碼
void Led_Delay(void); //led中專用延時函數
void Led_Init(void); //led中基本初始化操作
void Led(unsigned char num); //第num個led被點亮
void Led_Test(void); //led測試程序