S3C2410系统时钟和定时器.doc_第1页
S3C2410系统时钟和定时器.doc_第2页
S3C2410系统时钟和定时器.doc_第3页
S3C2410系统时钟和定时器.doc_第4页
S3C2410系统时钟和定时器.doc_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

S3C2410系统时钟和定时器S3C2410系统时钟和定时器(2011-05-26 08:59)主机环境:UBUNTU10.04LTS+arm-linux-gcc 2.95.3开发板环境:EdukitIII实验箱+s3c2410子板问题描述:首先初始化S3C2410系统时钟,然后通过定时器中断来控制LED的点亮、熄灭情况【1.系统时钟硬件原理】EdukitIII实验箱上一共有两个时钟,都是通过外接晶振实现,一个是实时时钟RTC,主要为系统计时使用,其晶振X101频率为32.768 kHz;另一个是系统时钟,为硬件设备提供时钟信号使用,其晶振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,上电后需要等待一段时间(Lock Time),MPLL才能输出稳定,Lock Time的值由寄存器LOCITIME设置。Lock Time之前,FCLK=Fin,Lock Time之后,MPLL输出正常,CPU工作在新的FCLK之下。启动S3C2410的MPLL,要设置3个相关寄存器:1.LOCITIME寄存器,用于设置Lock Time的长度,地址和各位含义如图2所示图2 LOCKTIME地址和各位含义LOCKTIME0:11用于设置MPLL的Lock Time,LOCKTIME12:23用于设置UPLL的Lock Time,使用默认值0x00FFFFFF即可。2.MPLLCON寄存器(Main PLL Control):用于设置FCLK与Fin的倍数,地址和各位含义如图3所示图3 MPLLCON地址和各位含义MPLLCON0:1称为SDIV,MPLLCON4:9称为PDIV,MPLLCON12:19称为MDIV,FCLK的计算公式如下:S3C2410:MPLL(FCLK)=(m*Fin)/(p*2s)S3C2410:MPLL(FCLK)=(2*m*Fin)/(p*2s)其中: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,因此该寄存器的值可以设置为(0x5c 12)|(0x04 4)|(0x00)。图4是一些常用的PLL值,设置MPLLCON寄存器时可以参考该表。图4:MPLLCON常用设置值3.CLKDIVN寄存器,用于设置FCLK、HCLK、PCLK的比例,地址和各位含义如图5所示图5 CLKDIVN地址和各位含义HDIVN1=CLKDIVN2=0,表示保留,HDIVN1=CLKDIVN2=1,表示FCLK:HCLK:PCLK=1:4:4,此时HDIVN和PDIVN均要设置为0。HDIVN=CLKDIVN1=0,表示HCLK=FCLK,HDIVN=CLKDIVN1=1,表示HCLK=FCLK/2;PDIVV=CLKDIVN0=0,表示PCLK=HCLK,PDIVV=CLKDIVN0=1,表示PCLK=FCLK/2。对于本例程,要求FCLK:HCLK:PCLK=1:2:4,所以CLKDIVN0:2=0b110=0x3。如果HDIVN=1,那么CPU要从fast bus mode转换为asynchronous bus mode,可以通过如下指令完成:mrc p15,0,r1,c1,c0,0n/*读出控制寄存器*/orr r1,r1,0xc 0000000n/*设置为asynchronous bus mode*/mcr p15,0,r1,c1,c0,0n/*写入控制寄存器*/【2.PWM定时器硬件原理】S3C2410共有5个16位的定时器,其中定时器0、1、2、3具有脉宽调制PWM(Pulse Width Modulation)功能,它们都有一个输出引脚TOUTi,可以通过定时器来控制输出引脚周期性的高、低电平变化,定时器4没有输出引脚,定时器结构如图6所示图6 PWM定时器结构图PWM定时器使用的时钟是PCLK,先通过两个8位的预分频器(使用TCFG0寄存器来设置)降低频率,定时器0、1公用一个预分频器,定时器2、3、4公用第二个预分频器。预分频器的输出进入到第二级分频器,可以产生2分频、4分频、8分频、16分频或者外部时钟TCLK0/TCLK1,每个定时器的工作频率可以从这5种频率中选择(使用TCFG1寄存器来设置)。PWM定时器工作流程如下:参考图7图7 PWM定时器操作流程(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寄存器(TIMER CONFIGURATION),用于控制预分频器,其地址和各位含义如图8所示图8 TCFG0寄存器地址和各位含义定时器的输入频率计算公式为:定时器工作频率=PCLK/(prescaler value+1)/(divider value),其中prescaler value的值(预分频器)通过TCFG0寄存器设置,TCFG00:7设置定时器0和定时器1的prescaler value值,TCFG08:15设置定时器2、3、4的prescaler value的值,该值的范围为0255,本例程选择定时器0的该值为99,因此该寄存器的值设置为99。divider value的值(第二级分频器)为2、4、8、16,由TCFG1寄存器设置2.TCFG1寄存器(TIMER CONFIGURATION),经预分频器得到的时钟被输入到第二级分频器,可以再次被2分频、4分频、8分频和16分频,由图6可知,定时器0、1还可以工作在外接时钟TCLK0下,定时器2、3、4还可以工作在外接时钟TCLK1下,使用TCFG1寄存器来设置这5个定时器的第二级分频器的分频数,其地址和各位含义如图9所示图9 TCFG1寄存器地址和各位含义TCFG120:23用于设置5个定时器的DMA模式,TCFG10:3设置定时器0的分频数。本例程中不使用定时器的DMA模式,定时器0的第二级分频选择1/16,所以该寄存器的值为0x3。3.TCON寄存器(TIMER CONTROL),其地址和各位含义如图10所示图10 TCON地址和各位含义TCON0设置定时器0的开启和停止;TCON1设置定时器0手动更新,将TCMPB0/TCNTB0的值装入内部寄存器TCMP0/TCNT0中;TCON2设置TOUT0是否反转;TCON3设置自动加载。对于本例程,使用定时器0,开启定时器、手动更新、反转、自动加载。4.TCNTB0/TCMPB0/TOUT0寄存器,TCNTB0用于保存定时器初始计数值,TCMPB0用于保存比较值,TOUT0用来观察TCNT0的数值;其地址和各位含义如图11所示图11 TCNTB0/TCMPB0/TOUT0寄存器地址和各位含义对与本例程,TCMPB0=0,TCNTB0=15625。【3.程序实现】该例程一共包含8个文件,描述如下:文件名描述Head.s ARM启动代码,设置异常向量,只实现了复位异常和普通中断异常;调用存储器设置函数、调用关闭看门狗定时器函数、调用时钟初始化函数、调用定时器初始化函数、调用LED初始化函数、调用中断初始化函数,调用把代码从Step Stone拷贝到SDRAM的拷贝函数,最后调用C语言的Main函数。init.c初始化函数的实现,包括关闭看门狗函数的实现、时钟初始化函数的实现、存储器初始化函数的实现、把代码从Step Stone拷贝到SDRAM函数的实现、LED初始化函数的实现、定时器初始化函数的实现、中断初始化函数的实现interrupt.c定时器中断的中断服务程序的实现,中断服务程序的功能是每次中断改变4个LED灯的状态interrupt.h定时器中断的中断服务程序的头文件s3c24xx.h s3c2410A的头文件,主要是相关寄存器地址的定义。main.c主函数Makefile Makefile文件timer.lds链接脚本文件*Name:head.SDesc:初始化,设置中断模式、系统模式的栈,设置好中断处理函数Parameter:Return:Author:yoyoba()Date:2011-5-26Modify:2011-5-26*.extern main.text.global _start_start:*中断向量,本程序中,除Reset和HandleIRQ外,其它异常都没有使用*b Reset0x04:未定义指令中止模式的向量地址HandleUndef:b HandleUndef0x08:管理模式的向量地址,通过SWI指令进入此模式HandleSWI:b HandleSWI0x0c:指令预取终止导致的异常的向量地址HandlePrefetchAbort:b HandlePrefetchAbort0x10:数据访问终止导致的异常的向量地址HandleDataAbort:b HandleDataAbort0x14:保留HandleNotUsed:b HandleNotUsed0x18:中断模式的向量地址b HandleIRQ0x1c:快中断模式的向量地址HandleFIQ:b HandleFIQ Reset:ldr sp,=4096设置栈指针,以下都是C函数,调用前需要设好栈bl disable_watch_dog关闭WATCHDOG,否则CPU会不断重启bl clock_init设置MPLL,改变FCLK、HCLK、PCLKbl memsetup设置存储控制器以使用SDRAMbl copy_steppingstone_to_sdram复制代码到SDRAM中ldr pc,=on_sdram跳到SDRAM中继续执行on_sdram:msr cpsr_c,#0xd2进入中断模式ldr sp,=4096设置中断模式栈指针msr cpsr_c,#0xdf进入系统模式ldr sp,=0x 34000000设置系统模式栈指针,bl init_led初始化LED的GPIO管脚bl timer0_init初始化定时器0bl init_i rq调用中断初始化函数,在init.c中msr cpsr_c,#0x5f设置I-bit=0,开IRQ中断ldr lr,=halt_loop设置返回地址ldr pc,=Main调用Main主函数halt_loop:b halt_loop HandleIRQ:sub lr,lr,#4计算返回地址stmdb sp!,r0-r12,lr保存使用到的寄存器注意,此时的sp是中断模式的sp初始值是上面设置的4096 ldr lr,=int_return设置调用ISR即EINT_Handle函数后的返回地址ldr pc,=Timer0_Handle调用中断服务函数,在interrupt.c中int_return:ldmia sp!,r0-r12,pc中断返回,表示将spsr的值复制到cpsr/*Name init.c*Desc ARM处理器硬件初始化函数实现*Parameter*Return*Author *Date 2011-5-26*Modify 2011-5-26*/#includes3c24xx.hvoid disable_watch_dogvoid;void clock_initvoid;void memsetupvoid;void copy_steppingstone_to_sdramvoid;void init_ledvoid;void timer0_initvoid;void init_irqvoid;/*关闭WATCHDOG,否则CPU会不断重启*/void disable_watch_dogvoidWTCON=0;/关闭WATCHDOG很简单,往这个寄存器写0即可#define S3C2410_MPLL_200MHZ 0x5c120x0440x00#define S3C2440_MPLL_200MHZ 0x5c120x0140x02/*对于MPLLCON寄存器,1912为MDIV,94为PDIV,10为SDIV*有如下计算公式:*S3C2410 MPLLFCLK=m*Fin/p*2s*S3C2410 MPLLFCLK=2*m*Fin/p*2s*其中m=MDIV+8,p=PDIV+2,s=SDIV*对于本开发板,Fin=12MHz*设置CLKDIVN,令分频比为:FCLKHCLKPCLK=124,*FCLK=200MHz,HCLK=100MHz,PCLK=50MHz*/void clock_initvoid/LOCKTIME=0x00ffffff;/使用默认值即可CLKDIVN=0x03;/FCLKHCLKPCLK=124,HDIVN=1,PDIVN=1/*如果HDIVN非0,CPU的总线模式应该从fast bus mode变为asynchronous bus mode*/_asm_mrc p15,0,r1,c1,c0,0n/*读出控制寄存器*/orr r1,r1,#0xc 0000000n/*设置为asynchronous bus mode*/mcr p15,0,r1,c1,c0,0n/*写入控制寄存器*/;/*判断是S3C2410还是S3C2440 GSTATUS1寄存器为通用状态寄存器,用来描述芯片ID标识,可以通过读取GSTATUS1寄存器的值来确定处理器的类型0x 32410000=S3C2410 0x 32410002=S3C2410A 0x 32440000=S3C2440 0x 32440002=S3C2440a EdukitIII实验箱使用的是S3C2410A芯片*/if GSTATUS1=0x 32410000 GSTATUS1=0x 32410002MPLLCON=S3C2410_MPLL_200MHZ;/*现在,FCLK=200MHz,HCLK=100MHz,PCLK=50MHz*/elseMPLLCON=S3C2440_MPLL_200MHZ;/*现在,FCLK=200MHz,HCLK=100MHz,PCLK=50MHz*/*设置存储控制器以使用SDRAM*/void memsetupvoidvolatile unsigned long*p=volatile unsigned long*MEM_CTL_BASE;/*这个函数之所以这样赋值,而不是像前面的实验比如mmu实验那样将配置值*写在数组中,是因为要生成位置无关的代码,使得这个函数可以在被复制到*SDRAM之前就可以在steppingstone中运行*/*存储控制器13个寄存器的值*/p0=0x 22011110;/BWSCON p1=0x 00000700;/BANKCON0 p2=0x 00000700;/BANKCON1 p3=0x 00000700;/BANKCON2 p4=0x 00000700;/BANKCON3 p5=0x 00000700;/BANKCON4 p6=0x 00000700;/BANKCON5 p7=0x 00018005;/BANKCON6 p8=0x 00018005;/BANKCON7/*REFRESH,*HCLK=12MHz 0x008C07A3,*HCLK=100MHz 0x008C04F4*/p9=0x008C04F4;p10=0x 000000B1;/BANKSIZE p11=0x 00000030;/MRSRB6 p12=0x 00000030;/MRSRB7void copy_steppingstone_to_sdramvoidunsigned int*pdwSrc=unsigned int*0;unsigned int*pdwDest=unsigned int*0x 30000000;while pdwSrc unsigned int*4096*pdwDest=*pdwSrc;pdwDest+;pdwSrc+;/*LED1-4对应GPF5、GPF6、GPF7、GPF8*/#define GPF5_out 15*2/LED1#define GPF6_out 16*2/LED2#define GPF7_out 17*2/LED3#define GPF8_out 18*2/LED4 void init_ledvoidGPFCON=GPF5_out GPF6_out GPF7_out GPF8_out;/*Timer input clock Frequency=PCLK/prescaler value+1/divider value*prescaler value=0255*divider value=2,4,8,16*本实验的Timer0的时钟频率=100MHz/99+1/16=62500Hz*设置Timer0 0.5秒钟触发一次中断:*/void timer0_initvoidTCFG0=99;/预分频器0=99 TCFG1=0x03;/选择16分频TCNTB0=31250;/0.5秒钟触发一次中断TCON=11;/手动更新TCON=0x09;/自动加载,清手动更新位,启动定时器0/*定时器0中断使能*/void init_irqvoid/定时器0中断使能INTMSK&=110;/*Name interrupt.c*Desc定时器0的终端服务程序*Parameter*Return*Author *Date 2011-5-26*Modify 2011-5-26*/#includes3c24xx.hvoid Timer0_Handlevoid/*每次中断令4个LED改变状态*/ifINTOFFSET=10GPFDAT=GPFDAT&0xf 5;/清中断SRCPND=1 INTOFFSET;INTPND=INTPND;/*Name interrupt.h*Desc中断处理函数头文件*Parameter*Return*Author *Date 2011-5-26*Modify 2011-5-26*/void EINT_Handle;/*Name Main.c*Desc主函数*Parameter*Return*Author *Date 2011-5-26*Modify 2011-5-26*/int Mainvoidwhile1;return 0;/*Name:Makefile*Desc:该例程的Makefile文件,使用了timer.lds链接脚本*Parameter:*Return:*Author:yoyoba()*Date:2011-5-26*Modify:2011-5-26*/objs:=head.o init.o interrupt.o main.o timer.bin:$(objs)arm-linux-ld-Ttimer.lds-o timer_elf$arm-linux-objcopy-O binary-S timer_elf$arm-linux-objdump-D-m arm timer_elf timer.dis%.o:%.c arm-linux-gcc-Wall-O2-c-o$%.o:%.S arm-linux-gcc-Wall-O2-c-o$clean:rm-f timer.bin timer_elf timer.dis*.o/*Name s3c24xx.h*Desc本例程使用到的s3c2410外围寄存器地址定义*Parameter*Return*Author *Date 2011-5-26*Modify 2011-5-26*/*WOTCH DOG register*/#define WTCON*volatile unsigned long*0x 53000000/*SDRAM regisers*/#define MEM_CTL_BASE 0x 48000000#define SDRAM_BASE 0x 30000000/*GPIO registers*/#define GPFCON*volatile unsigned long*0x 56000050#define GPFDAT*volatile unsigned long*0x 56000054#define GPFUP*volatile unsigned long*0x 56000058/*interrupt registes*/#define SRCPND*vola tile unsigned long*0x4A 000000#define INTMOD*volatile unsigned long*0x4A 000004#define INTMSK*volatile unsigned long*0x4A 000008#define PRIORITY*volatile unsigned long*0x4A00000c#define INTPND*volatile unsigned long*0x4A 000010#define INTOFFSET*volatile unsigned long*0x4A 000014#define SUBSRCPND*volatile unsigned long*0x4A 000018#define INTSUBMSK*volatile unsigned long*0x4A00001c/*external interrupt registers*/#define EINTMASK*volatile unsigned long*0x 560000a4#define EINTPEND*volatile unsigned long*0x 560000a8/*clock registers*/#define LOCKTIME*volatile unsigned long*0x4c 000000#define MPLLCON*volatile unsigned long*0x4c 000004#define UPLLCON*volatile unsigned long*0x4c 000008#define CLKCON*volatile unsigned long*0x4c00000c#define CLKSLOW*volatile unsigned long*0x4c 000010#define CLKD

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论