您的位置 首页 应用

s3c2440定时器中止的使用

在前面的几篇文章中,每当程序需要延时时,我们是利用循环语句来实现。这种方法的延时简单,但不是很精确,就是说不能得到确切的一段时间的…

在前面的几篇文章中,每逢程序需求延不时,咱们是运用循环查办来完结。这种办法的延时简略,但不是很准确,就是说不能得到切当的一段时刻的延时。因而当需求准确延不时,就不能选用这种办法了。一般是运用守时器来完结。在这儿,咱们就介绍一下s3c2440守时器的运用办法。

在解说之前,先介绍一下s3c2440时钟体系。一般来说,MCU的主时钟源首要是外部晶振或外部时钟,而用的最多的是外部晶振。在正确情况下,体系内所运用的时钟都是外部时钟源经过必定的处理得到的。咱们外部时钟源的频率一般不能分量体系所需求的高频条件,所以往往需求PLL(锁相环)进行倍频处理。在s3c2440中,有2个不同的PLL,一个是MPLL,另一个是UPLL。UPLL是给USB供给48MHz。在这儿,咱们首要介绍MPLL。外部时钟源经过MPLL处理后可以得到三个不同的体系时钟:FCLK、HCLK和PCLK。FCLK是主频时钟,用于ARM920T内核;HCLK用于AHB总线设备,如ARM920T,内存操控,中止操控,LCD操控,DMA以及USB主模块;PCLK用于APB总线设备,如外围设备的看门狗,IIS,I2C,PWM,MMC接口,ADC,UART,GPIO,RTC以及SPI。这三个体系时钟(FCLK、HCLK和PCLK)是有必定的比例联系,这种联系是经过寄存器CLKDIVN中的HDIVN位和PDIVN位来操控的,因而咱们只需知道了FCLK,再经过这两位的操控,就能确认HCLK和PCLK。而FCLK是怎么得到的呢?它是经过输入时钟(即外部时钟源)的频率,经过一个计算公式(详细公式请查阅数据手册)得到的,这个计算公式还需求三个参数(MDIV、PDIV、SDIV),而这三个参数是经过寄存器MPLLCON装备得到的。最终,咱们用最明晰的线路来制作一下时钟的发生进程:外部时钟源→经过寄存器MPLLCON得到FCLK→再经过寄存器CLKDIVN得到HCLK和PCLK。这个装备进程在发动文件中就已完结。在本开发板上,外部晶振为12MHz,进过MPLL倍频今后得到400MHz的FCLK,而FCLK、HCLK、PCLK之间的比例联系为1:4:8,因而HCLK为100MHz,PCLK为50MHz。

s3c2440的时钟体系就介绍到这儿,咱们再回到守时器的装备上来。怎么才干得到准确的守时呢?那就要靠TCFG0和TCFG1这两个寄存器来装备守时器的频率,即要确认TCNTOn每递减一个数所需求的时刻,它们之间是倒数的联系。详细的计算公式为:
守时器输出时钟频率=PCLK÷(prescaler+1)÷divider
其间prescaler值由TCFG0决议,divider值由TCFG1决议,而prescaler只能取0~255之间的整数,divider只能取2、4、8和16。比方已知PCLK为50MHz,而咱们想得到某必守时器的输出时钟频率为25kHz,则根据公式可以使prescaler等于249,divider等于8。有了这个输出时钟频率,理论上咱们经过设置寄存器TCNTBn就可以得到恣意与0.04毫秒(1÷25000×1000)成整数倍联系的时刻间隔了。例如咱们想要得到1秒钟的延时,则使TCNTBn为25000(1000÷0.04)即可。

下面咱们经过一段程序来演示运用守时器得到准确延时。这儿咱们用到的是守时器4。这段程序的作用是让蜂鸣器每隔2秒钟响一次,持续时刻为0.5秒,蜂鸣器响的一起伴随着LED亮。

#define _ISR_STARTADDRESS 0x33ffff00

#define U32 unsigned int

#define pISR_TIMER4(*(unsigned *)(_ISR_STARTADDRESS+0x58))

#define rSRCPND(*(volatile unsigned *)0x4a000000)//Interrupt request status
#define rINTMSK(*(volatile unsigned *)0x4a000008)//Interrupt mask control
#define rINTPND(*(volatile unsigned *)0x4a000010)//Interrupt request status

#define rGPBCON(*(volatile unsigned *)0x56000010)//Port B control
#define rGPBDAT(*(volatile unsigned *)0x56000014)//Port B data
#define rGPBUP(*(volatile unsigned *)0x56000018)//Pull-up control B

#define rTCFG0(*(volatile unsigned *)0x51000000)//Timer 0 configuration
#define rTCFG1(*(volatile unsigned *)0x51000004)//Timer 1 configuration
#define rTCON(*(volatile unsigned *)0x51000008)//Timer control
#define rTCNTB4 (*(volatile unsigned *)0x5100003c)//Timer count buffer 4

void __irq Timer4_ISR(void)
{
static int count;
count ++;
rSRCPND = rSRCPND | (0x1<<14);
rINTPND = rINTPND | (0x1<<14);
//每隔2秒蜂鸣器响一次,持续时刻为0.5秒,并伴随着LED亮
if (count % 4 ==0)
rGPBDAT = ~0x1e0;//蜂鸣器响,LED亮
else if (count % 4 ==1)
rGPBDAT = 0x1e0;//蜂鸣器不响,LED灭
}

void Main(void)
{
rGPBCON = 0x155555;//B0输出,给蜂鸣器;B5~B8输出,给LED
rGPBUP= 0x7ff;

rGPBDAT = 0x1e0;//蜂鸣器不响,LED灭

rSRCPND = rSRCPND | (0x1<<14);
rINTPND = rINTPND | (0x1<<14);
rINTMSK = ~(0x1<<14);//翻开守时器4中止 rTCFG0 &= 0xFF00FF;
rTCFG0 |= 0xf900;// prescaler等于249
rTCFG1 &= ~0xF0000;
rTCFG1 |= 0x20000;//divider等于8,则设置守时器4的时钟频率为25kHz
rTCNTB4 = 12500;//让守时器4每隔0.5秒中止一次

rTCON &= ~0xF00000;
rTCON |= 0x700000;
rTCON &= ~0x200000 ;//守时器4开端作业

pISR_TIMER4 = (U32)Timer4_ISR;

while(1)
{
;
}
}

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

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

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

微信扫一扫关注我们

返回顶部