找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 6499|回復(fù): 2
打印 上一主題 下一主題
收起左側(cè)

LPC11C14學(xué)習(xí)

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:60266 發(fā)表于 2014-8-17 22:17 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
功能:(設(shè)置 GPIO口方向),參數(shù)(端口號,位,輸入或輸出(0入1出))
             GPIOSetDir( PORT0, 1, 0 );

      GPIOSetValue()  一個是設(shè)置端口方向,一個是設(shè)置輸出的值,直接調(diào)用就可以了。

如果在片內(nèi)RAM當中運行代碼并且應(yīng)用程序需要調(diào)用中斷,那么必須將中斷向量重新映射到Flash地址0x0。這樣做是因為所有的異常向量都位于地址0x0及以上。通過將寄存器MEMMAP(位于系統(tǒng)控制模塊當中)配置為用戶RAM模式來實現(xiàn)這一點。



#ifdef __DEBUG_RAM   

  LPC_SYSCON->SYSMEMREMAP = 0x1;  

#else

#ifdef __DEBUG_FLASH   

  LPC_SYSCON->SYSMEMREMAP = 0x2;

#endif

#endif


ARM微控制器有一個顯著的特點,就是都可以把時鐘頻率倍頻到很高,具體到多高,每個系列的微控制器都有一個指標,我們現(xiàn)在要學(xué)的Cortex-M0內(nèi)核處理器LPC1114最高能到50MHz,當然,其它的ARM內(nèi)核微處理器可以倍頻到更高,現(xiàn)在好多手機都采用了ARM內(nèi)核處理器,比如賣的很火的諾基亞5233就是采用了ARM11處理器,ARM11的處理器的主頻為433MHz,比Cortex-M0的50MHz高多了吧!所以Cortex-M0處理器被ARM稱為入門級的內(nèi)核!
要實現(xiàn)對系統(tǒng)時鐘的配置,時鐘配置圖是必須要看懂的!因為它比文字更具有參考價值,看上這張圖配置時鐘,絕對不會出現(xiàn)漏洞�。ㄎ医ㄗh你把這張圖打印出來貼到你的墻上,我就是這么做的,你看著辦吧�。┙酉聛�,我將一步一步引領(lǐng)你徹底看懂這張“時鐘配置圖”。

注意了,要開始講圖了�。ㄟ@張圖就是數(shù)據(jù)手冊說的時鐘產(chǎn)生單元:CGU(Clock generation unit))
LPC1114內(nèi)部含有3個時鐘振蕩器:系統(tǒng)振蕩器,IRC振蕩器,看門狗振蕩器。系統(tǒng)振蕩器就是需要配合外部晶振工作的振蕩器(這是任何一款單片機都有的);IRC振蕩器就是內(nèi)部RC振蕩器,就是我在上面“總覽LPC1114”中提到的那個LPC1114一上電就默認選擇的12MHz時鐘振蕩器,它的精度沒有配合外部晶振的系統(tǒng)振蕩器高;看門狗振蕩器就是給看門狗提供的時鐘振蕩器!這么說大家明白了吧,在接下來的敘述里面,一提到系統(tǒng)振蕩器就是指利用外部晶振的時鐘振蕩器,IRC振蕩器就是指LPC1114的內(nèi)部時鐘振蕩器,可不要搞混了哦!
我們先從圖的中心點看起,找到“主時鐘”三個字,看“主時鐘”的左面,有四條線到了“主時鐘”的框上,這四條線就是“主時鐘”的來源,它們分別是:IRC振蕩器,看門狗振蕩器,倍頻之前的時鐘(sys_pllclkin)和倍頻之后的時鐘(sys_pllclkout)。也就是主時鐘可以在這四個時鐘源當中選擇一個做為主時鐘!通過操縱(人家專業(yè)名詞不叫“操縱”,叫“訪問”)“主時鐘源選擇寄存器(MAINCLKSEL)”實現(xiàn)。這個32位的主時鐘源選擇寄存器MAINCLKSEL只用到了兩位(誰讓兩位就可以表示四種狀態(tài)呢�。�,剩下的全都是保留位,如下:
位(bit) 符號 值 描述 復(fù)位值
1:0 SEL 00 選擇IRC振蕩器 00
01 選擇輸入到PLL之前的時鐘
10 選擇看門狗振蕩器
11 選擇PLL之后的時鐘
31:2 - - 保留 0
看復(fù)位值,系統(tǒng)默認情況下就是選擇IRC振蕩器作為系統(tǒng)的主時鐘的。我們?yōu)榱俗孡PC1114發(fā)揮出它最大的性能,就喜歡選擇PLL(PLL就是倍頻的意思)后的時鐘,在程序中這樣寫:
SYSCON->MAINCLKSEL = 0x00000003; //主時鐘源選擇PLL后的時鐘

