Cortex-M3 (NXP LPC1788)之SysTick系統(tǒng)節(jié)拍定時器
一,系統(tǒng)時鐘控制
LPC1788有3個獨立的振蕩器。他們是主振蕩器,內(nèi)部RC振蕩器,RTC振蕩器。復位后,LPC1788將用內(nèi)部的RC振蕩器運行,直到被軟件切換。這樣就能在沒有任何外部晶振的情況下運行。LPC1788的時鐘控制如圖1所示
本文引用地址:http://m.butianyuan.cn/article/201611/318446.htm在開發(fā)板上使用12M的晶振作為主振蕩器,它通過鎖相環(huán)PLL0來提高頻率提供CPU。由于芯片總是從內(nèi)部的RC振蕩器開始工作,因此主振蕩器只會應(yīng)軟件的請求而啟動。實現(xiàn)方法是設(shè)定SCS寄存器中的OSCEN位使能。主振蕩器提供一個狀態(tài)標志SCS寄存器的OSCSTAT位,這樣軟件就可以確定何時主振蕩器在運行穩(wěn)定。此時,軟件可以控制切換到主振蕩器,使其作為時鐘源。在啟動以前,必須通過SCS的OSCRANGE位,選擇一個頻率范圍。在確定了主振蕩器之后,需要進行鎖相環(huán)的配置。1,配置CLKSRCSEL選擇正確的時鐘源。2,將正確的PLL設(shè)置值寫入PLLCFG寄存器并且在PLLCON中使能PLL。3,向PLLFEED寄存器中寫入饋送序列0xAA,0x55。4,設(shè)置所需的時鐘分配器如CCLKSEL,PCLSEL,EMCCLKSEL,以及USBCLKSEL寄存器。5,查詢PLLSTAT寄存器等待PLL鎖定。
二,系統(tǒng)節(jié)拍定時器的控制
LPC1788的系統(tǒng)節(jié)拍定時器是一個24位的定時器,當數(shù)值達到0時產(chǎn)生中斷。系統(tǒng)節(jié)拍定時器的時鐘信號可以由CPU時鐘提供(即圖1中的cclk)。想要在規(guī)定的時間間隔循環(huán)的產(chǎn)生中斷,必須將指定的正確時間間隔值裝入STRELOAD寄存器進行初始化。假如我們選擇cclk作為系統(tǒng)節(jié)拍的時鐘信號,并且根據(jù)開發(fā)板將系統(tǒng)時鐘設(shè)置成12MHZ,為了循環(huán)1ms產(chǎn)生一次中斷,我們寫入STRELOAD的值為cclk/1000 - 1 。
程序的代碼如下,使LED燈每500ms閃爍。SystemInit函數(shù)在啟動文件中被調(diào)用。
- #definerFIO1DIR(*(volatileunsigned*)0x20098020)
- #definerFIO1MASK(*(volatileunsigned*)0x20098030)
- #definerFIO1PIN(*(volatileunsigned*)0x20098034)
- #definerFIO1SET(*(volatileunsigned*)0x20098038)
- #definerFIO1CLR(*(volatileunsigned*)0x2009803c)
- #definerCLKSRCSEL(*(unsigned*)(0x400FC10C))//時鐘源選擇寄存器
- #definerPLL0CON(*(unsigned*)(0x400FC080))//PLL0控制寄存器
- #definerPLL0CFG(*(unsigned*)(0x400FC084))//PLL0配置寄存器
- #definerPLL0STAT(*(unsigned*)(0x400FC088))//PLL0狀態(tài)寄存器
- #definerPLL0FEED(*(unsigned*)(0x400FC08C))//PLL0饋送寄存器
- #definerPLL1CON(*(unsigned*)(0x400FC0A0))
- #definerPLL1CFG(*(unsigned*)(0x400FC0A4))
- #definerPLL1STAT(*(unsigned*)(0x400FC0A8))
- #definerPLL1FEED(*(unsigned*)(0x400FC0AC))
- #definerCCLKSEL(*(unsigned*)(0x400FC104))//CPU時鐘選擇寄存器
- #definerUSBCLKSEL(*(unsigned*)(0x400FC108))//USB時鐘選擇寄存器
- #definerPCLKSEL(*(unsigned*)(0x400FC1A8))//外設(shè)時鐘寄存器
- #definerPCON(*(unsigned*)(0x400FC0C0))
- #definerPXCONP(*(unsigned*)(0x400FC0C4))
- #definerSCS(*(unsigned*)(0x400FC1A0))//系統(tǒng)控制和狀態(tài)寄存器
- #definerCLKOUTCFG(*(unsigned*)(0x400FC1C8))
- #definerSTCTRL(*(unsigned*)(0xE000E010))
- #definerSTRELOAD(*(unsigned*)(0xE000E014))
- #definerSTCURR(*(unsigned*)(0xE000E018))
- #definerSTALIB(*(unsigned*)(0xE000E01C))
- #defineCCLK120000000
- volatileunsignedlongSysTickCnt;
- /*
- 系統(tǒng)時鐘初始化
- */
- voidSystemInit()
- {
- rSCS&=~(0x1<<4);//頻率12M
- rSCS|=(0x1<<5);//使能主振蕩器
- while(0==(rSCS&(0x1<<6)));//等待主振蕩器穩(wěn)定
- rCLKSRCSEL=0x1;
- rPLL0CFG=0x9;//配置CCLK=120M
- rPLL0CON=0x01;
- rPLL0FEED=0xAA;
- rPLL0FEED=0x55;
- while(0==(rPLL0STAT&(0x1<<10)));
- rCCLKSEL=(0x1|(0x1<<8));
- rPCLKSEL=0x2;//配置PCLK=60M
- rCLKOUTCFG=0x0|(0xb<<4)|(0x1<<8);
- }
- /*
- 系統(tǒng)節(jié)拍定時器初始化
- */
- unsignedcharSysTick_Config(unsignedintticks)
- {
- if(ticks>0xFFFFFFUL)
- return0;
- rSTRELOAD=ticks;
- rSTCURR=0x0;
- rSTCTRL=(0x1)|(0x1<<1)|(0x1<<2);
- return1;
- }
- /*
- 系統(tǒng)節(jié)拍定時器中斷處理函數(shù)
- */
- voidSysTick_Handler(void)
- {
- SysTickCnt++;
- }
- intmain()
- {
- unsignedcharvalue=1;
- SysTick_Config(CCLK/1000-1);//每1ms產(chǎn)生一次SysTick系統(tǒng)異常
- rFIO1DIR|=(1<<18);//GPIO1.18->OUTPUT
- while(1)
- {
- if(SysTickCnt>=500)
- {
- SysTickCnt=0;
- value=!value;
- }
- if(0==value)
- {
- rFIO1PIN&=~(1<<18);
- }
- elseif(1==value)
- {
- rFIO1PIN|=(1<<18);
- }
- }
- }
關(guān)于SysTick的異常的優(yōu)先級可以在SHPR3中進行設(shè)置,優(yōu)先級等級可以從0~31。初始化默認為0,只低于固定的負數(shù)優(yōu)先級的復位,硬件故障和NMI。
評論