最新S3C2410系统时钟和定时器.docx

上传人:b****6 文档编号:7148670 上传时间:2023-01-21 格式:DOCX 页数:14 大小:21.17KB
下载 相关 举报
最新S3C2410系统时钟和定时器.docx_第1页
第1页 / 共14页
最新S3C2410系统时钟和定时器.docx_第2页
第2页 / 共14页
最新S3C2410系统时钟和定时器.docx_第3页
第3页 / 共14页
最新S3C2410系统时钟和定时器.docx_第4页
第4页 / 共14页
最新S3C2410系统时钟和定时器.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

最新S3C2410系统时钟和定时器.docx

《最新S3C2410系统时钟和定时器.docx》由会员分享,可在线阅读,更多相关《最新S3C2410系统时钟和定时器.docx(14页珍藏版)》请在冰豆网上搜索。

最新S3C2410系统时钟和定时器.docx

最新S3C2410系统时钟和定时器

 

S3C2410系统时钟和定时器

S3C2410系统时钟和定时器

S3C2410系统时钟和定时器(2011-05-2608:

59)

主机环境:

UBUNTU10.04LTS+arm-linux-gcc2.95.3开发板环境:

EdukitIII实验箱+s3c2410子板问题描述:

首先初始化S3C2410系统时钟,然后通过定时器中断来控制LED的点亮、熄灭情况【1.系统时钟硬件原理】EdukitIII实验箱上一共有两个时钟,都是通过外接晶振实现,一个是实时时钟RTC,主要为系统计时使用,其晶振X101频率为32.768kHz;另一个是系统时钟,为硬件设备提供时钟信号使用,其晶振X102为12MHz,系统时钟都是在X102的基础上通过时钟寄存器的控制来生成不同的时钟信号,为不同的硬件设备提供工作时钟信号。

S3C2410的时钟控制逻辑可以外接晶振,然后通过内部的电路产生时钟源,也可以直接使用外部提供的时钟源,通过引脚设置来选择。

时钟逻辑为整个系统提供3种时钟:

FCLK用于CPU核;HCLK用于AHB总线上的设备,如存储控制器、中断控制器、LCD控制器、DMA、USB主机模块等;PCLK用于APB总线上的设备,如WATCHDOG、IIS、I2C、PWM定时器、MMC接口、ADC、UART、GPIO、RTC、SPI等。

开发板上的外接时钟(晶振X102为12MHz)通过相位锁相环(PLL)电路来提高频率,S3C2410有两个PLL,一个MPLL,用于设置FCLK、HCLK、PCLK;另一个为UPLL,用于USB设备。

上电时,PLL没有启动,FCLK等于外部输入时钟Fin,若要提高系统频率,通过软件来启用PLL(设置相关寄存器),图1为PLL上电后的启动过程

图1上电后MPLL的启动过程图中的OSC即是外接晶振X102,频率为12MHz,上电后需要等待一段时间(LockTime),MPLL才能输出稳定,LockTime的值由寄存器LOCITIME设置。

LockTime之前,FCLK=Fin,LockTime之后,MPLL输出正常,CPU工作在新的FCLK之下。

启动S3C2410的MPLL,要设置3个相关寄存器:

1.LOCITIME寄存器,用于设置LockTime的长度,地址和各位含义如图2所示图2LOCKTIME地址和各位含义LOCKTIME[0:

11]用于设置MPLL的LockTime,LOCKTIME[12:

23]用于设置UPLL的LockTime,使用默认值0x00FFFFFF即可。

2.MPLLCON寄存器(MainPLLControl):

用于设置FCLK与Fin的倍数,地址和各位含义如图3所示图3MPLLCON地址和各位含义MPLLCON[0:

1]称为SDIV,MPLLCON[4:

9]称为PDIV,MPLLCON[12:

19]称为MDIV,FCLK的计算公式如下:

S3C2410:

MPLL(FCLK)=(m*Fin)/(p*2^s)S3C2410:

MPLL(FCLK)=(2*m*Fin)/(p*2^s)其中:

