22850|29

6366

帖子

4929

TA的资源

版主

楼主
 

深入理解ARM体系架构(S3C6410)----全14篇 [复制链接]

 
本系列文章已整理成电子文档,完整版下载地址:https://download.eeworld.com.cn/detail/tiankai001/13374


本文由muge0913编写,转载请注明出处:http://blog.csdn.net/muge0913/article/details/7364706


作者张同浩,邮箱:muge0913@sina.com




此系列文章写了一些S3C6410的几个外设的编程实例,和S3C6410的架构简单分析。以后做驱动或在其他项目中牵扯到的地方,通过查看芯片资料就可完成相应的功能。在对ARM处理器有了简单的编程基础后,我们就可以做linux在arm上的移植了,发现所做的事情越来越有趣了。虽然代码已经测试通过,但感觉写不很规范,呵呵,文章有不妥的地方希望大家指出,谢谢。


本文章由张同浩编写,转载请注明出处:http://blog.csdn.net/muge0913/article/details/7471602

邮箱:muge0913@sina.com


1、深入理解ARM体系架构(S3C6410)---arm7,arm9,arm11区别


2、深入理解ARM体系架构(S3C6410)---认识S3C6410


3、深入理解ARM体系架构(S3C6410)---S3C6410存储映射


4、深入理解ARM体系架构(S3C6410)---S3C6410系统时钟


5、深入理解ARM体系架构(S3C6410)---S3C6410复位


6、深入理解ARM体系架构(S3C6410)---S3C6410看门狗源码实例


7、深入理解ARM体系架构(S3C6410)---PWM实例


8、深入理解ARM体系架构(S3C6410)---UART实例


9、深入理解ARM体系架构(S3C6410)---外部中断控制实例


10、深入理解ARM体系架构(S3C6410)---系统时钟初始化实例


11、深入理解ARM体系架构(S3C6410)---DRAM控制器初始化实例


12、深入理解ARM体系架构(S3C6410)---lcd 显示图片


13、深入理解ARM体系架构(S3C6410)---ad转化实例


14、深入理解ARM体系架构(S3C6410)---rtc实例



[ 本帖最后由 tiankai001 于 2013-4-22 21:23 编辑 ]

最新回复

谢谢分享骄傲。  详情 回复 发表于 2016-11-4 13:06
点赞 关注(2)

回复
举报

6366

帖子

4929

TA的资源

版主

沙发
 
深入理解ARM体系架构(S3C6410)---arm7,arm9,arm11区别

1. 时钟频率的提高
虽然内核架构相同,但ARM7处理器采用3级流水线的冯·诺伊曼结构;而ARM9采用5级流水线的哈佛结构,ARM11为8级流水线哈弗结构(从arm9开始都采用了哈弗结构)。增加的流水线设计提高了时钟频率和并行处理能力。5级流水线能够将每一个指令处理分配到5个时钟周期内,在每一个时钟周期内同时有5个指令在执行。在常用的芯片生产工艺 下,ARM7一般运行在100MHz左右,而ARM9则至少在200MHz以上.ARM11首先推出350M~500MHz时钟频率的内核, 目前上升到1GHz时钟频率。

2 指令周期的改进
指令周期的改进对于处理器性能的提高有很大的帮助。性能提高的幅度依赖于代码执行时指令的重叠,这实际上是程序本身的问题。对于采用最高级的语言,一般来说,性能的提高在30%左右。

3.MMU(内存管理单元)
ARM7一般没有MMU(内存管理单元),(ARM720T有MMU)。
ARM9一般是有MMU的,ARM9940T只有MPU,不是一个完整的MMU。

ARM11当然也有MMU的。
这一条很重要,MMU单元是大型操作系统必需的硬件支持,如LINUX;WINCE等。这就是说,ARM7一般只能运行小型的实时系统如UCOS-II,eCOS等,而ARM9无此限制,一般的操作系统都可以移植。其实即使ARM720T能支持LINUX;WINCE等系统,也鲜有人用,因为以ARM7的运行速度跑这种大型操作系统,实在有点吃力。再者两者的应用领域明显不同,也无此必要。

下面两个图:架构一幕了然。


4. 在从ARM7到ARM9,ARM11的平台转变过程中,有一件事情是非常值得庆幸的,即ARM9,ARM11能够地向后兼容ARM7上的软件;并且开发人员面对的编程模型和架构基础也保持一致。


下面图是一些特征比较:








 
 

回复

6366

帖子

4929

TA的资源

版主

板凳
 
深入理解ARM体系架构(S3C6410)---认识S3C6410

芯片架构如图


S3C64xx系列的应用处理器芯片是三星主推的16/32 RISC 微处理器,三星目前推出了S3C6400和S3C6410,都是基于ARM11架构的,而且硬件管脚兼容,应该说大致的功能基本相同,比较明显的区别就是S3C6410带有2D/3D硬件加速。


S3C6410说明文档下载地址:http://download.csdn.net/detail/muge0913/4144550


简单说明如下:

ARM Core:采用ARM1176JZF-S的核,包含16KB的指令数据Cache和16KB的指令数据TCM,ARM Core电压为1.1V的时候,可以运行到553MHz,在1.2V的情况下,可以运行到667MHz。通过AXI,AHB和APB组成的64/32bit内部总线和外部模块相连。

TFT LCD Controller:显示控制器,支持TFT 24Bit LCD屏,分辨率能支持到1024x1024。显示输出接口支持RGB接口,I80接口,BT.601输出(YUV422 8Bit)和输出给TV Encoder的接口。支持最多5个图形窗口并可进行Overlay操作,从window0到window4,分别支持不同的图像输入源和不同的图像格式。实际上,显示控制器可以接收来自Carema,Frame Buffer和其他模块的图像数据,可以对这些不同的图像进行Overlay,并输出到不同的接口,比如LCD,TV Encoder。

RTC:系统掉电的时候由备份电池支持,需外接32.768KHz时钟,年/月/日/时/分/秒都是BCD码格式。

PLL:支持三个PLL分别是APLL,MPLL和EPLL。APLL为ARM提供时钟,产生ARMCLK,MPLL为所有和AXI/AHB/APB相连的模块提供时钟,产生HCLK和PCLK,EPLL为特殊的外设提供时钟,产生SCLK。

TIMER/PWM:支持5个32Bit Timer,其中Timer0和Timer1具有PWM功能,而Timer2,3,4没有输出管脚,为内部Timer。

WATCHDOG:看门狗,也可以当作16Bit的内部定时器。

I2S:用于和外接的Audio Codec传输音频数据。支持普通的I2S双通道,也支持5.1通道I2S传输,音频数据可以是8/16/32Bit,采样率从8KHz到192KHz。

I2C:支持2个I2C控制器。

UART:支持4个UART口,支持DMA和Interrupt模式,UART0/1/2还支持IrDA1.0功能。UART最高速度达3Mbps。

GPIO:通用GPIO端口,功能复用。

IrDA:独立的IrDA控制器,兼容IrDA1.1,支持MIR和FIR模式。

SPI:支持全功能的SPI。

MODEM:Modem接口控制器,内置8KB SRAM用于S3C6410和外接Modem交换数据,该SRAM还可以为Modem提供Boot功能。

USB OTG:支持USB OTG 2.0,同时支持Slave和Host功能,最高速度480Mbps。

USB HOST:独立的USB Host控制器,支持USB Host 1.1。

MMC/SD:SD/MMC控制器,兼容SD Host 2.0,SD Memory Card 2.0,SDIO Card 1.0和High-Speed MMC。

PCM AUDIO:支持两个PCM Audio接口,传输单声道16Bit音频数据。

AC97:AC97控制器,支持独立的PCM立体声音频输入,单声道MIC输入和PCM立体声音频输出,通过AC-Link接口与Audio Codec相连。

Post Processor:图像处理模块,类似TV Scaler模块。输入图像最大为4096x4096,输出图像最大为2048x2048,支持RGB与YUV之间的转换。

JPEG Codec:支持JPEG编解码功能,最大尺寸为4096x4096。

2D GRAPHICS:2D加速,支持画点/线,Bitblt功能和Color Expansion。

3D GRAPHICS:3D加速。


参考文章:http://blog.csdn.net/nanjianhui/article/details/4163792

 
 
 

回复

6366

帖子

4929

TA的资源

版主

4
 
深入理解ARM体系架构(S3C6410)---S3C6410存储映射

参考文章:http://blog.csdn.net/eagle_lzt/article/details/6310094

参考文章:http://www.threeway.cc/sitecn/In ... x?pid=1637&tid=1380


S3C6410的物理内存分成Memory和Pheriperal两部分,地址范围分别为0x0~0x6fffffff和0x7fffffff~0xffffffff。系统通过 SPINE总线访问Memory空间,通过PERI总线访问Pheriperal空间。而为了适应不同外设的访问速度,又分别通过AHB总线访问LCD、 Camera、Accelerator等高速外设,通过APB总线访问iic、watchdog等低速外设。


Memory:


(1)启动镜像区物理地址为0x00000000~0x07ffffff,共128MB,是用来启动系统的。但是这个范围内并没有实际的存储介质与之对应,只能在通过OM[4:0]选择具体的启动介质后再把相应介质的物理地址映射到这个启动区,比如说选择了IROM 启动方式后,就把IROM所占的地址空间映射为0x00000000开始的空间。引导镜像区反映一个镜像,这个镜像指向内存的一部分区域或者静态存储区。引导镜像的开始地址是0x0000_0000。

(2)内部内存区物理地址为0x08000000~0x0fffffff,共128MB。这个区域对应着内部的内存地址,内部的ROM和SRAM都是分布在这个区间。其中,0x08000000~0x0bffffff对应着内部ROM,当然实际上内部的ROM也并没有64MB这么多,只有32KB是有实际存储介质的,这32KB是一个只读区,放的是IROM方式下的启动代码,选择IROM启动的时候首先运行的代码就是这一部分,称为BL0,这部分代码由厂家固化。0x0c000000~0x0fffffff对应内部SRAM,可读可写,当NAND 闪存启动被选择时能映射到引导镜像区。  。