接下來看圖上,找到“系統(tǒng)PLL”方框,看它左面倒梯形方框的左面,有三條線,這三條線就是可以做為倍頻時鐘源的時鐘源。這三個時鐘源分別是:IRC振蕩器,系統(tǒng)振蕩器,看門狗振蕩器。這不就是LPC1114的三個時鐘振蕩器么,原來它們都可以做為PLL的時鐘源!該選擇誰捏?這就要操縱“系統(tǒng)倍頻時鐘源選擇寄存器(SYSPLLCLKSEL)”了。這個32位的寄存器也是只用到了兩位:
(兩位就可以表示四種狀態(tài)了,三個狀態(tài)當然是綽綽有余�。�
位(bit) 符號 值 描述 復(fù)位值
1:0 SEL 00 選擇IRC振蕩器 00
01 選擇系統(tǒng)振蕩器
10 選擇看門狗振蕩器
11 保留
31:2 - - 保留 0
看復(fù)位值,系統(tǒng)默認情況下就是選擇IRC振蕩器作為PLL輸入時鐘源的。既然我們外部安插了精確的12M晶振,就是想把它做為時鐘源的,選擇上面表格當中的01,就是選擇了外部12M晶振�。ㄎ以谙惹疤岬竭^,“系統(tǒng)振蕩器”就是代表外部的晶振,為了防止看的不仔細的朋友存在,我還是再說一遍吧�。�
程序中這樣寫:
SYSCON->SYSPLLCLKSEL = 0x00000001; //PLL時鐘源選擇“系統(tǒng)振蕩器”
當然,操作順序應(yīng)該是先選擇PLL的時鐘源,再選擇主時鐘源!

到現(xiàn)在,“主時鐘”左面的部分就看完了,接下來看“主時鐘”右面的!

右面部分從上往下看,首先呢,是“系統(tǒng)時鐘分頻器”方框,方框的右面橫線上寫著“系統(tǒng)時鐘”四個字。怎么樣!迷惑了吧!這里方框中所提到的“系統(tǒng)時鐘分頻器”其實就是“系統(tǒng)AHB時鐘分頻器(SYSAHBCLKDIV)”。這個寄存器的名字會把好多人迷惑的!因為這個分頻器可不僅僅給AHB(LPC1114的AHB只有GPIO,關(guān)于什么是AHB,什么是APB,去百度搜一下吧!介紹需要兩頁紙哦�。┨峁⿻r鐘的,它除了給AHB提供時鐘,還給內(nèi)核,存儲器以及APB提供時鐘。一定意義上說,它就是“系統(tǒng)時鐘分頻器”了,給這個寄存器寫0,LPC1114就不工作了;給這個寄存器寫1,LPC1114的系統(tǒng)時鐘就是主時鐘除以1;寫2,LPC1114的系統(tǒng)時鐘就是主時鐘除以2,以此類推!假如把外部晶振倍頻了4倍作為主時鐘,主時鐘就是48MHz,對SYSAHBCLKDIV寫4,系統(tǒng)時鐘就是12MHz。這時候有人就會有疑問了:“神經(jīng)病��!既然都倍頻起來了,還要縮小”!其實這是因為有時候我們的電路板上的其它芯片不能夠在很快的頻率下工作,否則就會出錯,比如無線通信芯片NRF24L01的速率就不能超過10MHz,所以某些時候,需要多分頻了。規(guī)定最多可以分頻255,所以你就可以想到,這個寄存器只用8位就可以了:
位(bit) 符號 值 描述 復(fù)位值
7:0 DIV 00000000 關(guān)閉系統(tǒng)時鐘 00000001
00000001 用1除
00000010 用2除
......
......
11111111 用255除
31:8 - - 保留 0
一般情況下,我們寫1,程序如下:(這條語句可以不用寫,因為默認值就是1)
SYSCON->SYSAHBCLKDIV = 0x01; //AHB時鐘分頻值為1

再往下看圖,數(shù)一下,有6個分頻器,這6個分頻器是:SSP0分頻器,SSP1分頻器,UART分頻器,SysTick分頻器,看門狗分頻器和CLKOUT引腳分頻器。
這些分頻器寄存器和SYSAHBCLKDIV是一樣的,都是用了8位,都是可以最多分頻255,我這里就不把表格畫出來了,唯一不同的是,這6個分頻器寄存器的復(fù)位值為0,而不是1。也就是說,在默認情況下,這些外設(shè)都是不工作的(沒有時鐘怎么工作�。┻@完全是為了節(jié)能做貢獻,不用就不讓它浪費電,用的時候再開!
看最后兩個分頻器!通過上面的介紹,你現(xiàn)在也可以看懂了,圖上說:看門狗的時鐘源可以有3個來源,不僅僅只有“看門狗振蕩器”可以給它提供,還可以用主時鐘或是IRC振蕩器!多么靈活的LPC1114呀!
LPC1114上的第四引腳是:PIO0_1/CLKOUT/CT32B0MAT2。這個腳可以當做P0.1腳,CLKOUT引腳和32位定時器的輸出腳。CLKOUT引腳,顧名思義,它是用來輸出時鐘的,輸出時鐘有什么用?
用處1:給別的需要時鐘的芯片提供時鐘;
用處2:用示波器觀察此引腳上的頻率可以判斷你寫的時鐘配置程序是否正確。
這個引腳在默認的情況下是P0.1腳,假如你要看看到底有沒有把外部的12MHz晶振倍頻到48MHz,你可以把這只腳配置為CLKOUT引腳,用示波器觀察觀察!
由圖中可知,它可以選擇IRC振蕩器,系統(tǒng)振蕩器,看門狗振蕩器以及主時鐘源作為時鐘源,選擇誰作為它的時鐘源,你就可以看到誰的頻率到底是多少了。
(在下面會給出實現(xiàn)的程序,不要急哦!)我曾經(jīng)用這個腳觀察了一下IRC振蕩器的頻率,值在12.01MHz和12.00MHz之間來回跳!后來又看了一下外部晶振的頻率,穩(wěn)穩(wěn)的顯示12.00MHz。

到現(xiàn)在,這張圖就看完了,你也應(yīng)該看懂了!

除了上面提到的“選擇寄存器”,還需要有“使能寄存器”的配合才能使選擇的時鐘源起作用。下面是一個典型的時鐘配置函數(shù):







void SysCLK_config(void)
{
uint8 i;

SYSCON->PDRUNCFG &= ~(1 << 5); //系統(tǒng)振蕩器上電
SYSCON->SYSOSCCTRL = 0x00000000; //振蕩器未被旁路,1~20Mhz頻率輸入
for (i = 0; i < 200; i++) __nop(); //等待振蕩器穩(wěn)定
SYSCON->SYSPLLCLKSEL = 0x00000001; //PLL時鐘源選擇“系統(tǒng)振蕩器”
SYSCON->SYSPLLCLKUEN = 0x01; //更新PLL選擇時鐘源
SYSCON->SYSPLLCLKUEN = 0x00; //先寫0,再寫1達到更新時鐘源的目的
SYSCON->SYSPLLCLKUEN = 0x01;
while (!(SYSCON->SYSPLLCLKUEN & 0x01)); //確定時鐘源更新后向下執(zhí)行

SYSCON->SYSPLLCTRL = 0x00000023; //設(shè)置M=4;P=2; FCLKOUT=12*4=48Mhz
SYSCON->PDRUNCFG &= ~(1 << 7); //PLL上電
while (!(SYSCON->SYSPLLSTAT & 0x01)); //確定PLL鎖定以后向下執(zhí)行

SYSCON->MAINCLKSEL = 0x00000003; //主時鐘源選擇PLL后的時鐘
SYSCON->MAINCLKUEN = 0x01; //更新主時鐘源
SYSCON->MAINCLKUEN = 0x00; //先寫0,再寫1達到更新時鐘源的目的
SYSCON->MAINCLKUEN = 0x01;
while (!(SYSCON->MAINCLKUEN & 0x01)); //確定主時鐘鎖定以后向下執(zhí)行
SYSCON->SYSAHBCLKDIV = 0x01; //AHB時鐘分頻值為1,使AHB時鐘設(shè)置為48Mhz
}

程序詳解:
在看程序詳解之前,你最好先看一遍程序。
(如果你是一位剛剛從51單片機接觸ARM單片機的朋友,你會發(fā)現(xiàn)這個函數(shù)里面的語句書寫方式完全和以前寫51程序不一樣啊,以前給51的寄存器寫值,是用這么一種形式:
SBUF = 0X88;
而現(xiàn)在是用這么一種形式:
SYSCON->MAINCLKSEL=0X00000001;
這里為什么不直接寫成:
MAINCLKSEL=0X00000001;
這其實是因為在NXPLPC11XX.H文件中對系統(tǒng)寄存器的定義采用了結(jié)構(gòu)體(Struct)的形式。現(xiàn)在,你可以在打開51單片機寄存器的定義文件REG51.H文件看一下,它對寄存器的地址定義是這樣的:
sfr SBUF = 0x99;
現(xiàn)在你再打開一下LPC1114對寄存器地址定義的NXPLPC11XX.H文件!全都是結(jié)構(gòu)體的定義,而且是純C語言寫的,再也找不到“sfr”這樣的C51語言了。關(guān)于NXPLPC11XX.H文件請看瑞嵌制作的《NXPLPC11XX.H文件詳解》。)

(在以后的程序中,我們會經(jīng)�?吹�&=~(1<<3)和|=(1<<3);這樣的句子,這些句子是對位操作用的。因為我們經(jīng)常要對32位寄存器的某一位操作,還同時不影響其它位的值,所以才有了上面這樣的形式。比如我們說我們要對某個寄存器的bit5(注意:可不是第5位,位是從0開始的)寫0,這樣寫:
寄存器&=~(1<<5);
對寄存器的bit5寫1,這樣寫:
寄存器|=(1<<5);
現(xiàn)在運用你的C語言知識分析一下,把十進制的1寫成二進制32位數(shù)就是:
00000000000000000000000000000001
(1<<5)就是把1右移5下,左面補零,執(zhí)行完這句話以后數(shù)就變成:
00000000000000000000000000100000
~(1<<5)就是再把這個數(shù)反相:
11111111111111111111111111011111
最后呢!再把這個數(shù)&給寄存器,&的操作即是遇到0與1等于0,1與0或1都還是1,所以執(zhí)行完以后,除了bit5被改成了0,其它的位都沒有變。按照相同的方法,你可以分析一下對bit5寫1的操作。)

現(xiàn)在,我們首先來看一下函數(shù)里的第一個語句是對PDRUNCFG寄存器操作,如果你的英語好的話,一眼就看出來這個寄存器是干嘛的了,就是“掉電配置寄存器”,之所以不叫“上電配置寄存器”是因為它是對某位寫“1”掉電,寫“0”上電。這個寄存器的描述請看官方數(shù)據(jù)手冊第三章�?催@個寄存器的bit5,該位控制著系統(tǒng)振蕩器的上電與掉電,默認是1,就是掉電狀態(tài),我們既然已經(jīng)決定了要用外部晶振作為時鐘源,那么現(xiàn)在就該把它上電了,于是就有了這條語句。
接下來這條語句是對SYSOSCCTRL寄存器操作,這個寄存器叫做“系統(tǒng)振蕩器控制寄存器”。(在后面的學(xué)習(xí)中,你會經(jīng)�?吹�,系統(tǒng)內(nèi)部的模塊需要好幾道門檻配置以后才能用,除了上電,還得控制,有的還需要再允許一下。這樣做看似麻煩,其實靈活�。┫到y(tǒng)控制寄存器只用了2個bit,bit0控制著系統(tǒng)振蕩器有沒有被旁路,bit1要根據(jù)外部晶振的值是多少來寫1或0。先說bit0,“被旁路”的意思就是“讓它不起作用”;“未被旁路”的意思就是“沒有讓它不起作用”。寫0表示“未被旁路”,寫1表示“被旁路”。那么什么時候被旁路呢?答:在有外部的“直接時鐘源”的時候。如果你51單片機學(xué)的很棒的話,你現(xiàn)在就應(yīng)該明白了,不明白的那就聽我給你解釋吧。其實51單片機也有不利用外部晶振而是利用“直接時鐘源”的時候,電路圖是這個樣子的:

這里我們不需要旁路晶振,所以對該位寫0。bit1是根據(jù)外部晶振的值來定的,對該位寫0表示外部晶振頻率值在1~20MHz范圍內(nèi),寫1表示外部晶振頻率值在15~50MHz范圍內(nèi)。在我們的開發(fā)板上用的晶振為12MHz,所以對該位寫0。
再往下是一條短暫延時程序,利用__nop();實現(xiàn)。給它一點時間完成任務(wù)。
再接下來的5條語句你可以把它看成一個整體,對PLL時鐘源的更新都是這個樣子的。關(guān)于SYSPLLCLKSEL寄存器,前面已經(jīng)講過了。SYSPLLCLKUEN是PLL時鐘源更新允許寄存器,根據(jù)官方數(shù)據(jù)手冊上的規(guī)定,要想實現(xiàn)更新,需要對該寄存器toggle一下,也就是對該寄存器先寫0,再寫1。while語句等待我們剛才寫的1運輸?shù)絊YSPLLCLKUEN里面。時鐘源的更新往往是需要一定時間的。
接下來,就該把選擇的時鐘源翻倍了。SYSPLLCTRL是系統(tǒng)倍頻控制寄存器,通過它可以確定倍頻的倍數(shù)。倍頻器是一個很有特點的東西。它除了可以用在單片機當中,還可以用在好多需要它的地方,比如射頻無線芯片當中可以用它來提高發(fā)射功率。倍頻器運用了模擬電子技術(shù)和數(shù)字電子技術(shù)。有時集成到芯片當中,有時單獨做成一塊芯片!關(guān)于LPC1114的倍頻器(PLL)的詳細描述,請看官方數(shù)據(jù)手冊第三章第九節(jié)。SYSPLLCTRL的bit0~bit4確定M值,bit5和bit6確定P值,bit7是DIRECT位,bit8是BYPASS位。其它位保留。bit7和bit8我們現(xiàn)在還不深究(要深究的話,還需要好好學(xué)習(xí)倍頻器的結(jié)構(gòu)),只需要知道它倆是來控制PLL的工作模式的,我們一般讓PLL工作在“普通模式”下,保持這倆位的默認值就可以。那么現(xiàn)在只剩M和P了。在普通模式下,PLL輸出頻率的計算公式如下所示:

看到上式,你可能會產(chǎn)生一個疑問:直接用M乘以PLL的輸入頻率Fclkin不行嗎?答案當然不行!為什么要確定P值呢?這個是PLL的機構(gòu)決定的,在普通模式下,輸出頻率實際上是由FCCO產(chǎn)生的,而為了能讓PLL正常工作,F(xiàn)CCO需要在156~320MHz之間�,F(xiàn)在,我們知道PLL的輸入頻率Fclkin的值為12MHz,LPC1114的允許最大工作頻率為50MHz,現(xiàn)在我們只能把它倍頻四倍到48MHz了,所以M值定位4。根據(jù)數(shù)據(jù)手冊上的規(guī)定,P可以定為四個值,即1,2,4,8。這里只有當P=2的時候,F(xiàn)CCO的值為48*2*2=192,在156~320之間。所以,我們一般情況下,就選M=4,P=2了。SYSPLLSTAT是倍頻狀態(tài)寄存器,專門用來看PLL有沒有鎖定的,它是一個只讀寄存器。
再往下的5條語句是更新主時鐘用的。和上面提到的更新PLL時鐘的語句如出一轍,我就不多講了,相信大家現(xiàn)在已經(jīng)能看懂了!
該函數(shù)的最后一句話,就是給SYSAHBCLKDIV寫1,確定分頻值為1。這個寄存器在前面已經(jīng)很詳細的講過了,這里就不啰嗦了!

到此!這個函數(shù)就都講完了。很好理解吧!這個函數(shù)就是每個工程里main函數(shù)里都會出現(xiàn)的初始化函數(shù)了。而且是必須的!為了使用方便,我已經(jīng)把這個函數(shù)放到了NXPLPC11XX.C文件里面,在你寫的main函數(shù)里直接調(diào)用函數(shù)名就可以了。

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:26188 發(fā)表于 2014-8-21 20:46 來自觸屏版 | 只看該作者
學(xué)習(xí)了,,不錯
回復(fù)

使用道具 舉報

板凳
ID:87666 發(fā)表于 2015-8-5 13:50 | 只看該作者
很詳細的東西
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表