ARM定时器汇编代码.docx

上传人:b****2 文档编号:20694045 上传时间:2023-04-25 格式:DOCX 页数:59 大小:31.50KB
下载 相关 举报
ARM定时器汇编代码.docx_第1页
第1页 / 共59页
ARM定时器汇编代码.docx_第2页
第2页 / 共59页
ARM定时器汇编代码.docx_第3页
第3页 / 共59页
ARM定时器汇编代码.docx_第4页
第4页 / 共59页
ARM定时器汇编代码.docx_第5页
第5页 / 共59页
点击查看更多>>
下载资源
资源描述

ARM定时器汇编代码.docx

《ARM定时器汇编代码.docx》由会员分享,可在线阅读,更多相关《ARM定时器汇编代码.docx(59页珍藏版)》请在冰豆网上搜索。

ARM定时器汇编代码.docx

ARM定时器汇编代码

;

;BootloaderStage1的代码

;head.S

;====================================================================

;head.S(Stage1)程序流程说明

;

;0,开机启动,入口地址为0,转到启动开始处

;1,禁止看门狗定时器

;2,关闭所有中断

;3,初始化系统时钟,设置CPU工作频率

;4,初始化内存控制寄存器

;5,初始化堆栈

;6,将IsrIRQ标号的地址传给标号HandleIRQ指向的内存单元

;7,将NandFlash中的代码复制到SDRAM

;8,初始化数据区

;

;9,跳到SDRAM中执行

;中断向量:

;在0地址开始是8条跳转指令,占4*8=32字节;

;在SDRAM的最后256字节的开始,用4*8=32字节存放各种模式的服务子程序入口地址;

;然后用4*32个字节存放对应的IRQ中断服务子程序入口地址。

;当我们自己编写应用程序时,会用到这些地址。

;把我们自己写的中断服务子程序的开始地址送到这些单元中,

;当发生中断时才会执行我们编写的服务子程序。

;这些与广嵌提供的BIOS兼容。

;====================================================================

;main.c(Stage2)程序流程说明

;

;1,串口初始化

;2,校准延时

;3,点亮LED

;4,显示logo

;5,进入循环

;6,显示功能提示菜单

;7,等待按键,选择功能

;8,判断选择,如果有效,则执行相应程序

;9,输出空行进行显示分割

;10,回到循环开始

;

;可选择的功能有:

;1,通过串口下载文件到SDRAM

;2,将下载到SDRAM的文件写入NANDFlash。

;这些功能分别由不同的函数调用完成。

;1,下载文件,voidcomdownload(void),在comload.c中定义。

;2,写入NandFlash,voidNandWrite(void),在nand.c中定义。

;=====================================================================

;文件包含

GEToption.inc

GETmemcfg.inc

GET2410addr.inc

;=====================================================================

;importconfigconstants

;编译器定义符号引入,在后面程序中使用

IMPORT|Image$$RO$$Base|;BaseofROMcode

IMPORT|Image$$RO$$Limit|;EndofROMcode(=startofROMdata)

IMPORT|Image$$RW$$Base|;BaseofRAMtoinitialise

IMPORT|Image$$ZI$$Base|;Baseandlimitofarea

IMPORT|Image$$ZI$$Limit|;tozeroinitialise

;=====================================================================

;Pre-definedconstants

;定义符号常量,运行模式常数

USERMODEEQU0x10;用户模式

FIQMODEEQU0x11;FIQ模式

IRQMODEEQU0x12;IRQ模式

SVCMODEEQU0x13;管理模式

ABORTMODEEQU0x17;中止模式

UNDEFMODEEQU0x1b;未定义模式

MODEMASKEQU0x1f;模式屏蔽,与以上常数配合设置工作模式

NOINTEQU0xc0;中断屏蔽,屏蔽FIQ中断和IRQ中断

;=====================================================================

;Thelocationofstacks

;定义符号常量,表示各种工作模式下的堆栈开始地址

;_STACK_BASEADDRESSisdefinedinoption.incvalue=0x33ff8000

UserStackEQU(_STACK_BASEADDRESS-0x3800);0x33ff4800~用户模式

SVCStackEQU(_STACK_BASEADDRESS-0x2800);0x33ff5800~管理模式

UndefStackEQU(_STACK_BASEADDRESS-0x2400);0x33ff5c00~未定义模式

AbortStackEQU(_STACK_BASEADDRESS-0x2000);0x33ff6000~中止模式

IRQStackEQU(_STACK_BASEADDRESS-0x1000);0x33ff7000~IRQ模式

FIQStackEQU(_STACK_BASEADDRESS-0x0);0x33ff8000~FIQ模式

;系统模式没有考虑,没有使用

;=====================================================================

;gblsstring_1

downloadAddressequ0x30400000

filebufequ0x303fff00

;----------------------------------------------------------------------

;宏定义,重复使用,减轻编程负担

MACRO

$HandlerLabelHANDLER$HandleLabel

$HandlerLabel

subsp,sp,#4;decrementsp(tostorejumpaddress)

stmfdsp!

{r0}

;PUSHtheworkregistertostack