(3)静态内存区物理地址为0x10000000~0x3fffffff,共6*128MB。这个区域用于访问挂在外部总线上的设备,比如说SRAM、NOR flash、oneNand等。这个区域被分割为6个bank,每个bank为128MB,数据宽度最大支持16bit,每个bank通过 Xm0CS[5:0]来划定。和S3C2410 不一样的是,bank2~bank5能映射到nand flash、CF等非线性存储器,这并不是说可以通过bank2~bank5的地址段就能直接访问nand flash、CF内部的地址,相反,当映射到这些器件的时候这些bank的地址也不能再使用了,访问这些非线性存储器还是得通过Pheriperal空间的AHB总线进行,和S3C2410中的访问方式是一样的。不过有一个特例是,当Xm0CS2被映射到nand flash的时候,Steppingstone的SRAM被映射到bank2开始的4KB,而在以nand flash方式启动的时候bank2被映射到0x00000000开始的地方,实际上就是把Steppingstone映射到0x0000000了,这和 S3C2410的情况还是相似的。

(4)动态内存区物理地址为0x40000000~0x6fffffff,共3*256MB。其中第一个256MB为保留区,实际使用的动态内存区为 0x50000000~0x6fffffff,又分为2个区间,分别占256MB,可以通过DMC的Xm1CS[1:0]来进行着2个区间的选择。这个内存区主要是扩展DRAM,最大可以扩展512MB的DRAM。

2.Pheriperal外设区域通过PERI 总线被访问,它的地址范围是0x7000_0000~0x7FFF_FFFF。这个地址范围的所有的SFR能被访问。而且如果数据需要从NFCON或CFCON 传输,这些数据需要通过PERI总线传输。


特殊设备地址空间:


AHB总线存储器映射





 
 
 

回复

6366

帖子

4929

TA的资源

版主

5
 
深入理解ARM体系架构(S3C6410)---S3C6410系统时钟

系统时钟控制逻辑,在S3C6410 中生成所需的系统时钟信号,用于CPU 的ARMCLK, 用于AXI/AHB 总线外设的HCLK 和APB 总线外设的PCLK。在S3C6410 中有三个PLL。一个仅用于ARMCLK,一个用于HCLK 和 PCLK,最后一个用于外设,特别用于音频相关的时钟。The third thingis for peripheral, especially for audio related clocks.通过外部提供的时钟源,时钟控制逻辑产生慢速时钟信号ARMCLK,HCLK 和 PCLK。该每个外设块的时钟信号可能被启用或禁用,由软件控制以减少电源消耗。

在电源控制逻辑中,S3C6410 有多种电源管理方案,以保持电力系统的最佳消耗。In the power control logic, S3C6410X has various power managementschemes to keep optimal power consumption for a given task. 在S3C6410中,电源管理由四个模块组成:通用时钟门控模式,空闲模式,停止模式和睡眠模式。

1、在S3C6410中,通用时钟门控模式用来控制内部外设时钟的开/关。可以通过用于外设所要求的特定应用提供时钟,使用通用时钟门控模式来优化S3C6410的电源消耗。例如:如果定时器没有要求,则可以中断时钟定时器,以降低功耗。General Clock Gating mode is used to control the ON/OFF of clocksfor internal peripherals in S3C6410X. You can optimize the power consumption ofS3C6410X using this General Clock Gating mode by supplying clocks for peripheralsthat are required for a certain application. For example, if a timer is notrequired, then you can disconnect the clock to the timer to reduce power.

2、闲置模式仅中断ARMCLK到CPU 内核,它提供时钟给所有外设。通过使用闲置模式,电力消耗通过CPU

内核而减少。

3、停止模式通过禁用PLL冻结所有时钟到CPU 以及外设。在S3C6410 中,电力消耗仅因为漏电流。

4、睡眠模式断开内部电源。因此,除了唤醒逻辑单元消耗的电量,CPU和内部逻辑消耗电量将为零。为了使用睡眠模式,两个独立的电源是必需的。其中一个电源为唤醒逻辑提供电力,另一个提供其他内部逻辑,包括CPU。SLEEP mode disconnects the internal power.Therefore, the power consumption due to CPU and the internal logic except thewakeup logic will be zero. In order to use the SLEEP mode two independent powersources are required. One of the two power sources supplies the power for thewake-up logic. The other one supplies the other internal logic including CPU,and must be controlled in order to be turned ON/OFF. In SLEEP mode, the secondpower supply source for the CPU and internal logic will be turned off.

3.1 系统控制器的特性

The System Controller includes the following features:

• Three PLLs: ARM PLL, main PLL, extra PLL (for the modules those usespecial frequency)

• Five power-saving mode: NORMAL, IDLE, STOP, DEEP-STOP, and SLEEP

• Six controllable power domain: domain-G, domain-V, domain-I,domain-P, domain-F, domain-S

• Control operating clocks of internal sub-blocks

• Control bus priority

3.2 功能描述

这部分主要介绍S3C6410 系统控制器的功能。包含时钟的体系结构,复位设计和电源管理模式。

1、 硬件结构

S3C6410是由ARM1176核、一些多媒体协处理器(co-processors)、多种外设IPs组成。ARM1176核是通过64位AXI总线与存储控制器相连的,这样做是为了满足带宽的需要。多媒体协处理(MFC多格式编码器、JPEG、camera接口、TV译码器、3D加速器等)器被分为五个电源域,这五个电源域可被单独控制以降低功耗。S3C6410X consists of ARM1176 processor, several media and graphicco-processors and various peripheral IPs. ARM1176 processor is connected toseveral memory controllers through 64-bit AXI-bus. This is done to meetbandwidth requirements. Media and graphic coprocessors, which include MFC(Multi-Format Codec), JPEG, Camera interface, TV encoder, 3D accelerator and etc,are divided into six power domains. The six power domain can be controlledindependently to reduce unwanted power consumption when the IPs is not requiredfor an application program.

2、时钟结构

时钟源在外部晶振和外部时钟二者之间进行选择。时钟发生器由三个PLL组成,最高可产生1.6GHz的信号。

3.时钟源的选择

The OM[4:0] pins determines theoperating mode of S3C6410X when the external reset signal is asserted. Asdescribed in the table, the OM[0] selects the external clock source, i.e., ifthe OM[0] is 0, the XXTIpll (external crystal) is selected.

Otherwise, XEXTCLK is selected.

The operating mode is mainlyclassified into six categories according to the boot device. The boot devicecan be among SROM, NOR, OneNAND, MODEM and Internal ROM. When NAND Flash deviceis used, XSELNAND pin must be 1, even if it is used as boot device or storagedevice. When OneNAND Flash device is used, XSELNAND must be 0, even if it isused as boot device or storage device. When NAND/OneNAND device is not used,

XSELNAND can be 0 or 1.

4、锁相环

Clock selection betweenPLLs and input reference clock

Figure 3-4illustrates the clock generation logic. S3C6410X has three PLLs which are APLLfor ARM operating clock, MPLL for main operating clock, and EPLL for specialpurpose. The operating clocks are divided into three groups. The first thing isARM clock, which is generated from APLL. MPLL generates the main system clocks,which are used for operating AXI, AHB, and APB bus operation. The last group isgenerated from EPLL. Mainly, the generated clocks are used for peripheral IPs,i.e., UART, IIS, IIC, and etc. The lowest three bits of CLK_SRC registercontrol the source clocks of three groups. When the bit has 0, then the inputclock is bypassed to the group. Otherwise, the PLL output will be applied tothe group.

1)ARM和AXI/AHB/APB时钟

ARM1176最大支持667MHZ,在不改变PLL的情况下,可以通过DIVarm来控制该频率。

S3C6410由AXI、AHB、APB总线组成。IPs可以连接相应总线来满足I/O带宽和操作性能。连接在AXI/AHB的总线上的设备,最高可以达到133MHz的速度。当连接在APB总线上时,最高可以达到66MHz的速度。总线速度很高程度上依赖于AHB和APB总线之间的同步数据传输。

ARM and AXI/AHB/APB bus clock generation

ARM1176 processor of S3C6410X runs up to maximum 667MHz. Theoperating frequency can be controlled by the internal clock divider, DIVARM,without changing PLL frequency. The divider ratio varies from 1 to 16. ARM processordecreases the operating speed to reduce power dissipation.S3C6410X consists ofAXI bus, AHB bus, and APB bus to optimize the performance requirements.Internal IPs are connected to appropriate bus systems to meet their I/Obandwidth and operating performance. When they are attached to AXI bus or AHBbus, the operating speed can be up to maximum 133MHz. While they are attachedto APB bus, the maximum operating speed can be up to 66MHz. Moreover, the busspeed between AHB and APB has high dependency to synchronize data transmission.Figure 3-5 illustrates the part of bus clock generation to meet therequirements of bus system clocks.

HCLKx2用于两个DDR控制器,DDR0、DDR1,最高可达到266MHZ,每个DDR控制器可以单独控制,以用来降低功耗。所有的AHB总线上的时钟是由DIVhclk分频得来的,同样,也可以单独控制来降低功耗。HCLK_GATE寄存器来配置HCLKx2和HCLK。

APB总线与AHB总线类似,但是注意:在AHB和APB总线之间的频率比必须隔着一个偶数值,例如:如果DIVhclk是1,那么DIVpclk必须是1、3…..,否则,则不能传输数据。

Low-speed interconnection IPs transfer data through APB bus system.APB clocks of them are running at up to 66MHz as described in the above sectionand generated from DIVPCLK clock divider. They are also masked using PCLK_GATEregister. As described, the frequency ratio between AHB clock and APB clockmust be an even integer value. For example, if DIVHCLK has 1 of CLK_DIV0[8],then DIVPCLK must be 1, 3, ... of CLK_DIV0[15:12].Otherwise, the IPs on APB bussystem cannot transfer data correctly.

在AHB总线上的JPEG和安全子系统不能运行在133MHz。AHB总线用DIVjpeg和DIVsecur为它们单独产生时钟信号,因此它们与APB之间的频率也要隔着一个偶数。

APLL单独用于ARM核,其值不作约束。


其他时钟,用的时候查看手册即可。

2)MFC时钟

3)camera I/F(接口)时钟

4)显示时钟(POST、LCD和scaler

5)音频时钟(IIS和PCM)

6)UART、SPI、MMC时钟

7)IrDA 和USBHOST时钟

8)时钟的开关控制

可以通过控制HCLK_GATE、PCLK_GATE、SCLK_GATE。

9)时钟的输出

有一个时钟输出端口,产生内部时钟,用于中断或调试。


 
 
 

回复

6366

帖子

4929

TA的资源

版主

6
 
深入理解ARM体系架构(S3C6410)---S3C6410复位

reset

