您的位置 首页 新能源

ARM学习之定时器Timer0试验

/*Project:Timer0实验Writer:SHOWTime:2011/10/16Hareware:硬件平台:mini2440,J-link.Function:通过定时器0实现LED1…

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

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/qiche/xinnengyuan/325897.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部