;(lrdoes'tpushbecauseitreturntooriginaladdress)

ldrr0,=$HandleLabel;loadtheaddressofHandleXXXtor0

ldrr0,[r0]

;loadthecontents(serviceroutinestartaddress)ofHandleXXX

strr0,[sp,#4];storethecontents(ISR)ofHandleXXXtostack

ldmfdsp!

{r0,pc};POPtheworkregisterandpc(jumptoISR)

MEND

;

;当产生IRQ中断时,PC先指向IRQ的中断入口0x18执行跳转到HandlerIRQ标号

;处。

假设SP=0x33ff8000,

;执行"subsp,sp,#4"后SP=0x33ff7ffc;

;

;"stmfdsp!

{r0}"指令的意义为SP先递减1(即减1个字,4字节)变成

;0x33fff7ff8,然后将r0的数据传给SP指向的地址,

;

;"ldrr0,=HandleIRQ"指令将标号HandleIRQ的地址(0x33ffff18)传给r0;

;

;"ldrr0,[r0]"指令将r0内容的内容传给r0,即将保存在表中的IsrIRQ

;标号的地址传给r0;

;

;

;"strr0,[sp,#4]"指令将r0值传给SP+4,即传给0x33ff7ff8,

;SP保持不变,此时0x33ff6ffc保存着中断处理函数的入口地址;

;"ldmfdsp!

{r8-r9,pc}"指令将SP指向的单元(0x33ff6ff4)的内容传给

;r8后递增1字,再将SP指向的单元(0x33ff6ff8)的内容传给r9后递增1字,

;再将SP指向的单元(0x33ff6ffc)的内容传给PC后增1字,

;此时SP=0x33ff7000,PC指向产生中断的中断源服务程序。

;====================================================================

;importMain;说明Main符号在其它文件中定义

;Main符号在Main.c中定义

;====================================================================

areaInit,code,readonly;声明代码段

entry;说明程序入口

start;标号

;=====================================================================

;设置中断向量表

bResetHandler;转到复位后开始执行的代码处

bHandlerUndef;handlerforUndefinedmode

bHandlerSWI;handlerforSWIinterrupt

bHandlerPabort;handlerforPAbort

bHandlerDabort;handlerforDAbort

b.;reserved

;bUart0RxInt;

;bIsrIRQ

bHandlerIRQ;handlerforIRQinterruptIRQ中断入口地址

bHandlerFIQ;handlerforFIQinterruptFIQ中断入口地址

;=====================================================================

;通过调用宏,编写中断服务子程序代码

HandlerFIQHANDLERHandleFIQ

;HandlerIRQHANDLERHandleIRQ

HandlerUndefHANDLERHandleUndef

HandlerSWIHANDLERHandleSWI

HandlerDabortHANDLERHandleDabort

HandlerPabortHANDLERHandlePabort

;---------------------------------------------------------------------

HandlerIRQ

;bIsrIRQ

;movr0,#'R'

;bluart_putch

;adrlr0,IsrIRQ

;adrlr0,Uart0RxInt

;movpc,r0

subsp,sp,#4;decrementsp(tostorejumpaddress)

stmfdsp!

{r0}

;PUSHtheworkregistertostack

;(lrdoes'tpushbecauseitreturntooriginal

;address)

ldrr0,=HandleIRQ;loadtheaddressofHandleXXXtor0

ldrr0,[r0]

;adrlr0,IsrIRQ;cannotldrr0,=IsrIRQ

;loadthecontents(serviceroutinestartaddress)

;ofHandleXXX

strr0,[sp,#4];storethecontents(ISR)ofHandleXXXtostack

ldmfdsp!

{r0,pc};POPtheworkregisterandpc(jumptoISR)

;=====================================================================

;以HandlerIRQHANDLERHandleIRQ为例,在汇编时,将展开形成如下代码

;

;HandlerIRQ;<===$HandlerLabel

;subsp,sp,#4;decrementsp(tostorejumpaddress)

;stmfdsp!

{r0}

;;sp先递减1(4字节),r0的内容存入sp指向的单元

;;PUSHtheworkregistertostack

;;(lrdoes'tpushbecauseitreturntooriginaladdress)

;ldrr0,=HandleIRQ;<==ldrr0,=$HandleLabel;loadtheaddressofHandleXXXtor0

;;HandleIRQ标号定义在RamData数据段

;;

;ldrr0,[r0]

;;loadthecontents(serviceroutinestartaddress)ofHandleXXX

;strr0,[sp,#4];storethecontents(ISR)ofHandleXXXtostack

;;r0中的值传送给sp+4指向的单元,sp的值不变。

;ldmfdsp!

{r0,pc};POPtheworkregisterandpc(jumptoISR)

;;

(1)先将sp指向的单元的内容传送给r0,sp递增1(4字节);

;;

(2)再将sp指向单元的内容传送给pc,sp递增1(4字节).

;=====================================================================

;IRQ中断服务子程序的入口,根据不同的IRQ中断,执行不同的IRQ服务子程序

;下面有代码将IsrIRQ标号的地址传给标号HandleIRQ指向的内存单元

;所以当发生IRQ中断时,HandlerIRQ程序会跳转到此处执行

IsrIRQ

;bUart0RxInt

;movr0,#'Q'

;bluart_putch

;subspc,lr,#4

subsp,sp,#4;reservedforPC

stmfdsp!

{r8-r9}

ldrr9,=INTOFFSET

ldrr9,[r9]

ldrr8,=HandleEINT0

addr8,r8,r9,lsl#2

ldrr8,[r8]

;adrlr8,Uart0RxInt;2013-9-15

strr8,[sp,#8]

ldmfdsp!

{r8-r9,pc}

;假设IRQ模式的SP=0x33ff7000,

;执行"subsp,sp,#4"后SP=0x33ff6ffc;

;

;"stmfdsp!

{r8-r9}"指令的意义为SP先递减1(即减1个字,4字节)变成

;0x33fff6ff8,然后将r9传给SP指向的地址,之后SP再递减,r8再传给SP指向

;地址,所以执行完该指令后,SP=0x33ff6ff4,0x33ff6ff8保存r9的内容,

;0x33ff6ff4保存r8的内容;

;

;"ldrr9,=INTOFFSET"指令将INTOFFSET寄存器地址传给r9;

;"ldrr9,[r9]"指令将r9的内容作为地址所指向的单元的内容传给r9,

;即将INTOFFSET寄存器的值传给r9;

;

;"ldrr8,=HandleEINT0"指令将中断服务程序入口地址表的HandleIRQ

;地址(0x33ffff20)传给r8;

;"addr8,r8,r9,lsl#2"指令将r9左移2位(即r9乘以4)再加上

;r8原先的内容再传给r8。

;这里r9左移2位是因为每个中断源在地址表中都占用4字节,而在INTOFFSET

;中的偏移量值只有1;

;"ldrr8,[r8]"指令将r8内容的内容传给r8,即将保存在表中的产生中断的

;中断源的中断处理函数入口地址传给r8;

;

;"strr8,[sp,#8]"指令将r8值传给SP+8,即传给0x33ff6ffc,

;SP保持不变,此时0x33ff6ffc保存着中断处理函数的入口地址;

;"ldmfdsp!

{r8-r9,pc}"指令将SP指向的单元(0x33ff6ff4)的内容传给

;r8后递增1字,再将SP指向的单元(0x33ff6ff8)的内容传给r9后递增1字,

;再将SP指向的单元(0x33ff6ffc)的内容传给PC后增1字,

;此时SP=0x33ff7000,PC指向产生中断的中断源服务程序。

;=====================================================================

;

;=================

;ENTRY

;复位后跳转到此处,执行复位程序

;=================

ResetHandler

;=====================================================================

;1关闭看门狗

ldrr0,=WTCON;watchdogdisable

ldrr1,=0x0

strr1,[r0]

;=====================================================================

;2关闭中断

ldrr0,=INTMSK

ldrr1,=0xffffffff;allinterruptdisable

strr1,[r0]

ldrr0,=INTSUBMSK

ldrr1,=0x3ff;allsubinterruptdisable

strr1,[r0]

;=====================================================================

;3初始化时钟系统

ldrr1,=LOCKTIME;0x4C000000;PLLlocktimecounter

ldrr2,=0x000FFFFF

strr2,[r1]

;ConfigureMPLL

;设置主频为约200MHz

ldrr0,=MPLLCON

ldrr1,=((0xa1<<12)+(0x03<<4)+1)

;Fin=12MHz,Fout=202.8MHz

;((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV);

strr1,[r0]

;设置FCLK:

HCLK:

PCLK=1:

2:

4

ldrr1,=CLKDIVN;0x4C000014;Clockdividercontrol

ldrr2,=0x3;FCLK:

HCLK:

PCLK=1:

2:

4

strr2,[r1]

;=====================================================================

;4初始化内存控制寄存器

;Setmemorycontrolregisters

[{true}

adrlr0,SMRDATA

;can'tuseldrr0,=xxxximportant!

!

!

;ADR伪指令,格式:

ADR{条件吗}寄存器组,标号

;标号:

非字对准地址-255~+255;字对准-1020~+1020

;生成ADD/SUBPC,#xx

;见符意德P68

ldrr1,=BWSCON;BWSCONAddress

addr2,r0,#52;EndaddressofSMRDATA

0

ldrr3,[r0],#4

strr3,[r1],#4

cmpr2,r0

bne%B0

]

;=====================================================================

;5,初始化堆栈

;Initializestacks

blInitStacks

;=====================================================================

;6,将IsrIRQ标号的地址传给标号HandleIRQ指向的内存单元

;SetupIRQhandler

ldrr0,=HandleIRQ

adrlr1,IsrIRQ;cannotldrr1,=IsrIRQ

strr1,[r0]

;Thisroutineisneededifthereisn't;'subspc,lr,#4'at0x18,0x1c

;=====================================================================

;7,将NandFlash中的代码复制到

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

当前位置:首页 > PPT模板 > 其它模板

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

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