S3C6410X has three types ofreset signals and SYSCON can place the system into one of three resets.

• Hardware reset: It isgenerated by asserting XnRESET. It is an uncompromised, ungated, total andcomplete reset that is used when you do not require information in system anymore. It fully initializes all system.

• Watchdog reset: It isgenerated by a special hardware block, i.e., watchdog timer. When the system ishanged due to an unpredictable software error, the hardware block monitorsinternal hardware status and generates reset signal to escape from this status.

• Wakeup reset: It is generatedwhen S3C6410X wake up from SLEEP mode. Since internal hardware states are notavailable any more after SLEEP mode, they must be initialized.

Hardwarereset

当XnRESET 引脚被声明后,系统内的所有单元(除了RTC 之外)复位到预先定义好的状态时,硬件复位被调用。在这段期间,将发生下面的动作:所有内部寄存器和ARM1176 内核都到预先定义好的复位状态。所有引脚都得到它们的复位状态。当XnRESET 被声明的同时,XnRSTOUT 引脚就被声明了。

XnRESET是不被屏蔽的,始终保持使能状态。XnRESET 的声明,无论先前为何模式,S3C6410 都进入复

位状态。XnRSET 必须持有足够长的时间允许内部稳定和传播。

The hardwarereset is invoked when XnRESET pin is asserted and all units in the system(except RTC) are reset to pre-defined states. During this period, the followingactions occur.

• All internalregisters and ARM1176 core go to the pre-defined reset states.

• All pins gettheir reset state.

• XnRSTOUT pinis asserted when XnRESET is asserted.

XnRESET isun-maskable and is always enabled. Upon assertion of XnRESET, S3C6410X entersinto reset state regardless of the previous mode. XnRSET must be held longenough to allow internal stabilization and propagation of the reset state toenter proper reset state.

Powerregulator for S3C6410X must be stable prior to the deassertion of XnRESET.Otherwise, it may damage S3C6410X and the operation is unpredictable. Figure3-17 is the timing diagram of power-on reset and pll turn-on sequence.


Watchdogreset

当软件挂起时,看门狗复位被调用。因此,在看门狗不能及时喂到时,就会发出超时命令。在看门狗复位期间,有以下动作发生:

除了ALIVE 和RTC 模块,所有模块进入预先定义好的复位状态。所有引脚都进入复位状态。在看门狗复位期间,nRSTOUT 引脚被声明。

在正常模式和闲置模式下,看门狗可被激活,并可产生超时信号。当看门狗定时器超时并复位使能时,其

可被调用。因此,下列依次发生:

1) WDT 产生超时信号。

2) SYSCON 调用复位信号,初始化内部IP。

3) 包括nRSTOUT 复位被声明,直到复位计数器RST_STABLE 被终止。

Watchdog resetis invoked when a software hang-up. Then, the software cannot initialize aregister within WDT and WDT makes time-out signals for watchdog reset. As theoccurrence of watchdog reset means that system has fatal problem, it behaveslike external reset except reset status register. During the watchdog reset,the

followingactions occur:

• All blocksexcept reset status register in ALIVE block go to their pre-defined resetstate.

• All pins gettheir reset state.

• The nRSTOUTpin is asserted during watchdog reset.

Watchdog resetcan be activated in NORMAL and IDLE mode, since WDT can generate time-outsignal. It is invoked when watchdog timer and reset are enabled. Then, thefollowing sequence occurs:

1. WDTgenerate time-out signal.

2. SYSCONinvokes reset signals and initialize internal IPs.

3. The resetincluding nRSTOUT will be asserted until the reset counter, RST_STABLE, isexpired.

Wakeupreset

Wakeup reset is invoked whenS3C6410 is woken-up from SLEEP by a wakeup event. The details are described inSLEEP mode section.


 
 
 

回复

6366

帖子

4929

TA的资源

版主

7
 
深入理解ARM体系架构(S3C6410)---S3C6410看门狗源码实例

当系统运行受到外部干扰或者系统错误,程序有时会出现跑飞,导致整个系统瘫痪。他会设置一段时间,当超出这段 时间,从程序中跳出进入中断处理程序。WatchDog本质上是一种定时器,那么普通定时器拥有的特性它也应该具备,是的当它计时超时时也会引起事件的发生,只是这个事件除了可以是系统中断外,他也可以是一个系统重启信号(Reset Signal)。可以这么说,能发送系统重启信号的定时器我们就叫它WatchDog。看门狗定时器中断是我们不希望看到的,因此我们要想方设法避免它发生。主要的方法就是在中断发生前,重新对看门狗定时器的寄存器进行赋值,使它的定时器重新开始记时,这种方法俗称喂狗。

S3C6410看门狗定时器的功能:

    作为常规时钟,并且可以产生中断

    作为看门狗定时器使用,当时钟计数器减为零时,它将产生一个复位信号。

The S3C6410XRISC microprocessor watchdog timer is used to resume the controller operation wheneverit is disturbed by malfunctions such as noise and system errors. The watchdogtimer generates the reset signal.

It can be usedas a normal 16-bit interval timer to request interrupt service.Advantagein using WDT instead of PWM timer is that WDT generates the reset signal.

FEATURES

The WatchdogTimer includes the following features:

• Normal interval timer mode with interruptrequest.

• Internal reset signal is activated when thetimer count value reaches 0 (time-out).

• Level-triggered Interrupt mechanism.


看门狗模块包括一个8位预分频器,一个分频器,一个16bit计数器。它的8位预分频器把PCLK分频后,再被分频得到4种频率,16分频,32分频,64分频,128分频。WatchDog可以选择工作于哪种频率下。S3C2440用3个寄存器对WatchDog进行操作:

    看门狗定时器控制寄存器(WTCON)

    看门狗定时器数据寄存器(WTDAT)

看门狗定时器计数寄存器(WTCNT)

Figure 34-1shows the functional block diagram of the watchdog timer. The watchdog timeruses only PCLK as its source clock. The PCLK frequency is prescaled to generatethe corresponding watchdog timer clock, and the resulting frequency is dividedagain.

The prescalervalue and the frequency division factor are specified in the watchdog timercontrol (WTCON)register. Valid prescaler values range from 0 to 28-1. Thefrequency division factor can be selected as 16, 32, 64,or 128.

Use thefollowing equation to calculate the watchdog timer clock frequency and theduration of each timer clock cycle:

t_watchdog = 1/( PCLK / (Prescaler value + 1) / Division_factor )

注意:

1、Once the watchdog timer is enabled, the value ofwatchdog timer data (WTDAT) register cannot be automatically reloaded into thetimer counter (WTCNT). For this reason, an initial value must be written to thewatchdog timer count (WTCNT) register, before the watchdog timer starts.

2、When the S3C6410 is in debug mode using EmbeddedICE, the watchdog timer must not operate.The watchdog timer can determinewhether or not it is currently in the debug mode from the CPU coresignal(DBGACK signal). Once the DBGACK signal is asserted, the reset output ofthe watchdog timer is not activated as the watchdog timer is expired.

看门狗寄存器映射:



1、WATCHDOG TIMER CONTROL(WTCON) REGISTER

WTCON允许用户使能看门狗定时器,从不同四个源选择时钟,使能中断,使能看门狗定时器输出。S3C6410看门狗定时器用于系统故障后复位。如果不希望复位,则使能定时器无效。

The WTCONregister allows the user to enable/disable the watchdog timer, select the clocksignal from 4 different sources, enable/disable interrupts, and enable/disablethe watchdog timer output.

The Watchdogtimer is used to resume the S3C6410 restart on mal-function after its power on.At this time,disable the interrupt generation and enable the Watchdog timeroutput for reset signal.

If controllerrestart is not desired and if the user wants to use the normal timer only,which is provided by the Watchdog timer, enable the interrupt generation anddisable the Watchdog timer output for reset signal.


注意:Initial state of ‘Reset enable/disable’ is 1(reset enable). If user do notdisable this bit, S3C6410 will be rebooted in about 5.63sec (In the case ofPCLK is 12MHz). So at boot loader, this bit should be disabled before undercontrol of Operating System, or Firmware.

2、WATCHDOG TIMER DATA (WTDAT) REGISTER

WTDAT用于确定超时期限。WTDAT的内容在最初的定时器操作时不能自动加载到定时器计数其中。但使用0x8000将驱使第一次超时,在这种情况下,WTDAT的值将自动载入WTCNT。

The WTDATregister is used to specify the time-out duration. The content of WTDAT cannotbe automatically loaded into the timer counter at initial watchdog timeroperation. However, using 0x8000 (initial value of WTCNT)will drive the firsttime-out. Then, the value of WTDAT will be automatically reloaded into WTCNT.


3、WATCHDOG TIMER COUNT(WTCNT) REGISTER

The WTCNT register contains the current count values for the watchdogtimer during normal operation.

注意:The content of the WTDAT register cannot be automatically loaded into thetimer count register when the watchdog timer is enabled initially, so the WTCNTregister must be set to an initial value before enabling it.





定义寄存器:


[cpp] view plaincopyprint?


  • //watchdog  
  • #define WTCON    (*(volatile unsigned *)(0x7E004000))  
  • #define WTDAT    (*(volatile unsigned *)(0x7E004004))  
  • #define WTCNT    (*(volatile unsigned *)(0x7E004008))  




初始化函数:


[cpp] view plaincopyprint?


  • void init_watchdog()  
  • {  
  •     WTDAT = 0xff;  
  •     WTCNT = 0x8000;  
  •     WTCON = 0XC021;//Prescaler value为6,16分频  
  • }  





在mian函数中调用:



[cpp] view plaincopyprint?


  • init_watchdog();  
  • while(1);  





注意:程序通过友善提供的superboot下载到内存并运行,约2秒后系统复位,PCLK=133M


程序下载:http://download.csdn.net/detail/muge0913/4156953

 
 
 

回复

6366

帖子

4929

TA的资源

版主

8
 
深入理解ARM体系架构(S3C6410)---PWM实例

S3C6410X中有5个定时器,这些定时器产生内部中断。其中,Timer0和Timer1具有PWM功能,而Timer2,3,4没有此功能。

The S3C6410X RISC microprocessorcomprises of five 32-bit timers. These timers are used to generate internal interruptsto the ARM subsystem. In addition, Timers 0 and 1 include a PWM function (PulseWidth Modulation),which can drive an external I/O signal. The PWM for timer 0and 1 have an optional dead-zone generator capability, which can be utilized tosupport a large current device. Timer 2, 3 and 4 are internal timers with no outputpins.

