本程序为samsung的S3C44b0x芯片的定时中断程序,可以设置定时器0~5
本程序的特点:
1. 只需设置所需的中断频率Hz,以及开启与否(1,0)即可,所有寄存器的配置由程序完成;
2. 所有寄存器配置,只配置和功能相关的寄存器,以及寄存器的相关位,而不影响其他部分。
因此,本程序可以全部或部分的复制到读者的程序中,而不会影响作者程序其他部分的功能;
编程思想:
定时器的定时中断涉及MClk、Prescaler、Mux、TCNT等寄存器,其中Precaler和TCNT的取值
均可在一定范围内任意取值,Prescaler的范围较小,而TCNT范围较宽。Mux只可取有限的几
个值。因此程序中,先固定Precaler值,并试探取一个Mux值时,能否顺利得到允许的TCNT,
若能则表示可以成功配置,则记下此时的几个值,并配置寄存器。如不能,则阶梯增加Precaler
的值,再试探至成功。
这种试探的方法,作者初步计算,常用范围(1Hz~几十KHz)应该可行,但并未真正验算。
建议:
大家也编一些只和使用参数(如中断频率和开启)相关的子程序,而实现功能的寄存器由程序自动
计算并不配置完成,遵循本程序特点的1,2两条编写的程序,使用起来会很方便,可移植性较好。
程序说明:
1. 6个定时器均使用连续中断模式,例程中关掉了定时器3;
2. 本程序在ADS1.2和SDT2.51中,使用简易JTAG调试通过;
3. 本贴内容只包含程序的主要部分,其余部分和网络上流传的程序相同,包括inc,44blinb,44binit等;
4. 由于程序中先计算频率配置寄存器,后决定是否开启寄存器,即使不用的定时器,也需要配置其频率;
//44BTEST : timer.c
/* timer.c, samsung的S3C44b0x芯片的定时中断程序,可以设置定时器0~5的定时中断 */
/* 只需设置所需的中断频率Hz,以及开启与否(1,0)即可,所有寄存器的配置由程序完成 */
/* 作者:hawkzone , 版权归作者所有:2004~ */
/* 欢迎大家检查、使用、完善,并传播 */
/* 发表于:www.devarm.com(www.devarm.com) , 20040622*/
#include "myinc.h"
void __irq Timer0Done(void);
void __irq Timer1Done(void);
void __irq Timer2Done(void);
void __irq Timer3Done(void);
void __irq Timer4Done(void);
void __irq Timer5Done(void);
/************************************************
* Timer 0 & 1 interrupt *
************************************************/
void Timer01Start(U32 freq0,U32 freq1,U8 start0,U8 start1)
// if one of time0 & time1 is used, freq0 & freq1 are needed and the same value are recommended.
{
U32 mux,pre,tmp;
Uart_Printf("[Timer 01 Interrupt test]
");
rINTMSK = rINTMSK & (~(BIT_GLOBAL|BIT_TIMER0|BIT_TIMER1));
pISR_TIMER0=(unsigned)Timer0Done;
pISR_TIMER1=(unsigned)Timer1Done;
if (start0 | start1)
{
pre = 15;
while( pre<256)
{
tmp=0;
if( MCLK/(2*freq0*pre) <=65535 & MCLK/(2*freq1*pre) <65535)
{
rTCFG1 = ( rTCFG1 | 0x00 ) & 0x0fffff00; //all interrupt,mux=1/2
mux = 2;
}
else if( MCLK/(4*freq0*pre) <=65535 & MCLK/(4*freq1*pre) <65535)
{
rTCFG1 = ( rTCFG1 | 0x11 ) & 0x0fffff11; //all interrupt,mux=1/4
mux = 4;
}
else if( MCLK/(8*freq0*pre) <=65535 & MCLK/(8*freq1*pre) <65535)
{
rTCFG1 = ( rTCFG1 | 0x22 ) & 0x0fffff22; //all interrupt,mux=1/8
mux = 8;
}
else if( MCLK/(16*freq0*pre) <=65535 & MCLK/(16*freq1*pre) <65535)
{
rTCFG1 = ( rTCFG1 | 0x33 ) & 0x0fffff33; //all interrupt,mux=1/16
mux = 16;
}
else if( MCLK/(32*freq0*pre) <=65535 & MCLK/(32*freq1*pre) <65535)
{
rTCFG1 = ( rTCFG1 | 0x44 ) & 0x0fffff44; //all interrupt,mux=1/32
mux = 32;
}
else
{
pre = pre+16;
tmp=1;
}
if (tmp==0)
break;
}
rTCFG0 = ( rTCFG0 | pre ) & (0xffffff00 |pre); //dead zone=0
rTCNTB0 = MCLK/(freq0*pre*mux);
rTCNTB1 = MCLK/(freq1*pre*mux);
if (start0 == 0)
{
rTCON = rTCON & 0xfffffffe; //stop timer0
}
else
{
rTCON = ( rTCON | 0x02 ) & 0xfffffff2;
rTCON = ( rTCON | 0x09 ) & 0xfffffff9;
}
if (start1 == 0)
{
rTCON = rTCON & 0xfffffffd; //stop timer1
}
else
{
rTCON = ( rTCON | 0x0200 ) & 0xfffff2ff;
rTCON = ( rTCON | 0x0900 ) & 0xfffff9ff;
}
}
}
/************************************************
* Timer 0 & 1 interrupt code end*
************************************************/
/************************************************
* Timer 2 & 3 interrupt *
************************************************/
Timer 2 & 3与1 & 2类似,在此暂删掉
Timer 4 & 5其实与其他的也类似,当寄存器稍不一样,保留
/************************************************
* Timer 4 & 5 interrupt code end*
************************************************/
/************************************************
* Timer 0 ~ 5 interrupt service routine *
************************************************/
void __irq Timer0Done(void)
{
rI_ISPC=BIT_TIMER0;
Uart_Printf("
Timer 0 has interruptted");
}
void __irq Timer1Done(void)
{
rI_ISPC=BIT_TIMER1;
Uart_Printf("
Timer 1 has interruptted");
}
void __irq Timer2Done(void)
{
rI_ISPC=BIT_TIMER2;
Uart_Printf("
Timer 2 has interruptted");
}
void __irq Timer3Done(void)
{
rI_ISPC=BIT_TIMER3;
Uart_Printf("
Timer 3 has interruptted");
}
void __irq Timer4Done(void)
{
rI_ISPC=BIT_TIMER4;
Uart_Printf("
Timer 4 has interruptted");
}
void __irq Timer5Done(void)
{
rI_ISPC=BIT_TIMER5;
Uart_Printf("
Timer 5 has interruptted");
}
/************************************************
* Timer 0 ~ 5 interrupt service routine end *
************************************************/
void Main()
{
rSYSCFG=CACHECFG; // Using 8KB Cache//
Port_Init();
Uart_Init(0,57600);
Delay(10);
Uart_Select(0); //Select UART0
Led_Display(0x01);
Timer01Start(1,1,1,1);
Timer23Start(1,1,1,0);
/* 由于程序中先计算频率配置寄存器,后决定是否开启寄存器,即使不用的定时器,也需要配置其频率; */
Timer45Start(1,1,1,1);
while(1)
{
//KICK_DOG;
}
}
关键词:
分享
S3C44b0x
芯片
定时
中断
程序
寄