m=MDIV+8,p=PDIV+2,s=SDIV对于本开发板,Fin=12MHz(晶振X102的频率)本例要产生的FCLK为200MHz,因此MDIV=0x5C=92;PDIV=0x04=4;SDIV=0x00=0,所以m=100,p=6,s=0,把Fin=12MHz代入S3C2410的MPLL(FCLK)计算公式,可以得到FCLK=200MHz,因此该寄存器的值可以设置为((0x5c12)|(0x044)|(0x00))。

图4是一些常用的PLL值,设置MPLLCON寄存器时可以参考该表。

图4:

MPLLCON常用设置值3.CLKDIVN寄存器,用于设置FCLK、HCLK、PCLK的比例,地址和各位含义如图5所示

图5CLKDIVN地址和各位含义

HDIVN1=CLKDIVN[2]=0,表示保留,HDIVN1=CLKDIVN[2]=1,表示FCLK:

HCLK:

PCLK=1:

4:

4,此时HDIVN和PDIVN均要设置为0。

HDIVN=CLKDIVN[1]=0,表示HCLK=FCLK,HDIVN=CLKDIVN[1]=1,表示HCLK=FCLK/2;PDIVV=CLKDIVN[0]=0,表示PCLK=HCLK,PDIVV=CLKDIVN[0]=1,表示PCLK=FCLK/2。

对于本例程,要求FCLK:

HCLK:

PCLK=1:

2:

4,所以CLKDIVN[0:

2]=0b110=0x3。

如果HDIVN=1,那么CPU要从fastbusmode转换为asynchronousbusmode,可以通过如下指令完成:

mrcp15,0,r1,c1,c0,0\n/*读出控制寄存器*/

orrr1,r1,0xc0000000\n/*设置为"asynchronousbusmode"*/

mcrp15,0,r1,c1,c0,0\n/*写入控制寄存器*/

【2.PWM定时器硬件原理】

S3C2410共有5个16位的定时器,其中定时器0、1、2、3具有脉宽调制PWM(PulseWidthModulation)功能,它们都有一个输出引脚TOUTi,可以通过定时器来控制输出引脚周期性的高、低电平变化,定时器4没有输出引脚,定时器结构如图6所示

图6PWM定时器结构图

PWM定时器使用的时钟是PCLK,先通过两个8位的预分频器(使用TCFG0寄存器来设置)降低频率,定时器0、1公用一个预分频器,定时器2、3、4公用第二个预分频器。

预分频器的输出进入到第二级分频器,可以产生2分频、4分频、8分频、16分频或者外部时钟TCLK0/TCLK1,每个定时器的工作频率可以从这5种频率中选择(使用TCFG1寄存器来设置)。

PWM定时器工作流程如下:

参考图7

图7PWM定时器操作流程

(1).定时器有TCMPBn、TCNTBn寄存器,用于设置定时器n的初始比较值和初始计数值

(2).然后设置TCONn寄存器启动定时器n,TCMPBn、TCNTBn寄存器的值分别装入TCMPn、TCNTn寄存器,TCMPn、TCNTn是定时器内部寄存器,在定时器n的工作频率下,TCNTn开始减1计数,其值可以通过读取TCNTOn得到

(3).当TCNTn的值等于TCMPn的值时,定时器n的输出TOUTn电平反转,TCNTn继续减数

(4).当TCNTn的值到达0时,输出引脚TOUTn电平再次反转(这样就实现了PWM),并触发定时器n的定时中断(如果定时中断使能)

(5).TCNTn到达0时,如果在TCON寄存器中将定时器n设为"自动加载",则TCMPBn和TCNTBn自动重新装入TCMPn和TCNTn寄存器,下一个计数流程开始,

PWM定时器常用寄存器,以定时器0为例

1.TCFG0寄存器(TIMERCONFIGURATION),用于控制预分频器,其地址和各位含义如图8所示

图8TCFG0寄存器地址和各位含义

定时器的输入频率计算公式为:

定时器工作频率=PCLK/(prescalervalue+1)/(dividervalue),其中prescalervalue的值(预分频器)通过TCFG0寄存器设置,TCFG0[0:

7]设置定时器0和定时器1的prescalervalue值,TCFG0[8:

15]设置定时器2、3、4的prescalervalue的值,该值的范围为0~255,本例程选择定时器0的该值为99,因此该寄存器的值设置为99。

dividervalue的值(第二级分频器)为2、4、8、16,由TCFG1寄存器设置