PWM具有两种操作模式:自动装载模式,一次触发模式。为实现PWM功能,芯片提供了16个功能寄存器。这些功能寄存器都连接APB总线。


总体架构图如下:



S3C6410X中有5个定时器,这些定时器产生内部中断。其中,Timer0和Timer1具有PWM功能,而Timer2,3,4没有此功能。定时器具有双缓冲特性,这样就能在不停止当前定时器操作的情况下,为下次定时器运行装入新的数值。尽管为定时器设置了新数值,但当前的定时操作能够成功完成。定时器从TCNTBn读取的值是为下次延时定时用的,并不影响当前定时器的运行。当TCNTn减小到0的时候,TCNTBn的值会自动复制到TCNTn中,这就是说的自动装载操作。定时器的当前技术数值可以从定时计数观察寄存器中TCNTOn读取。如果TCNTn为0且从装载也为0的话则TCNTn不在进行下次操作。


寄存器介绍:

1、总寄存器映射图

2、TCFG0寄存器:

3、TCFG1寄存器:

4、TCON控制寄存器:




mini6410蜂鸣器原理图:




定义寄存器:


[cpp] view plaincopyprint?


  • /* PWM Timer */  
  • #define rTCFG0       (*(volatile unsigned *)(0x7F006000))  
  • #define rTCFG1       (*(volatile unsigned *)(0x7F006004))  
  • #define rTCON        (*(volatile unsigned *)(0x7F006008))  
  • #define rTCNTB0      (*(volatile unsigned *)(0x7F00600C))  
  • #define rTCMPB0      (*(volatile unsigned *)(0x7F006010))  
  • #define rTCNTO0      (*(volatile unsigned *)(0x7F006014))  
  • #define rTCNTB1      (*(volatile unsigned *)(0x7F006018))  
  • #define rTCMPB1      (*(volatile unsigned *)(0x7F00601c))  
  • #define rTCNTO1      (*(volatile unsigned *)(0x7F006020))  
  • #define rTCNTB2      (*(volatile unsigned *)(0x7F006024))  
  • #define rTCNTO2      (*(volatile unsigned *)(0x7F00602c))  
  • #define rTCNTB3      (*(volatile unsigned *)(0x7F006030))  
  • #define rTCNTO3      (*(volatile unsigned *)(0x7F006038))  
  • #define rTCNTB4      (*(volatile unsigned *)(0x7F00603c))   
  • #define rTCNTO4      (*(volatile unsigned *)(0x7F006040))   
  • #define rTINT_CSTAT  (*(volatile unsigned *)(0x7F006044))  




编写初始化函数:


[cpp] view plaincopyprint?


  • void init_pwm()  
  • {  
  •    
  •     rGPFCON &= ~(0x3U << 28);  
  •     rGPFCON |=  (0x2U << 28);  
  •       
  •     rTCFG0 &= ~0xff;  
  •     rTCFG0 |= (50 - 1);  
  •    
  •     rTCFG1 = 0x4;  
  •     #define freq 800  
  •     rTCNTB0 = (133000000/50/16)/freq;  
  •     rTCMPB0 = rTCNTB0/2;  
  •   
  •   
  •     rTCON &= ~0x1f;  
  •     rTCON |= 0xb;       //disable deadzone, auto-reload, inv-off, update TCNTB0&TCMPB0, start timer 0  
  •   
  •   
  •     rTCON &= ~2;            //clear manual update bit  
  •       
  • }  


在main函数中:

[cpp] view plaincopyprint?


  • init_pwm();  
  • while(1);  





程序下载地址:http://download.csdn.net/detail/muge0913/4170428

 
 
 

回复

6366

帖子

4929

TA的资源

版主

9
 
深入理解ARM体系架构(S3C6410)---UART实例


1、  概括OVERVIEW

S3C6410提供了4个独立的异步串行口,每个独立的串行口可以工作在中断模式或DMA模式下。也就是说UART能够产生一个中断或DMA请求。UART可以提供最高3Mbps。每个UART包含2个64位的FIFO,分别用于接收,发送缓冲。

S3C6410 UART 包括可编程的波特率,红外发射接收,1或2个停止校验位,5,6,7,8数据位,和奇偶检验。每个UART包含一个波特率发生器,接收发送和控制单元。

波特率可以由PCLK,EXT_UCLK0或EX_UCLK1锁定。发送接收器分别包含了一个64位FIFO和一个数据移位器。通过向FIFO写入数据,再把FIFO中的数据拷贝到数据移位器中,从而通过TxDn引脚被发送出去。接收数据与之相反:RxDn->datashifter->FIFO.


2、  特性FEATURES

RxD0, TxD0, RxD1, TxD1, RxD2, TxD2, RxD3and TxD3支持DMA格式和中断格式。

UART 0,1,2,3支持红外通信和64位FIFO

UART 0,1支持nRTS0, nCTS0, nRTS1, and nCTS1

支持高速操作。

支持握手操作。




下面将描述数据的发送和接收,中断的产生,波特率的产生,回环模式,红外模式,和自动流控制模式。

3 、 数据发送DATA TRANSMISSION

发送的数据帧是可以编程的,其中包括一个开始位,5~8位数据位,奇偶校验位和1或2个停止位。这些都可以通过线性控制器ULCONn控制。发送器可以产生终止条件,这终止条件能强制在一个帧数据发送时间内使串口输出0状态。

The data framefor transmission is programmable. It consists of a start bit, 5 to 8 data bits,an optional parity bit and 1 to 2 stop bits, which can be specified by the linecontrol register (ULCONn). The transmitter can also produce the breakcondition, which forces the serial output to logic 0 state for one frametransmission time. This block transmits break signals after the presenttransmission word is transmitted completely. After the break signal transmission,it continuously transmits data into the Tx FIFO (Tx holding register in thecase of Non-FIFO mode).



4、 数据接收DATA RECEPTION

接收的数据帧是可以编程的,其中包括一个开始位,5~8位数据位,奇偶校验位和1或2个停止位。这些都可以通过线性控制器ULCONn控制。接收器能检测到溢出错误,奇偶校验错误,帧错误,和终止条件。每一个错误都可以设置一个错误标志。

overrun error指的是在一个以前的数据还没有被读走之前新的数据就把此数据覆盖了。

parity error指的是接收器检测到一个非预料的奇偶条件。

frame error指的是收到的数据没有停止位。

break condition指的是RxDn在超过一个数据帧的时间始终保持0状态。

当接收器在三个字的时间内(其间隔根据字长位的设置)没有收到任何数据且RxFIFO为空,产生超时条件。


5、 自动流控制AUTO FLOW CONTROL(AFC)

S3C6410中的UART0 和UART1 支持有nRTS和nCTS信号自动控制流。这样,它能连接至外部的UART。如果用户想连接UART到Modem。

则必须通过设置UMCONn禁止自动流并且通过软件来控制nRTS。只有在nCTS信号有效的情况下,UART才会向FIFO中写入数据。在自动流控制中nCTS表示另一个UART已经准备好接收数据了。在接收数据之前,如果FIFO有2个以上空余字节空间则把nRTS设为有效。空余字节空间小于1时,则要把nRTS设为无效。


串口部分寄存器较多,其实根据需要仔细配置即可。

已经编写好的串口程序如下:

[cpp] view plaincopyprint?


  • void Uart_Init(void)  
  • {  
  •     // UART I/O port initialize (RXD0 : GPA0, TXD0: GPA1)  
  •     rGPACON = (rGPACON & ~(0xff<<0)) | (0x22<<0);    // GPA0->RXD0, GPA1->TXD0  
  •     rGPAPUD = (rGPAPUD & ~(0xf<<0)) | (0x1<<0);        // RXD0: Pull-down, TXD0: pull up/down disable  
  •   
  •     // Initialize UART Ch0  
  •     rULCON0 = (0<<6)|(0<<3)|(0<<2)|(3<<0);                    // Normal Mode, No Parity, 1 Stop Bit, 8 Bit Data  
  •     rUCON0 = (0<<10)|(1<<9)|(1<<8)|(0<<7)|(0<<6)|(0<<5)|(0<<4)|(1<<2)|(1<<0);    // PCLK divide, Polling Mode  
  •     rUFCON0 = (0<<6)|(0<<4)|(0<<2)|(0<<1)|(0<<0);            // Disable FIFO  
  •     rUMCON0 = (0<<5)|(0<<4)|(0<<0);                        // Disable Auto Flow Control  
  •   
  •     rUBRDIV0 = 35;                                    // Baud rate  
  •     rUDIVSLOT0 = 0x80;//aSlotTable[DivSlot];  
  • }  
  •   
  •   
  • void Uart_SendByte(int data)  
  • {  
  •     while(!(rUTRSTAT0 & 0x2));   //Wait until THR is empty.  
  •     //_Delay();  
  •     WrUTXH0(data);  
  • }  
  •   
  • void Uart_SendString(char *pt)  
  • {  
  •     while(*pt)  
  •         Uart_SendByte(*pt++);  
  • }  
  •   
  • //=====================================================================  
  • char Uart_GetCh(void)  
  • {  
  •            
  •      while(!(rUTRSTAT0 & 0x1)); //Receive data ready  
  •         return RdURXH0();  
  •      
  • }  
  •   
  • char Uart_GetKey(void)  
  • {  
  •         if(rUTRSTAT0 & 0x1)    //Receive data ready  
  •             return RdURXH0();  
  •         return 0;      
  • }  
 
 
 

回复

6366

帖子

4929

TA的资源

版主

10
 
在8位处理器上运行 Linux

一名叫做 Dmitry Grinberg 的国外黑客尝试制作了一个 8 位的简单计算机微控制设备,在它上面运行Linux。


他写了一个 ARM 模拟器: 启动 2 小时后看到了命令行提示符(init=/bin/bash),4 小时后看到了 Ubuntu 登录页面。登录之后系统从某种程度上还是可用的,输入一个命令后在一分钟内能看到回应。


按照一般情况来说,Linux 不会在少于 32 位的系统上运行,因此,黑客 Grinberg 不得不为 8 位处理器编写了一个 32 位模拟器,他模拟的 CPU 速度只有 6.5KHz,它是最廉价、最慢、最简单和最低端的 Linux PC,一旦启动之后,该计算机还是有点用处的,作者 Grinberg 偶尔会用它来格式化SD卡。



