微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > ARM学习之定时器Timer0实验

ARM学习之定时器Timer0实验

时间:11-19 来源:互联网 点击:
/*
Project: Timer0实验
Writer: SHOW
Time: 2011/10/16
Hareware: 硬件平台:mini2440 , J-link.
Function: 通过定时器0实现LED1以1s的时间间隔闪烁。
Direction:这个实验主要设计的知识是定时器与定时器时钟源的设置,整个实验思路如下:
1.设置定时器时钟源PCLK大小。
2.设置定时器定时频率大小。
3.定时时间到进入中断服务函数,让lED1闪烁。
参考代码:国嵌ARM精讲第三天演示程序,JustDo的CLK实验。
参考书籍:韦东山《嵌入式linux应用开发完全手册P166。s3c2440手册。

*/
#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);

//========================================================================
// 函数名称: 延时1ms子函数
// 功能描述: 延时
// 参数: times为延时的ms数。
// 返回值: void
//========================================================================
void Delay1ms(int times)
{
int i;
for( ; times > 0; times-- )
for(i=400; i>0 ; i--);
}

//========================================================================
// 函数名称: 主函数
// 功能描述: 函数入口
// 参数: void
// 返回值: void
//========================================================================
void Main(void)
{
MMU_Init();
Init_LED(); //初始化LED。
Set_TimerSourceClock_PCLK();
Init_Timer0();

while(1);

}

//========================================================================
// 函数名称: 定时器时钟源频率PCLK设置子函数
// 功能描述完成对时钟源的设置。并且确定MPLL与PCLK大小。
// 参数: void
// 返回值: void
// PS->时钟源设置步骤: 1.定时器的时钟源由MPLL的PCLK提供。这里首先先设置MPLL为200M,通过CLKdivN寄存器设置
// FCLK,HCLK,PCLK的的分频比,得到需要的PCLK = 50M。
// 2.MPLL的设置方法:MPLL与FCLK的设置计算公式一样,设置对应的寄存器为MPLLCON。
//MPLLCON的[19:12]为Mdiv,[9:4]为Pdiv,[1:0]为Sdiv。其中m=Mdiv+8,p=Pdiv+2,s=Sdiv。
// 计算公式为MPLL(FCLK) = (2 * m * Fin)/(p * 2^s)。PS: Fin为板子外接晶振频率,MIni2440的Fin = 12M。
// 总结: 设置定时器时钟源是频率,步骤(1)首先设置MPLLCON确定FCLK。(2)再设置CLKdivN确定分频比确定PCLK。一共需要设置MPLLCON和CLKdivN两个寄存器。
//========================================================================
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);//设置FCLK的值
//rCLKdivN |= (1<2 | 1<0);//设置FCLK:HCLK:PCLK的比值

}

//========================================================================
// 函数名称: 定时器初始化子函数
// 功能描述: 完成对定时器0的设置与开定时器中断
// 参数: void
// 返回值: void
// PS->定时器的设置步骤: 根据格式 定时器输出频率= PCLK/{prescaler value+1}/{divider value}
//prescaler value = 0~255,divider value = 2,4,8,16。
//1.设置定时器配置寄存器0(TCFG0)确定prescaler value。
//2.设置定时器配置寄存器1(TGFG1)确定divider value。
//3.设置定时器0计数缓存寄存器(TCNTB0)与比较缓存寄存器(TCMPB0)确定计数初值。
//4.设置寄存器TCON,确定定时器工作方式,并且启动定时器。
//========================================================================
void Init_Timer0(void)
{
rTCFG0 = 49; //prescaler = 49
rTCFG1 |= 0x03; //divider = 16
rTCNTB0 = 62500; //TCNTB0[15:0]=计数值 50000000/49+1/16=62500

rTCON |=(1<1); //更新TCNTB0 和 TCMTB0的值
rTCON =0;//将TCON的值清0,注这一步很重要,如没有,定时器将一直更新TCNTB0和TCMTB0的值导致无法启动
rTCON |= (1<3 | 1<0);//启动定时器0,并设置为自动装载

ClearPending(BIT_TIMER0);
pISR_TIMER0 = (U32)IRQ_Timer0_Handle; // 中断入口
EnableIrq(BIT_TIMER0); //开中断
}

//========================================================================
// 函数名称: LED初始化子函数
// 功能描述: 初始化IO口 设置GPIO为输出口。
// 参数: void
// 返回值: void
//========================================================================
void Init_LED(void)
{
//rGPBCON = 0; 复位即为0可不用先给0。
rGPBCON |= (1<10) | (1<12) | (1<14) | (1<16); // 设置GPB5~GPB8 为输出口。
rGPBDAT |= (LED1_OFF | LED2_OFF | LED3_OFF | LED4_OFF);// 初始化熄灭。
}

//========================================================================
// 函数名称: Timer0中断服务函数
// 功能描述: 进入中断后LED亮1s,灭1秒。
// 参数: void
// 返回值: void
//========================================================================
void __irq IRQ_Timer0_Handle(void)
{
ClearPending(BIT_TIMER0);
LED_Run();

}

//========================================================================
// 函数名称: LED闪烁函数
// 功能描述: 前后两次分别执行与或操作,使LED产生亮灭。
// 参数: void
// 返回值: void
//========================================================================
void LED_Run(void)
{
if(rGPBDAT &(1<5))
rGPBDAT &=~(1<5);
else
rGPBDAT |=(1<5);
}

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top