2.TCFG1寄存器(TIMERCONFIGURATION),经预分频器得到的时钟被输入到第二级分频器,可以再次被2分频、4分频、8分频和16分频,由图6可知,定时器0、1还可以工作在外接时钟TCLK0下,定时器2、3、4还可以工作在外接时钟TCLK1下,使用TCFG1寄存器来设置这5个定时器的第二级分频器的分频数,其地址和各位含义如图9所示

图9TCFG1寄存器地址和各位含义

TCFG1[20:

23]用于设置5个定时器的DMA模式,TCFG1[0:

3]设置定时器0的分频数。

本例程中不使用定时器的DMA模式,定时器0的第二级分频选择1/16,所以该寄存器的值为0x3。

3.TCON寄存器(TIMERCONTROL),其地址和各位含义如图10所示

图10TCON地址和各位含义

TCON[0]设置定时器0的开启和停止;TCON[1]设置定时器0"手动更新",将TCMPB0/TCNTB0的值装入内部寄存器TCMP0/TCNT0中;TCON[2]设置TOUT0是否反转;TCON[3]设置自动加载。

对于本例程,使用定时器0,开启定时器、手动更新、反转、自动加载。

4.TCNTB0/TCMPB0/TOUT0寄存器,TCNTB0用于保存定时器初始计数值,TCMPB0用于保存比较值,TOUT0用来观察TCNT0的数值;其地址和各位含义如图11所示

图11TCNTB0/TCMPB0/TOUT0寄存器地址和各位含义

对与本例程,TCMPB0=0,TCNTB0=15625。

【3.程序实现】

该例程一共包含8个文件,描述如下:

文件名

描述

Head.sARM启动代码,设置异常向量,只实现了复位异常和普通中断异常;调用存储器设置函数、调用关闭看门狗定时器函数、调用时钟初始化函数、调用定时器初始化函数、调用LED初始化函数、调用中断初始化函数,调用把代码从StepStone拷贝到SDRAM的拷贝函数,最后调用C语言的Main函数。

init.c

初始化函数的实现,包括关闭看门狗函数的实现、时钟初始化函数的实现、存储器初始化函数的实现、把代码从StepStone拷贝到SDRAM函数的实现、LED初始化函数的实现、定时器初始化函数的实现、中断初始化函数的实现

interrupt.c

定时器中断的中断服务程序的实现,中断服务程序的功能是每次中断改变4个LED灯的状态

interrupt.h

定时器中断的中断服务程序的头文件

s3c24xx.hs3c2410A的头文件,主要是相关寄存器地址的定义。

main.c

主函数

MakefileMakefile文件

timer.lds

链接脚本文件

@*@Name:

head.S@Desc:

初始化,设置中断模式、系统模式的栈,设置好中断处理函数@Parameter:

@Return:

@Author:

yoyoba(stuyou@)@Date:

2011-5-26@Modify:

2011-5-26@*

.externmain.text.global_start_start:

@*@中断向量,本程序中,除Reset和HandleIRQ外,其它异常都没有使用@*bReset

@0x04:

未定义指令中止模式的向量地址HandleUndef:

bHandleUndef

@0x08:

管理模式的向量地址,通过SWI指令进入此模式HandleSWI:

bHandleSWI

@0x0c:

指令预取终止导致的异常的向量地址HandlePrefetchAbort:

bHandlePrefetchAbort

@0x10:

数据访问终止导致的异常的向量地址HandleDataAbort:

bHandleDataAbort

@0x14:

保留HandleNotUsed:

bHandleNotUsed

@0x18:

中断模式的向量地址bHandleIRQ

@0x1c:

快中断模式的向量地址HandleFIQ:

bHandleFIQReset:

ldrsp,=4096@设置栈指针,以下都是C函数,调用前需要设好栈bldisable_watch_dog@关闭WATCHDOG,否则CPU会不断重启blclock_init@设置MPLL,改变FCLK、HCLK、PCLKblmemsetup@设置存储控制器以使用SDRAMblcopy_steppingstone_to_sdram@复制代码到SDRAM中ldrpc,=on_sdram@跳到SDRAM中继续执行on_sdram:

msrcpsr_c,#0xd2@进入中断模式ldrsp,=4096@设置中断模式栈指针