这款计算机设备的硬件配置:8位24MHz微处理器,16MB ROM,128KB内存,运行Linux系统。




 
 
 

回复

6366

帖子

4929

TA的资源

版主

11
 
深入理解ARM体系架构(S3C6410)---外部中断控制实例

关于S3C6410的中断问题,网上有很多高手已经分析过了,在这里我主要分析S3C6410实现过程,和自己已经编写好的简单程序。

我用的是mini6410 的k1键实现外部中断。


按键初始化:


[cpp] view plaincopyprint?


  • void Key_Init()  
  • {  
  •     rGPNCON|=(1<<1);  //将GPN0设置为中断模式  
  •     rGPNPUD&=~(1<<0);//上拉电阻  
  •     rEINT0CON0|=(3<<0); //下降沿触发  
  •     rEINT0MASK&=~(1<<0);  //取消屏蔽  
  •     rEINT0FLTCON0|=(1<<7);  //延时滤波  
  • }  


注意:我在这只初始化了一个引脚,即GPNCON0

按键中断程序:



[cpp] view plaincopyprint?


  • void Key_ISR() __irq  //按键中断函数  
  • {  
  •     i++;  
  •       
  •     if(i%2==0)Led_Display(0x0);//在这里用户可添加其他的处理操作  
  •     else Led_Display(0xf);  
  •       
  •     rEINT0PEND|=(1<<0);//写1清除中断  
  •     INTC_ClearVectAddr();//这个函数下面我们再介绍  
  • }  



[cpp] view plaincopyprint?


  • /*
  • 清除中断指示,防止干扰下一次中断发生
  • */  
  • void INTC_ClearVectAddr(void)  
  • {  
  •    rVIC0ADDR = 0x0;  
  •    rVIC1ADDR = 0x0;  
  • }  





中断初始化函数:



[cpp] view plaincopyprint?


  • void INTC_Init(void)   
  • {  
  •   //关闭所有中断  
  •   rVIC0INTENCLEAR = 0xffffffff;   
  •   rVIC1INTENCLEAR = 0xffffffff;   
  •    
  •   //都设置为IRQ  
  •   rVIC0INTSELECT = 0x0;  
  •   rVIC1INTSELECT = 0x0;  
  •    
  •   INTC_ClearVectAddr();  
  •    
  • }  


使能中断函数:


