新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > ARM學(xué)習(xí)之定時(shí)器Timer0實(shí)驗(yàn)

ARM學(xué)習(xí)之定時(shí)器Timer0實(shí)驗(yàn)

作者: 時(shí)間:2016-11-19 來源:網(wǎng)絡(luò) 收藏
/*
Project: Timer0實(shí)驗(yàn)
Writer: SHOW
Time: 2011/10/16
Hareware: 硬件平臺(tái):mini2440 , J-link.
Function: 通過定時(shí)器0實(shí)現(xiàn)LED1以1s的時(shí)間間隔閃爍。
Direction:這個(gè)實(shí)驗(yàn)主要設(shè)計(jì)的知識(shí)是定時(shí)器與定時(shí)器時(shí)鐘源的設(shè)置,整個(gè)實(shí)驗(yàn)思路如下:
1.設(shè)置定時(shí)器時(shí)鐘源PCLK大小。
2.設(shè)置定時(shí)器定時(shí)頻率大小。
3.定時(shí)時(shí)間到進(jìn)入中斷服務(wù)函數(shù),讓lED1閃爍。
參考代碼:國嵌ARM精講第三天演示程序,JustDo的CLK實(shí)驗(yàn)。
參考書籍:韋東山《嵌入式linux應(yīng)用開發(fā)完全手冊(cè)P166。s3c2440手冊(cè)。

*/
#include "2440addr.h"
#include "2440lib.h"
#include "2440slib.h"
#include "def.h"
#include "mmu.h"
#include "Option.h"


#define LED1_OFF (1<<5)
#define LED2_OFF (1<<6)
#define LED3_OFF (1<<7)
#define LED4_OFF (1<<8)


#define MPLL_200MHZ ((0x5c<<12) | (0x01<<4) | (0x02))


void Init_LED(void);
void __irq EintHandler(void);
void Set_TimerSourceClock_PCLK(void);
void Init_Timer0(void);
void __irq IRQ_Timer0_Handle(void);
void LED_Run(void);




//========================================================================
// 函數(shù)名稱: 延時(shí)1ms子函數(shù)
// 功能描述: 延時(shí)
// 參數(shù): times為延時(shí)的ms數(shù)。
// 返回值: void
//========================================================================
void Delay1ms(int times)
{
int i;
for( ; times > 0; times-- )
for(i=400; i>0 ; i--);
}


//========================================================================
// 函數(shù)名稱: 主函數(shù)
// 功能描述: 函數(shù)入口
// 參數(shù): void
// 返回值: void
//========================================================================
void Main(void)
{
MMU_Init();
Init_LED(); //初始化LED。
Set_TimerSourceClock_PCLK();
Init_Timer0();

while(1);

}


//========================================================================
// 函數(shù)名稱: 定時(shí)器時(shí)鐘源頻率PCLK設(shè)置子函數(shù)
// 功能描述完成對(duì)時(shí)鐘源的設(shè)置。并且確定MPLL與PCLK大小。
// 參數(shù): void
// 返回值: void
// PS->時(shí)鐘源設(shè)置步驟: 1.定時(shí)器的時(shí)鐘源由MPLL的PCLK提供。這里首先先設(shè)置MPLL為200M,通過CLKDIVN寄存器設(shè)置
// FCLK,HCLK,PCLK的的分頻比,得到需要的PCLK = 50M。
// 2.MPLL的設(shè)置方法:MPLL與FCLK的設(shè)置計(jì)算公式一樣,設(shè)置對(duì)應(yīng)的寄存器為MPLLCON。
//MPLLCON的[19:12]為MDIV,[9:4]為PDIV,[1:0]為SDIV。其中m=MDIV+8,p=PDIV+2,s=SDIV。
// 計(jì)算公式為MPLL(FCLK) = (2 * m * Fin)/(p * 2^s)。PS: Fin為板子外接晶振頻率,MIni2440的Fin = 12M。
// 總結(jié): 設(shè)置定時(shí)器時(shí)鐘源是頻率,步驟(1)首先設(shè)置MPLLCON確定FCLK。(2)再設(shè)置CLKDIVN確定分頻比確定PCLK。一共需要設(shè)置MPLLCON和CLKDIVN兩個(gè)寄存器。
//========================================================================
void Set_TimerSourceClock_PCLK(void)
{
rMPLLCON = 0;
rMPLLCON |= MPLL_200MHZ; // MPLL = FCLK
rCLKDIVN = 0x03; // FCLK:HCLK:PCLK = 1:2:4 => PCLK = 50MHz.
//rMPLLCON = 0;
//rMPLLCON |= (0x3f<<12 | 2<<4 | 2<<0);//設(shè)置FCLK的值
//rCLKDIVN |= (1<<2 | 1<<0);//設(shè)置FCLK:HCLK:PCLK的比值

}