msrcpsr_c,#0xdf@进入系统模式ldrsp,=0x34000000@设置系统模式栈指针,

blinit_led@初始化LED的GPIO管脚bltimer0_init@初始化定时器0blinit_irq@调用中断初始化函数,在init.c中msrcpsr_c,#0x5f@设置I-bit=0,开IRQ中断

ldrlr,=halt_loop@设置返回地址ldrpc,=Main@调用Main主函数halt_loop:

bhalt_loopHandleIRQ:

sublr,lr,#4@计算返回地址stmdbsp!

{r0-r12,lr}@保存使用到的寄存器@注意,此时的sp是中断模式的sp@初始值是上面设置的4096ldrlr,=int_return@设置调用ISR即EINT_Handle函数后的返回地址ldrpc,=Timer0_Handle@调用中断服务函数,在interrupt.c中int_return:

ldmiasp!

{r0-r12,pc}^@中断返回,^表示将spsr的值复制到cpsr

/*

*Nameinit.c

*DescARM处理器硬件初始化函数实现

*Parameter

*Return

*Authoryoyobastuyou@

*Date2011-5-26

*Modify2011-5-26

*/

#include"s3c24xx.h"

voiddisable_watch_dogvoid;

voidclock_initvoid;

voidmemsetupvoid;

voidcopy_steppingstone_to_sdramvoid;

voidinit_ledvoid;

voidtimer0_initvoid;

voidinit_irqvoid;

/*

*关闭WATCHDOG,否则CPU会不断重启

*/

voiddisable_watch_dogvoid

{

WTCON=0;//关闭WATCHDOG很简单,往这个寄存器写0即可

}

#defineS3C2410_MPLL_200MHZ0x5c120x0440x00

#defineS3C2440_MPLL_200MHZ0x5c120x0140x02

/*

*对于MPLLCON寄存器,1912为MDIV,94为PDIV,10为SDIV

*有如下计算公式:

*S3C2410MPLLFCLK=m*Fin/p*2^s

*S3C2410MPLLFCLK=2*m*Fin/p*2^s

*其中m=MDIV+8,p=PDIV+2,s=SDIV

*对于本开发板,Fin=12MHz

*设置CLKDIVN,令分频比为:

FCLKHCLKPCLK=124,

*FCLK=200MHz,HCLK=100MHz,PCLK=50MHz

*/

voidclock_initvoid

{

//LOCKTIME=0x00ffffff;//使用默认值即可

CLKDIVN=0x03;//FCLKHCLKPCLK=124,HDIVN=1,PDIVN=1

/*如果HDIVN非0,CPU的总线模式应该从"fastbusmode"变为"asynchronousbusmode"*/

__asm__

"mrcp15,0,r1,c1,c0,0\n"/*读出控制寄存器*/

"orrr1,r1,#0xc0000000\n"/*设置为"asynchronousbusmode"*/

"mcrp15,0,r1,c1,c0,0\n"/*写入控制寄存器*/

/*判断是S3C2410还是S3C2440GSTATUS1寄存器为通用状态寄存器,用来描述芯片ID标识,可以通过读取GSTATUS1寄存器

的值来确定处理器的类型

0x32410000=S3C24100x32410002=S3C2410A0x32440000=S3C24400x32440002=S3C2440aEdukitIII实验箱使用的是S3C2410A芯片*/

ifGSTATUS1==0x32410000GSTATUS1==0x32410002

{

MPLLCON=S3C2410_MPLL_200MHZ;/*现在,FCLK=200MHz,HCLK=100MHz,PCLK=50MHz*/

}

else

{

MPLLCON=S3C2440_MPLL_200MHZ;/*现在,FCLK=200MHz,HCLK=100MHz,PCLK=50MHz*/

}

}

/*

*设置存储控制器以使用SDRAM

*/

voidmemsetupvoid