[cpp] view plaincopyprint?


  • //打开某一个中断  
  •   
  • int INTC_Enable(unsigned int intNum)  
  • {  
  •     if(intNum > INT_LIMIT)//数值检测  
  •      {  
  •         return -1;  
  •      }  
  •       
  •       
  •   
  •     if(intNum<32)//如果是vic0组  
  •     {  
  •          
  •         rVIC0INTENABLE |= (1<
  •          
  •     }  
  •     else//如果是vic1组  
  •     {  
  •         rVIC1INTENABLE |= (1<<(intNum -32));                    
  •     }  
  •   
  •     return 0;  
  •   
  • }  




指定中断程序函数:


[cpp] view plaincopyprint?


  • void INTC_SetIntISR(unsigned int intNum, void (*isr)(void) __irq)  
  • {  
  •   if(intNum > INT_LIMIT)//数值检测  
  •      {  
  •         return ;  
  •      }  
  •       
  •      if(intNum < 32)//如果是vic0组  
  •      {  
  •          VIC0VECTADDR[intNum] = (unsigned )isr;  
  •          
  •      }  
  •      else//如果是vic1组  
  •      {  
  •          VIC1VECTADDR[intNum-32] = (unsigned )isr;  
  •      }  
  • }  



编写main函数:


[cpp] view plaincopyprint?


  • Led_Init();//led初始化  
  •   
  • Led_Display(0x0);//控制led  
  •   
  • Key_Init();//按键初始化  
  • INTC_Init();//中断初始化  
  • INTC_Enable(INT_EINT0);//中断使能  
  • INTC_SetIntISR(INT_EINT0,Key_ISR);//指定中断处理函数  
  •   
  • while(1);//等待  
 
 
 

回复

6366

帖子

4929

TA的资源

版主

12
 
深入理解ARM体系架构(S3C6410)---系统时钟初始化实例


关于这篇文章:

1、此段程序实现了533M的系统时钟设置。关于s3c6410时钟知识请看另一篇文章:http://blog.csdn.net/muge0913/article/details/7364706


2、用的开发工具为RVDS2.2。写这篇文章主要是为下篇的sdram初始化和代码拷贝实现,做个知识的铺垫。呵呵

3、如果要实现其他频率的设置,在下面的 定义数据代码 中修改相应的数据即可,主要是分频值的设置。

程序如下:

1、定义数据:


[cpp] view plaincopyprint?


  • ;clock  
  • ELFIN_WATCHDOG_BASE  EQU   0x7e004000  
  • ELFIN_CLOCK_POWER_BASE EQU   0x7e00f000  
  • OTHERS_OFFSET       EQU   0x900  
  • APLL_LOCK_OFFSET    EQU   0x00  
  • MPLL_LOCK_OFFSET    EQU   0x04  
  • EPLL_LOCK_OFFSET    EQU   0x08  
  • CLK_DIV2_OFFSET     EQU   0x28  
  • CLK_DIV0_OFFSET     EQU   0x20  
  • Startup_PCLKdiv     EQU   3  
  • Startup_HCLKx2div   EQU   1  
  • Startup_HCLKdiv     EQU   1  
  • Startup_MPLLdiv     EQU   1  
  • Startup_APLLdiv     EQU   1  
  • CLK_DIV_VAL         EQU   ((Startup_PCLKdiv<<12)|(Startup_HCLKx2div<<9)|(Startup_HCLKdiv<<8)|(Startup_MPLLdiv<<4)|Startup_APLLdiv)  
  • APLL_MDIV           EQU   266  
  • APLL_PDIV           EQU   3  
  • APLL_SDIV           EQU   1  
  • APLL_VAL            EQU   ((1<<31 | APLL_MDIV<<16 | APLL_PDIV<<8 | APLL_SDIV))  
  • APLL_CON_OFFSET     EQU   0x0c  
  • MPLL_CON_OFFSET     EQU   0x10  
  • EPLL_CON0_OFFSET    EQU   0x14  
  • EPLL_CON1_OFFSET    EQU   0x18  
  • CLK_SRC_OFFSET      EQU   0x1c  
  • MPLL_MDIV           EQU   266  
  • MPLL_PDIV           EQU   3  
  • MPLL_SDIV           EQU   1  
  • MPLL_VAL            EQU   ((1<<31 | MPLL_MDIV<<16 | MPLL_PDIV<<8 | MPLL_SDIV))  


2、时钟初始化程序:


[cpp] view plaincopyprint?


  • clk_init  
  •     ldr r0, =ELFIN_CLOCK_POWER_BASE ;0x7e00f000  
  •      ldr r1, [r0, #OTHERS_OFFSET]  
  •      mov r2, #0x40  
  •      orr r1, r1, r2  
  •      str r1, [r0, #OTHERS_OFFSET]  
  •      nop  
  •      nop  
  •      nop  
  •      nop  
  •      nop  
  •      ldr r2, =0x80  
  •      orr r1, r1, r2  
  •      str r1, [r0, #OTHERS_OFFSET]  
  • check_syncack  
  •      ldr r1, [r0, #OTHERS_OFFSET]  
  •      ldr r2, =0xf00  
  •      and r1, r1, r2  
  •      cmp r1, #0xf00  
  •      bne check_syncack  
  •      mov r1, #0xff00  
  •      orr r1, r1, #0xff  
  •      str r1, [r0, #APLL_LOCK_OFFSET]  
  •      str r1, [r0, #MPLL_LOCK_OFFSET]  
  •      str r1, [r0, #EPLL_LOCK_OFFSET]  
  •      ldr    r1, [r0, #CLK_DIV2_OFFSET]  
  •      bic r1, r1, #0x70000  
  •      orr r1, r1, #0x30000  
  •      str r1, [r0, #CLK_DIV2_OFFSET]  
  •      ldr    r1, [r0, #CLK_DIV0_OFFSET] ;Set Clock Divider  
  •      bic r1, r1, #0x30000  
  •      bic r1, r1, #0xff00  
  •      bic r1, r1, #0xff  
  •      ldr r2, =CLK_DIV_VAL  
  •      orr r1, r1, r2  
  •      str r1, [r0, #CLK_DIV0_OFFSET]  
  •      ldr r1, =APLL_VAL  
  •      str r1, [r0, #APLL_CON_OFFSET]  
  •      ldr r1, =MPLL_VAL  
  •      str r1, [r0, #MPLL_CON_OFFSET]  
  •      ldr r1, =0x80200203   ;FOUT of EPLL is 96MHz  
  •      str r1, [r0, #EPLL_CON0_OFFSET]  
  •      ldr r1, =0x0  
  •      str r1, [r0, #EPLL_CON1_OFFSET]  
  •      ldr r1, [r0, #CLK_SRC_OFFSET] ;APLL, MPLL, EPLL select to Fout  
  •      ldr r2, =0x2007  
  •      orr r1, r1, r2  
  •      str r1, [r0, #CLK_SRC_OFFSET]  
  •      ;wait at least 200us to stablize all clock  
  •      mov r1, #0x10000  
  • 1   
  •     subs r1, r1, #1  
  •      bne %B1  
  •      ;Synchronization for VIC port  
  •      ldr r1, [r0, #OTHERS_OFFSET]  
  •      orr r1, r1, #0x20  
  •      str r1, [r0, #OTHERS_OFFSET]  
  •   
  •      mov pc,lr  
 
 
 

回复

6366

帖子

4929

TA的资源

版主

13
 
深入理解ARM体系架构(S3C6410)---DRAM控制器初始化实例

S3C6410内存控制器是采用的PL340内存控制芯片。AMBA APB3.0接口协议规定,可以通过编程将AXI从总线接口和APB主总线接口进行桥接,实现二者总线上的数据的传输。DRAM控制器可以直接从SDRAM或DRAM接收一个控制命令。通过将操作命令写入direct_cmd寄存器,操作SDRAM进行对应操作。通过向memc_cmd寄存器写入状态模式命令,使DRAM控制器进入对应的工作模式。例如:向direct_cmd寄存器写入:Prechargeall’,‘Autorefresh’,‘NOP’,and ‘MRS’ 等命令,可以让SDRAM芯片分别执行不同操作,向memc_cmd寄存器写入一些状态命令可以让SDRAM芯片进入’Config’, ‘Ready’, and ‘Low_power’等工作模式。

DRAM控制器支持两种节能模式。当SDRAM处于不活动状态并且持续一定的时钟周期时,DRAM控制器会自动将SDRAM进入预充电节能模式或正常节能模式下以降低系统功耗。当驱动操作DRAM控制器进入对应的STOP(停止),Deep Stop(深度睡眠),Sleep Mode(睡眠)等模式时,SDRAM芯片进入自刷新的节能模式。

DRAM控制器支持两个同类型的chip,同时能为每个chip最大分配256M的地址空间。除了时钟时钟信号和片选信号,其他的引脚chip都是共享的。



dram控制器引脚接口如下:



注:

在复位时,必须软件初始化DRAM控制器和连接到此控制器的SDRAM。初始化SDRAM参考SDRAM的数据手册即可。在mini6410开发用的是mobile ddr sdram。


在mini6410中sdram的电路如下:



DRAM控制器初始化程序如下:



[cpp] view plaincopyprint?


  • mem_ctrl_asm_init  
  •   
  •      ldr r0, =ELFIN_MEM_SYS_CFG    ;Memory sussystem address 0x7e00f120  
  •      mov r1, #0xd      ;Xm0CSn2 = NFCON CS0 设置NAND Flash为存储器  
  •      str r1, [r0]  
  •      ldr r0, =ELFIN_DMC1_BASE     ;DMC1 base address 0x7e001000  
  •       
  •      ; memc_cmd : 010 wake up  
  •      ldr r1, =0x04  
  •      str r1, [r0, #INDEX_DMC_MEMC_CMD]  
  •       
  •      ; Refresh period = ((Startup_HCLK / 1000 * DDR_tREFRESH) - 1) / 1000000  -> DDR_tREFRESH 7800 ns  
  •      ldr r1, = 1308        ; DMC_DDR_REFRESH_PRD  
  •      str r1, [r0, #INDEX_DMC_REFRESH_PRD]  
  •       
  •      ; CAS_Latency = DDR_CASL<<1    -> DDR_CASL 3  
  •      ldr r1, = 6         ; DMC_DDR_CAS_LATENCY  
  •      str r1, [r0, #INDEX_DMC_CAS_LATENCY]  
  •       
  •      ; t_DQSS (clock cycles)  
  •      ldr r1, = 1         ; DMC_DDR_t_DQSS  
  •      str r1, [r0, #INDEX_DMC_T_DQSS]  
  •      ; T_MRD  (clock cycles)  
  •      ldr r1, = 2         ; DMC_DDR_t_MRD  
  •      str r1, [r0, #INDEX_DMC_T_MRD]  
  •      ; T_RAS (clock cycles)  
  •      ldr r1, = 7         ; DMC_DDR_t_RAS  
  •      str r1, [r0, #INDEX_DMC_T_RAS]  
  •      ; T_RC Active Bank x to Active Bank x delay(clock cycles)  
  •      ldr r1, = 10        ; DMC_DDR_t_RC  
  •      str r1, [r0, #INDEX_DMC_T_RC]  
  •      ; T_RCD RAS to CAD delay(clock cycles)  
  •      ldr r1, = 4         ; DMC_DDR_t_RCD  
  •      ldr r2, = 8         ; DMC_DDR_schedule_RCD  
  •      orr r1, r1, r2  
  •      str r1, [r0, #INDEX_DMC_T_RCD]  
  •      ; T_RFC AutoRefresh(clock cycles)  
  •      ldr r1, = 11         ; DMC_DDR_t_RFC  
  •      ldr r2, = 256        ; DMC_DDR_schedule_RFC  
  •      orr r1, r1, r2  
  •      str r1, [r0, #INDEX_DMC_T_RFC]  
  •      ; T_RP Precharge to RAS delay(clock cycles)  
  •      ldr r1, = 4         ; DMC_DDR_t_RP  
  •      ldr r2, = 8         ; DMC_DDR_schedule_RP  
  •      orr r1, r1, r2  
  •      str r1, [r0, #INDEX_DMC_T_RP]  
  •      ; T_RRD Active Bank x to Active Bank y delay(clock cycles)  
  •      ldr r1, = 3         ; DMC_DDR_t_RRD  
  •      str r1, [r0, #INDEX_DMC_T_RRD]  
  •      ; T_WR Write to precharge delay(clock cycles)  
  •      ldr r1, =3         ; DMC_DDR_t_WR  
  •      str r1, [r0, #INDEX_DMC_T_WR]  
  •      ; T_WTR Write to Read delay(clock cycles)  
  •      ldr r1, = 2         ;DMC_DDR_t_WTR  
  •      str r1, [r0, #INDEX_DMC_T_WTR]  
  •      ; T_XP Exit Power down(clock cycles)  
  •      ldr r1, = 2         ; DMC_DDR_t_XP  
  •      str r1, [r0, #INDEX_DMC_T_XP]  
  •      ; T_XSR Exit self refresh(clock cycles)  
  •      ldr r1, = 17        ; DMC_DDR_t_XSR  
  •      str r1, [r0, #INDEX_DMC_T_XSR]  
  •      ; T_ESR SelfRefresh(clock cycles)  
  •      ldr r1, = 17        ; DMC_DDR_t_ESR  
  •      str r1, [r0, #INDEX_DMC_T_ESR]  
  •      ; Memory Configuration Register  
  •      ldr r1, = 0x40010012      ; DMC1_MEM_CFG  
  •      str r1, [r0, #INDEX_DMC_MEMORY_CFG]  
  •      ldr r1, = 0xb41        ; DMC1_MEM_CFG2  
  •      str r1, [r0, #INDEX_DMC_MEMORY_CFG2]  
  •      ldr r1, = 0x150f8       ; DMC1_CHIP0_CFG  
  •      str r1, [r0, #INDEX_DMC_CHIP_0_CFG]  
  •      ldr r1, = 0         ; DMC_DDR_32_CFG  
  •      str r1, [r0, #INDEX_DMC_USER_CONFIG]  
  •      ; The follows is according to the Datasheet initialization sequence  
  •      ;DMC0 DDR Chip 0 configuration direct command reg  
  •      ldr r1, = 0x0c0000       ; DMC_NOP0  
  •      str r1, [r0, #INDEX_DMC_DIRECT_CMD]  
  •      ;Precharge All  
  •      ldr r1, = 0         ; DMC_PA0  
  •      str r1, [r0, #INDEX_DMC_DIRECT_CMD]  
  •      ;Auto Refresh 2 time  
  •      ldr r1, = 0x40000       ; DMC_AR0  
  •      str r1, [r0, #INDEX_DMC_DIRECT_CMD]  
  •      str r1, [r0, #INDEX_DMC_DIRECT_CMD]  
  •      ;MRS  
  •      ldr r1, = 0xa0000       ; DMC_mDDR_EMR0  
  •      str r1, [r0, #INDEX_DMC_DIRECT_CMD]  
  •      ;Mode Reg  
  •      ldr r1, = 0x80032       ; DMC_mDDR_MR0  
  •      str r1, [r0, #INDEX_DMC_DIRECT_CMD]  
  •      ;Enable DMC1  
  •      mov r1, #0x0  
  •      str r1, [r0, #INDEX_DMC_MEMC_CMD]  
  • check_dmc1_ready  
  •      ldr r1, [r0, #INDEX_DMC_MEMC_STATUS]  
  •      mov r2, #0x3  
  •      and r1, r1, r2  
  •      cmp r1, #0x1  
  •      bne check_dmc1_ready  
  •      nop  
  •   
  •     mov pc, lr   



最后把生成的.bin文件,放到sd卡中,在配置文件当中设置运行.bin文件即可。



程序下载地址:http://download.csdn.net/detail/muge0913/4200810程序下载地址:http://download.csdn.net/detail/muge0913/4200810

 
 
 

回复

6366

帖子

4929

TA的资源

版主

14
 
深入理解ARM体系架构(S3C6410)---lcd 显示图片

S3C6410显示控制器包含这样的逻辑电路:从后处理器(POST Processor)或系统内存视频缓冲数据的本地总线传递数据到外部LCD驱动接口电路的逻辑电路。S3C6410包含4种接口:传统的RGB接口,I80接口,标准电视编码接口NTSC/PAL,IT-R BT.601接口。S3C6410显示控制器支持5层图像窗口。层图像窗口支持:various color format,16 level alpha blending, color key, x-y position control, soft scrolling,variable window size。显示控制器支持1BPP~24BPP 色彩的RGB格式和YCbCr格式。显示控制器能满足水平垂直像素,数据宽度, 接口时序, 刷新频率等各种设置需求。显示控制器视频数据接口包括:RGB_VD[23:0],SYS_VD[17:0], TV_OUT。




显示控制器由VSFR,VDMA,VPRCS,VTIME,和视频时钟产生器。VSFR包含一些可编程的寄存器和两个256x25的调色板内存。这些都是用于配置显示控制器的。VDMA专用于显示DMA。它能将一帧的视频数据发送到VPRCS。通过这些特定DMA,这些视频数据可以在CPU不调停的情况下,显示到显示屏上。VPRCS从VDMA接收视频数据,并把接收的数据转化成合适的数据格式,从而再发送到显示器件上(LCD)。VTIME包含一些可编程的逻辑器件以满足不同显示设备的需求,如设置接口时序和刷新频率. 产生:RGB_VSYNC,RGB_HSYNC, RGB_VCLK, RGB_VDEN,SYS_CS1, SYS_CS0等信号控制显示设备。



FIFO在VDMA中。当FIFO为空或部分为空时,VDMA就会请求数据。当内存中的总线仲裁接收到这样的传输请求时,就会从系统内存向内部FIFO传输4/8/16连续的字。每个FIFO有64个字,同时FIFO的使用大小又有数据的传输速率决定。显示控制器有5个FIFO,主要是为了满足5个图像层的使用。在每个屏幕显示模式中,只有一个FIFO被使用。VPRCS通过FIFO提取数据。VPRCS支持层功能,最多5个层。下面的图像显示了数据流从系统总线到输出缓存的过程。



再来看看mini6410中,nec43和显示控制器的连接原理图:



这样我们就可以参考相应的寄存器设置,来实现lcd的图片显示了,

原图片:


我的手机像素极差,,,,


程序如下:

初始化函数:


[cpp] view plaincopyprint?


  • void LCD_Init(void)   
  • {  
  •   
  •   
  •     //设置VD0~15  
  •     rGPICON = 0xaaaaaaaa;  //设置GPI0~15为LCD VD0~15  
  •     rGPIPUD = 0x00000000;  
  •   
  •     //设置VD16~23和HSYNC、VSYNC、VDEN、VCLK  
  •     rGPJCON = 0x00aaaaaa;  
  •     rGPJPUD = 0x00000000;  
  •   
  •     //LCD寄存器设置  
  •     rSPCON |= (1<<0);  //设置RGBI/F配置  //rSPCON = rSPCON & ~(0x3) | 1;  
  •     rMIFPCON &= ~(1<<3);  //设置LCD支路为一般模式  
  •       
  •     rVIDCON0 = (0<<29)|(0<<27)|(0<<26)|(0<<18)|(0<<17)|(0<<16)|(9<<6)|(0<<5)|(1<<4)|(0<<3)|(0<<2)|(1<<1)|(1<<0);  
  •     rVIDCON1 = 1<<7;  //1=RGB类型LCD设备在VCLK上升沿得到视频数据  
  •       
  •     //设置屏的时序  
  •     rVIDTCON0 = (0x00<<16)|(0x00<<8)|(0x02<<0);  
  •     rVIDTCON1 = (0x2d<<16)|(0x04<<8)|(0x06<<0);  
  •     rVIDTCON2 = (271<<11)|(479<<0);  
  •   
  •     //设置窗口格式  
  •     rWINCON0 = 11<<2;  //设置24BPP  
  •   
  •     //设置窗口位置  
  •     rVIDOSD0A = (0<<11)|(0<<0);  
  •     rVIDOSD0B = (479<<11)|(271<<0);  
  •     rVIDOSD0C = (((480*272)&0xffffff)<<0);  //4.3屏幕分辨率480*272  
  •   
  •     //设置Window1的开始和结束的缓存地址与地址在内存中的存放地址以及缓存的大小  
  •     rVIDW00ADD0B0 = ((addr>>24)<<24)|(addr&0xffffff);  
  •     rVIDW00ADD1B0 = (addr&0xffffff + 480*272);  
  •     rVIDW00ADD2 = (0<<13)|(480<<0);  
  •   
  •     //设置抖动  
  •     rDITHMODE=(1<<5)|(1<<3)|(1<<1)|(1<<0);  
  •   
  •     //开显示  
  •     rVIDCON0 |= (3<<0);  
  •     rWINCON0 |= (1<<0);  
  • }  



画图函数:



[cpp] view plaincopyprint?


  • void LCD_DrawPixel(unsigned int x, unsigned int y, unsigned int color)  
  • {  
  •     if((x<480) && (y<272))  
  •         LCD_BUFFER[y][x] = color;  
  • }  
  •   
  • void LCD_Paint_Bmp(int x0,int y0,int h,int l,const unsigned char *bmp)  
  • {  
  •     int x,y;  
  •     unsigned int c;  
  •     int p = 0;  
  •       
  •     for( y = y0 ; y < l ; y++ )  
  •     {  
  •         for( x = x0 ; x < h ; x++ )  
  •         {  
  •             //RGB888  
  •             c = (bmp[p]) | (bmp[p+1]<<8) | (bmp[p+2]<<16);  
  •             if ( ( (x0+x) < LCD_XSIZE) && ( (y0+y)
  •             LCD_BUFFER[y0+y][x0+x] = c ;  
  •             p = p+3;   
  •         }  
  •     }  
  • }  
 
 
 

回复

6366

帖子

4929

TA的资源

版主

15
 
深入理解ARM体系架构(S3C6410)---ad转化实例


对于adc的功能大家都已经很熟悉了,以前我也写过关于S3C6410中ad的文章,如:http://blog.csdn.net/muge0913/article/details/7059241

本实例是把采集的ad数据转化后显示在lcd屏上,在这直接把自己调试好的源码贴出来


ad转化器相关代码:


[cpp] view plaincopyprint?


  • void adc_init()  
  • {  
  •     /*设置分频时钟*/  
  •     char preScaler = 66500000/2500000 - 1; //PCLK=66M         
  •     rADCCON = (1<<14)|(preScaler<<6)|(0<<3)|(0<<2);//通道AIN0  
  •    // rADCCON =0x44c1;//通道AIN0  
  • }  
  • int read_adc()  
  • {  
  •    /*开始AD转换*/  
  •    rADCCON |= 0x01; //start ADC  
  •       
  •    while(rADCCON & 0x1);    //check if Enable_start is low  
  •       
  •    /*检查转换是否结束*/  
  •    while(!(rADCCON & 0x8000));  //check if EC(End of Conversion) flag is high  
  •       
  •    return ( (int)rADCDAT0 & 0x3ff );  
  • }  
  •   
  • void delay_adc()  
  • {  
  •     int i,j;  
  •     for(i=0;i<10000000;i++)  
  •         for(j=0;j>10000000;j++);   
  • }  


lcd相关代码:

初始化子程序:


[cpp] view plaincopyprint?


  • void LCD_Init(void)   
  • {  
  •   
  •     //设置LCD调光  
  •     //rGPFCON |= (1<<30);  //设置LCD调光管脚GPF15(PWM1)为输出  
  •     //rGPFDAT |= (1<<15);  //rGPFDAT =  0x00002000;  
  •     //rGPFPUD &= ~(1<<30);  //rGPFPUD = 0x00000000;  
  •   
  •     //设置VD0~15  
  •     rGPICON = 0xaaaaaaaa;  //设置GPI0~15为LCD VD0~15  
  •     rGPIPUD = 0xffffffff;  
  •   
  •   
  •          
  •     //设置VD16~23和HSYNC、VSYNC、VDEN、VCLK  
  •     rGPJCON = 0x00aaaaaa;  
  •     rGPJPUD = 0xffffffff;  
  •     rWINCON0 &= ~(1<<0);  
  •   
  •     //LCD寄存器设置  
  •     rSPCON &= (~0x3);  
  •     rSPCON |= (1<<0);  //设置RGBI/F配置  
  •     rMIFPCON &= ~(1<<3);  //设置LCD支路为一般模式  
  •       
  •     rVIDCON0 = (0<<29)|(0<<26)|(0<<17)|(1<<16)|(9<<6)|(0<<5)|(1<<4)|(0<<3)|(0<<2);  
  •     rVIDCON1 = 1<<7;  //1=RGB类型LCD设备在VCLK上升沿得到视频数据  
  •       
  •     //设置屏的时序  
  •     rVIDTCON0 = (0x00<<16)|(0x00<<8)|(0x02<<0);  
  •     rVIDTCON1 = (0x2d<<16)|(0x04<<8)|(0x06<<0);  
  •     rVIDTCON2 = (271<<11)|(479<<0);  
  •   
  •     //设置窗口格式  
  •     rWINCON0 = 11<<2;  //设置24BPP  
  •   
  •     //设置窗口位置  
  •     rVIDOSD0A = (0<<11)|(0<<0);  
  •     rVIDOSD0B = (479<<11)|(271<<0);  
  •     rVIDOSD0C = (((480*272)&0xffffff)<<0);  //4.3屏幕分辨率480*272  
  •   
  •     //设置Window1的开始和结束的缓存地址与地址在内存中的存放地址以及缓存的大小  
  •     rVIDW00ADD0B0 = ((addr>>24)<<24)|(addr&0xffffff);  
  •     rVIDW00ADD1B0 = (addr&0xffffff + 480*272);  
  •     rVIDW00ADD2 = (0<<13)|(480<<0);  
  •   
  •     //设置抖动  
  •     rDITHMODE=(1<<5)|(1<<3)|(1<<1)|(1<<0);  
  •   
  •     //开显示  
  •     rVIDCON0 |= (3<<0);  
  •     rWINCON0 |= (1<<0);  
  • }  


lcd字符显示子程序:

[cpp] view plaincopyprint?


  • void Paint_text(unsigned int x, unsigned int y, unsigned int color, unsigned char ch[], unsigned int lengx,int lengy){  
  •     int i, j, test, t = -1;           
  •     for(i = 0; i < lengy; i++){              
  •         for(j = 0; j < lengx; j++){           
  •             if(j%8 == 0){           
  •                 test = 0x80;           
  •                 t++;           
  •             }           
  •             if(ch[t] & test)           
  •                 LCD_BUFFER[y+i][x+j] = color;  
  •             else  
  •                 LCD_BUFFER[y+i][x+j] = 0xffffff;  
  •               
  •             test >>= 1;              
  •         }            
  •     }           
  • }   





头文件中字符数据定义:


[cpp] view plaincopyprint?


  • unsigned char charnum[10][16]={  
  • {0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x24,0x18,0x00,0x00},  
  • {0x00,0x00,0x00,0x10,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00},  
  • {0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x04,0x04,0x08,0x10,0x20,0x42,0x7E,0x00,0x00},  
  • {0x00,0x00,0x00,0x3C,0x42,0x42,0x04,0x18,0x04,0x02,0x02,0x42,0x44,0x38,0x00,0x00},  
  • {0x00,0x00,0x00,0x04,0x0C,0x14,0x24,0x24,0x44,0x44,0x7E,0x04,0x04,0x1E,0x00,0x00},  
  • {0x00,0x00,0x00,0x7E,0x40,0x40,0x40,0x58,0x64,0x02,0x02,0x42,0x44,0x38,0x00,0x00},  
  • {0x00,0x00,0x00,0x1C,0x24,0x40,0x40,0x58,0x64,0x42,0x42,0x42,0x24,0x18,0x00,0x00},  
  • {0x00,0x00,0x00,0x7E,0x44,0x44,0x08,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00},  
  • {0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x24,0x18,0x24,0x42,0x42,0x42,0x3C,0x00,0x00},  
  • {0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x26,0x1A,0x02,0x02,0x24,0x38,0x00,0x00}};  
  •   
  •   
  •   
  •   
  • unsigned char charnumc[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x22,0x40,0x40,0x40,0x22,0x1C,0x00,0x00};  
  • unsigned char charnumo[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,0x00};  
  • unsigned char charnumn[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xDC,0x62,0x42,0x42,0x42,0x42,0xE7,0x00,0x00};  
  • unsigned char charnumv[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE7,0x42,0x24,0x24,0x28,0x10,0x10,0x00,0x00};  
  • unsigned char charnume[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x7E,0x40,0x40,0x42,0x3C,0x00,0x00};  
  • unsigned char charnumr[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0x32,0x20,0x20,0x20,0x20,0xF8,0x00,0x00};  
  • unsigned char charnums[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x42,0x40,0x3C,0x02,0x42,0x7C,0x00,0x00};  
  • unsigned char charnumi[]={0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00};  





主函数程序:


[cpp] view plaincopyprint?


  • adc_init();  
  •   
  • LCD_Init();  
  • Paint_background(0xffffff,0,0,480,272);  
  •   
  •   
  • while(1)  
  • {  
  • adc_data = read_adc();  
  • adc_data = (adc_data*32226);  
  •   
  • adc_data_tmp[0] = adc_data/100000/100;  
  • //adc_data_tmp[1] = ((adc_data/100)%100000)/10000;  
  • adc_data_tmp[1] = adc_data%10000000/1000000;  
  • adc_data_tmp[2] = adc_data%1000000/100000;  
  • adc_data_tmp[3] = adc_data%100000/10000;  
  • adc_data_tmp[4] = adc_data%10000/1000;  
  • adc_data_tmp[5] = adc_data%1000/100;  
  • adc_data_tmp[6] = adc_data%100/10;  
  • adc_data_tmp[7] = adc_data%10;  
  •   
  •   
  • Paint_text(124+8*0, 20, 0x0,charnum[adc_data_tmp[0]],8, 16);  
  • Paint_text(124+8*1, 20, 0x0,charnum[adc_data_tmp[1]],8, 16);  
  • Paint_text(124+8*2, 20, 0x0,charnum[adc_data_tmp[2]],8, 16);  
  • Paint_text(124+8*3, 20, 0x0,charnum[adc_data_tmp[3]],8, 16);  
  • Paint_text(124+8*4, 20, 0x0,charnum[adc_data_tmp[4]],8, 16);  
  • Paint_text(124+8*5, 20, 0x0,charnum[adc_data_tmp[5]],8, 16);  
  • Paint_text(124+8*6, 20, 0x0,charnum[adc_data_tmp[6]],8, 16);  
  • Paint_text(124+8*7, 20, 0x0,charnum[adc_data_tmp[7]],8, 16);  
  • delay_adc();  
  •   
  • }  
 
 
 

回复

6366

帖子

4929

TA的资源

版主

16
 
深入理解ARM体系架构(S3C6410)---rtc实例

实时时钟(RTC)的主要功能是在系统掉电的情况下,利用后备电源使时钟继续运行,从而不会丢失时间信息。s3c6410内部集成了RTC模块,其内部的寄存器BCDSEC,BCDMIN,BCDHOUR,BCDDAY,BCDDATE,BCDMON和BCDYEAR分别存储了当前的秒,分,小时,星期,日,月和年,表示时间的数值都是BCD码。

S2C6410中的闰年问题:


闰年产生器基于BCDDAY,BCDMOD,BCDYEAR从而能决定每月最后的日期是28,29,30,还是31。一个8位的计数器只能表示2个BCD数据,因此不能判断“00”结尾的年份是不是闰年。例如它不能判断1900和2000是不是闰年。为了解决这个问题,S3C6410中有一硬件逻辑来支持2000的闰年问题。因此S3C6410支持1901到2099年的范围。


读写操作:


在读BCD寄存器时,RTCCON寄存器0位必须至1,为了显示秒,分,小时,日,月,年,cpu必须从其对应的寄存器中取值(BCDSEC, BCDMIN, BCDHOUR,BCDDATE, BCDDAY, BCDMON, BCDYEAR)。多寄存器同时读取可能会产生1秒误差。例如用户从BCDMIN到BCDYEAR都进行了读,得到的结果为2059年12月31日23时59分,当读取这个结果时BCDSEC的数值在1~59之间,读到的2059年12月31日23时59分是没有问题的,但是当读取这个结果时BCDSEC的值为0,实际结果可能是2059年12月31日23时59分也可能是2060年1月1日0时0分。所以此时应重读这些寄存器,从而得到正确的数值。


后备电源操作:


实时时钟逻辑能被后备电源驱动,通过RTCVDD向RTC模块供电。当系统关闭时,cpu和RTC接口是封闭的,这时后备电源只驱动振荡电路和BCD计数器,从而把功耗降到最低。


逻辑图:


接口:




以下程序完成了时间设置获取,在lcd上显示功能,

源码如下

头文件:


[cpp] view plaincopyprint?


  • //RTC  
  • #define RTC_BASE    (0x7E005040)  
  • #define rRTCCON     (*(volatile unsigned *)RTC_BASE)  
  • #define rTICNT      (*(volatile unsigned *)(RTC_BASE + 0x4))  
  • #define rRTCALM     (*(volatile unsigned *)(RTC_BASE + 0x10))  
  • #define rALMSEC     (*(volatile unsigned *)(RTC_BASE + 0x14))  
  • #define rALMMIN     (*(volatile unsigned *)(RTC_BASE + 0x18))  
  • #define rALMHOUR    (*(volatile unsigned *)(RTC_BASE + 0x1c))  
  • #define rALMDATE    (*(volatile unsigned *)(RTC_BASE + 0x20))  
  • #define rALMMON     (*(volatile unsigned *)(RTC_BASE + 0x24))  
  • #define rALMYEAR    (*(volatile unsigned *)(RTC_BASE + 0x28))  
  • #define rBCDSEC     (*(volatile unsigned *)(RTC_BASE + 0x30))  
  • #define rBCDMIN     (*(volatile unsigned *)(RTC_BASE + 0x34))  
  • #define rBCDHOUR    (*(volatile unsigned *)(RTC_BASE + 0x38))  
  • #define rBCDDATE    (*(volatile unsigned *)(RTC_BASE + 0x3c))  
  • #define rBCDDAY     (*(volatile unsigned *)(RTC_BASE + 0x40))  
  • #define rBCDMON     (*(volatile unsigned *)(RTC_BASE + 0x44))  
  • #define rBCDYEAR    (*(volatile unsigned *)(RTC_BASE + 0x48))  
  • #define rCURTICNT   (*(volatile unsigned *)(RTC_BASE + 0x50))  
  • #define rINTP       (*(volatile unsigned *)(RTC_BASE - 0x10))  




初始化rtc:
[cpp] view plaincopyprint?


  • void init_rtc()  
  • {  
  •     rRTCCON = 0x85;  
  • }  


设置实时数据:

[cpp] view plaincopyprint?


  • void set_rtc()  
  • {  
  • //2012,04.14.13,06  
  •     rRTCCON |= 0x01;  
  •     rBCDSEC = 5*16 +1;  
  •     rBCDMIN = 6;  
  •     rBCDHOUR = 1*16 +3;  
  •     rBCDDATE = 1*16+4;  
  •     rBCDMON =4;  
  •     rBCDYEAR = 1*16+2;  
  •     rRTCCON &= ~(0x01);  
  • }  


获取实时数据:

[cpp] view plaincopyprint?


  • void get_rtc(unsigned char rtc_data[6])  
  • {  
  •   
  •     rRTCCON |= 0x01;  
  •     rtc_data[0] =rBCDSEC;  
  •     rtc_data[1] = rBCDMIN;  
  •     rtc_data[2] = rBCDHOUR;  
  •     rtc_data[3] = rBCDDATE;  
  •     rtc_data[4] = rBCDMON;  
  •     rtc_data[5] = rBCDYEAR;  
  •       
  •     rRTCCON &= ~(0x01);   
  •   
  •     if(rtc_data[0] == 0)  
  •     {  
  •     rRTCCON |= 0x01;  
  •     rtc_data[0] =rBCDSEC;  
  •     rtc_data[1] = rBCDMIN;  
  •     rtc_data[2] = rBCDHOUR;  
  •     rtc_data[3] = rBCDDATE;  
  •     rtc_data[4] = rBCDMON;  
  •     rtc_data[5] = rBCDYEAR;   
  •     rRTCCON &= ~(0x01);   
  •     }  
  •   
  • }  




mian:

[cpp] view plaincopyprint?


  • init_rtc();   
  • LCD_Init();  
  • Paint_background(0xffffff,0,0,480,272);  
  • set_rtc();  
  •   
  • while(1)  
  • {  
  •   
  • get_rtc(tmp_rtc);  
  • rtc_data_tmp[13] = tmp_rtc[0]%16;  
  • rtc_data_tmp[12] = tmp_rtc[0]/16;  
  •   
  • rtc_data_tmp[11] = tmp_rtc[1]%16;  
  • rtc_data_tmp[10] = tmp_rtc[1]/16;  
  •       
  • rtc_data_tmp[9] = tmp_rtc[2]%16;  
  • rtc_data_tmp[8] = tmp_rtc[2]/16;  
  •   
  • rtc_data_tmp[7] = tmp_rtc[3]%16;  
  • rtc_data_tmp[6] = tmp_rtc[3]/16;  
  •   
  • rtc_data_tmp[5] = tmp_rtc[4]%16;  
  • rtc_data_tmp[4] = tmp_rtc[4]/16;  
  •       
  • rtc_data_tmp[3] = tmp_rtc[5]%16;  
  • rtc_data_tmp[2] = tmp_rtc[5]/16;  
  •   
  • rtc_data_tmp[1] = tmp_rtc[6]%16;  
  • rtc_data_tmp[0] = tmp_rtc[6]/16;  
  •   
  • for(jj=0;jj<14;jj++)      
  • {  
  •     Paint_text(124+8*jj, 20, 0x0,charnum[rtc_data_tmp[jj]],8, 16);  
  • }  
  • delay_rtc();  
  •   
  • }  



程序下载地址:http://download.csdn.net/detail/muge0913/4225558

由于上传文件不及时显示,大家要程序的话,留下邮箱即可,

 
 
 

回复

445

帖子

0

TA的资源

纯净的硅(初级)

17
 
很好的资料哟
 
 
 

回复

910

帖子

656

TA的资源

五彩晶圆(初级)

18
 
 
个人签名天下难事,必做于易;天下大事,必做于细。
与其博览群书,不如精读一本。
 
 

回复

23

帖子

0

TA的资源

一粒金砂(初级)

19
 
顶一个,谢谢分享!
 
 
 

回复

3

帖子

0

TA的资源

一粒金砂(初级)

20
 
多谢楼主。。。。791044288@qq.com
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表