S3C2440有5个16位的定时器,其中定时器0、1、2、3有脉冲宽度调制(PWM)功能,定时器4是一个内部定时器,没有外部输出引脚。在这里不详细的写定时器的工作原理,只对定时器0进行操作,其他的定时器操作类似。不废话了,上程序分析:
1、整体程序框架

程序依然由两部分组成,startcode为启动代码(其实并没有用到所有的启动代码,这里只是将它们一起添加了。),source为自己写的程序。
2、source下程序解析
Main.c文件
#include"timer.h"
#include"irr.h"
#include"led.h"
extern int flag;
int Main()
{
Timer0_Init(); //定时器0初始化函数
Isr_Init(); //中断初始化函数
Led1_Init(); //Led初始化函数
while(1)
{
; //while(1)循环,这里为空,表示不执行任何命令;从这点也可以体会到Led闪烁是由于定时器0产生中断,执行中断服务程序的结果。
}
return 0;
}
timer.h文件
#ifndef_EIMER0_H_
#define_TIMER0_H_
#include"2440addr.h"
void Timer0_Init(void);
#endif
timer.c文件
#include"2440addr.h"
void Timer0_Init(void)
{
rTCFG0 &= ~(0xff); //将寄存器TCFG0的低8位清零(TCFG0用于配置第一级分频器)
rTCFG0 |= 99; //将分频系数-1写入TCFG0的低8位(分频系数=prescaler //value+1,这里prescaler=99)
rTCFG1 &= ~(0xf); //将TCFG1的低4位清零(配置第二分频器)
rTCFG1 |= 0x02; //将TCFG1的低4位赋值为0x02,即选择8分频输出
rTCMPB0 =0; //给TCMPB0装入初值,当TCNTB0递减到这个值时,产生中断
rTCNTB0 = 62500; //定时器0的输入时钟频率为62.5KHz,即定时器每秒计数62500次,因此初始化 //的 时候装入62500,1s产生一次中断
rTCON |= (1<<1);
rTCON = 0x09; //设置自动加载位,同时开启定时器。
}
irr.h文件
#ifndef _ISRSERVICE_H_
#define _ISRSERVICE_H_
void Isr_Init(void) ;
void __irq Timer0_Isr(void);
#endif
irr.c文件
#include"config.h"
#include"irr.h"
#include"led.h"
int flag=0;
void Isr_Init(void)
{
rINTMSK&=~(1<<10);//记得把中断打开啊。。。。
pISR_TIMER0=(unsigned int)Timer0_Isr; //将中断服务程序的入口地址加载到内存地址 //0x33ffff20处
}
void __irq Timer0_Isr() //中断服务函数,当定时器0产生中断时执行。
{
flag=!flag;
if(flag==1)
{
Led1_On();
}
else
{
Led1_Off();
}
rSRCPND |=1<<10; //产生中断后将这两位清零
rINTPND |=1<<10;
}
led.h文件
#ifndef_LED_H_
#define_LED_H_
extern void Led1_Init(void);
extern void Led1_On(void);
extern void Led1_Off(void);
led.c文件 实现LED的初始化,和点亮四个LED、熄灭四个LED
#include"2440addr.h"
#include"led.h"
void Led1_Init(void)
{
rGPBCON &=~(3<<10 |3<<12 | 3<<14 | 3<<16);
rGPBCON |=(1<<10 | 1<<12 |1<<14 |1<<16);
rGPBUP &=~(1<<5 | 1<<6 | 1<<7 | 1<<8);
rGPBDAT |=(1<<5 | 1<<6 | 1<<7 | 1<<8);
}
void Led1_On(void)
{
rGPBDAT &= ~(1<<5 | 1<<6 | 1<<7 | 1<<8);
}
void Led1_Off(void)
{
rGPBDAT |=(1<<5 | 1<<6 | 1<<7 | 1<<8);
}
以上程序可以实现4个LED以1秒的频率闪烁(4个同时,不是流水灯)。