{

volatileunsignedlong*p=volatileunsignedlong*MEM_CTL_BASE;

/*这个函数之所以这样赋值,而不是像前面的实验比如mmu实验那样将配置值

*写在数组中,是因为要生成"位置无关的代码",使得这个函数可以在被复制到

*SDRAM之前就可以在steppingstone中运行

*/

/*存储控制器13个寄存器的值*/

p0=0x22011110;//BWSCONp1=0x00000700;//BANKCON0p2=0x00000700;//BANKCON1p3=0x00000700;//BANKCON2p4=0x00000700;//BANKCON3p5=0x00000700;//BANKCON4p6=0x00000700;//BANKCON5p7=0x00018005;//BANKCON6p8=0x00018005;//BANKCON7

/*REFRESH,

*HCLK=12MHz0x008C07A3,

*HCLK=100MHz0x008C04F4

*/

p9=0x008C04F4;

p10=0x000000B1;//BANKSIZEp11=0x00000030;//MRSRB6p12=0x00000030;//MRSRB7

}

voidcopy_steppingstone_to_sdramvoid

{

unsignedint*pdwSrc=unsignedint*0;

unsignedint*pdwDest=unsignedint*0x30000000;

whilepdwSrcunsignedint*4096

{

*pdwDest=*pdwSrc;

pdwDest++;

pdwSrc++;

}

}

/*

*LED1-4对应GPF5、GPF6、GPF7、GPF8

*/

#defineGPF5_out15*2//LED1

#defineGPF6_out16*2//LED2

#defineGPF7_out17*2//LED3

#defineGPF8_out18*2//LED4voidinit_ledvoid

{

GPFCON=GPF5_outGPF6_outGPF7_outGPF8_out;

}

/*

*TimerinputclockFrequency=PCLK/{prescalervalue+1}/{dividervalue}

*{prescalervalue}=0~255

*{dividervalue}=2,4,8,16

*本实验的Timer0的时钟频率=100MHz/99+1/16=62500Hz

*设置Timer00.5秒钟触发一次中断:

*/

voidtimer0_initvoid

{

TCFG0=99;//预分频器0=99TCFG1=0x03;//选择16分频

TCNTB0=31250;//0.5秒钟触发一次中断

TCON=11;//手动更新

TCON=0x09;//自动加载,清"手动更新"位,启动定时器0

}

/*

*定时器0中断使能

*/

voidinit_irqvoid

{

//定时器0中断使能

INTMSK&=~110;

}

/*

*Nameinterrupt.c

*Desc定时器0的终端服务程序

*Parameter

*Return

*Authoryoyobastuyou@

*Date2011-5-26

*Modify2011-5-26

*/

#include"s3c24xx.h"

voidTimer0_Handlevoid

{

/*

*每次中断令4个LED改变状态

*/

ifINTOFFSET==10

{

GPFDAT=~GPFDAT&0xf5;

}

//清中断

SRCPND=1INTOFFSET;

INTPND=INTPND;

}

/*

*Nameinterrupt.h

*Desc中断处理函数头文件

*Parameter

*Return

*Authoryoyobastuyou@

*Date2011-5-26

*Modify2011-5-26

*/

voidEINT_Handle;

/*

*NameMain.c

*Desc主函数

*Parameter

*Return

*Authoryoyobastuyou@

*Date2011-5-26

*Modify2011-5-26

*/

intMainvoid

{

while1;

return0;

}

/*

*Name:

Makefile

*Desc:

该例程的Makefile文件,使用了timer.lds链接脚本

*Parameter:

*Return:

*Author:

yoyoba(stuyou@)

*Date:

2011-5-26

*Modify:

2011-5-26

*/

objs:

=head.oinit.ointerrupt.omain.otimer.bin:

$(objs)

arm-linux-ld-Ttimer.lds-otimer_elf$^

arm-linux-objcopy-Obinary-Stimer_elf$@

arm-linux-objdump-D-marmtimer_elftimer.dis

%.o:

%.carm-linux-gcc-Wall-O2-c-o$@$

%.o:

%.Sarm-linux-gcc-Wall-O2-c-o$@$

clean:

rm-ftimer.bintimer_elftimer.dis*.o

/*

*Names3c24xx.h

*Desc本例程使用到的s3c2410外围寄存器地址定义

*Parameter

*Return

*Authoryoyobastuyou@

*Date2011-5-26

*Modify2011-5-26

*/

/*WOTCHDOGregister*/

#defineWTCON*volatileunsignedlong*0x53000000

/*SDRAMregisers*/

#defineMEM_CTL_BASE0x48000000

#defineSDRAM_BASE0x30000000

/*GPIOr

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 交通运输

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1