//========================================================================
// 函數(shù)名稱: 定時(shí)器初始化子函數(shù)
// 功能描述: 完成對(duì)定時(shí)器0的設(shè)置與開定時(shí)器中斷。
// 參數(shù): void
// 返回值: void
// PS->定時(shí)器的設(shè)置步驟: 根據(jù)格式 定時(shí)器輸出頻率= PCLK/{prescaler value+1}/{divider value}
//prescaler value = 0~255,divider value = 2,4,8,16。
//1.設(shè)置定時(shí)器配置寄存器0(TCFG0)確定prescaler value。
//2.設(shè)置定時(shí)器配置寄存器1(TGFG1)確定divider value。
//3.設(shè)置定時(shí)器0計(jì)數(shù)緩存寄存器(TCNTB0)與比較緩存寄存器(TCMPB0)確定計(jì)數(shù)初值。
//4.設(shè)置寄存器TCON,確定定時(shí)器工作方式,并且啟動(dòng)定時(shí)器。
//========================================================================
void Init_Timer0(void)
{
rTCFG0 = 49; //prescaler = 49
rTCFG1 |= 0x03; //divider = 16
rTCNTB0 = 62500; //TCNTB0[15:0]=計(jì)數(shù)值 50000000/49+1/16=62500


rTCON |=(1<<1); //更新TCNTB0 和 TCMTB0的值
rTCON =0;//將TCON的值清0,注這一步很重要,如沒有,定時(shí)器將一直更新TCNTB0和TCMTB0的值導(dǎo)致無法啟動(dòng)
rTCON |= (1<<3 | 1<<0);//啟動(dòng)定時(shí)器0,并設(shè)置為自動(dòng)裝載

ClearPending(BIT_TIMER0);
pISR_TIMER0 = (U32)IRQ_Timer0_Handle; // 中斷入口
EnableIrq(BIT_TIMER0); //開中斷
}


//========================================================================
// 函數(shù)名稱: LED初始化子函數(shù)
// 功能描述: 初始化IO口 設(shè)置GPIO為輸出口。
// 參數(shù): void
// 返回值: void
//========================================================================
void Init_LED(void)
{
//rGPBCON = 0; 復(fù)位即為0可不用先給0。
rGPBCON |= (1<<10) | (1<<12) | (1<<14) | (1<<16); // 設(shè)置GPB5~GPB8 為輸出口。
rGPBDAT |= (LED1_OFF | LED2_OFF | LED3_OFF | LED4_OFF);// 初始化熄滅。
}


//========================================================================
// 函數(shù)名稱: Timer0中斷服務(wù)函數(shù)
// 功能描述: 進(jìn)入中斷后LED亮1s,滅1秒。
// 參數(shù): void
// 返回值: void
//========================================================================
void __irq IRQ_Timer0_Handle(void)
{
ClearPending(BIT_TIMER0);
LED_Run();


}


//========================================================================
// 函數(shù)名稱: LED閃爍函數(shù)
// 功能描述: 前后兩次分別執(zhí)行與或操作,使LED產(chǎn)生亮滅。
// 參數(shù): void
// 返回值: void
//========================================================================
void LED_Run(void)
{
if(rGPBDAT &(1<<5))
rGPBDAT &=~(1<<5);
else
rGPBDAT |=(1<<5);
}


評(píng)論


技術(shù)專區(qū)

關(guān)閉