ARM课件S3C2440A.docx
- 文档编号:25574744
- 上传时间:2023-06-09
- 格式:DOCX
- 页数:19
- 大小:632.27KB
ARM课件S3C2440A.docx
《ARM课件S3C2440A.docx》由会员分享,可在线阅读,更多相关《ARM课件S3C2440A.docx(19页珍藏版)》请在冰豆网上搜索。
ARM课件S3C2440A
以下程序在Keil4中建立项目,芯片选S3C2410A
无论是S3C2410A还是S3C2440A,其IO口B都是11位二进制数,xxx xxxxxxxx,现在控制第5、6、7、8为做输出点亮LED灯(共阳极,输出0点亮),即xx8 765x xxxx,
GPBCON equ 0x56000010
GPBDAT equ 0x56000014
GPBUP equ 0x56000018
xportxmain
areaInit,code,readonly
entry
export
xmain
ldrr0,=GPBCON
ldrr1,[r0]
bicr1,#0x3fC00 ;r1=xx00000000xxxxxxxxxx
orrr1,#0x15400 ;r1=xx01010101xxxxxxxxxx
strr1,[r0] ;r1传给GPBCON设置8765位为输出
ldrr0,=GPBUP
ldrr1,[r0]
orrr1,#0x1e0 ;r1=xx1111xxxxx
strr1,[r0] ;开B口第8、7、6、5位上拉电阻
ldrr0,=GPBDAT
ldrr2,[r0] ;把B口最初状态保存在R2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LOOP drr1,[r2]
orrr1,#0x1c0
strr1,[r0]
bl delay
;BL跳转时将PC+4值自动保存在R14即LR中,也就是将程序的下一个语句地址保存在lr中在跳
;转后执行mov pc,lr相当于返回,这样BL相当于调用子程序,pc=lr相当于子程序返回
;;;;;;;;;;;;;;;;;;
drr1,[r2]
orrr1,#0x1a0
strr1,[r0]
bl delay
;;;;;;;;;;;;;;;;;;;;;
ldrr1,[r2]
orrr1,#0x160
strr1,[r0]
bl delay
;;;;;;;;;;;;;;;;;;;;;;;;
ldrr1,[r2]
orrr1,#0x0e0
strr1,[r0]
bl delay
;;;;;;;;;;;;;;;;;;;;;;;;
bLOOP
delay
movr3,#3
delay1 subr3,r3,#1
cmpr3,#0x0
bnedelay1
movpc,lr ;这句相当于子程序返回语句
end
1.A(*(volatileunsigned*)0x56000010)的意思是把0x48000000强制转换成volatileunsignedlong类型的指针,暂记为p,那么就是#defineA*p,即A为P指针指向位置的内容了。
这里就是通过内存寻址访问到寄存器A,可以读/写操作。
*(volatileunsigned*)0×48000080含义:
因为()优先级高于*,所以先执行(volatileunsigned*)0×48000080这个表示将0×48000080强制转化为指针类型,指针指向的类型是unsigned,指针存放的地址为0×56000080。
也就是说指针指向寄存器A。
然后在执行()外面的*,表示取出指针所指向的值。
2.在ADS1.2中,可以先添加头文件,再调用。
调用头文件时,由于2440addr.h头文件在调用了option.h头文件的内容,而option.h头文件在有调用了def.h,所以,这三个头文件需要同时调用。
在利用厂家提供的资料制作自己的头文件也用注意这种情况!
在keil4中进行时,Keil4已经预装了一些许可芯片的头文件,可以直接调用芯片型号的头文件,如S3C2440芯片,可直接调用#include“S3C2440.h"、如S3C2410芯片,可直接调用#include"S3C2410.h",也可以新建头文件,把下面的内容复制进响应的头文件文本文件中,保存,再在C语言程序中调用这些头文件。
#include"option.h"
#include
#include
#include"def.h"
#include"2440addr.h"
3.2440addr.h定义了ARM内所有寄存器的名称,如A~F等多个IO口的控制寄存器名称;option定义了时钟的设置等功能;def.h定义了几个特殊字长名称,如U32为unsignedint(无符号长整型)、U16为unsignedshort(短整形),S32为int型(有符号整型),S16为shortint,U8为unsignedchar,S8为char等
4.ARM开发不会都用汇编语言或C语言单独完成,往往是两者配合使用,一般用汇编编写初始化文件,设置程序入口(根据硬件状况设置),再用C语言编写开发程序。
如
IMPORTxMain ;相当于设置主函数入口,C语言的主函数就必须用xMain(),不能用main()
AREA Init,CODE,READONLY
ENTRY
LDRR0,=0x3FF0000 ;LDR也是一种赋值语句,相当于MOV,不同是LDR的数前是=,mov的数前是#
BICR1,R1,#0xF80 ;给立即数0xF8(即11111000)取反,再与R1与运算,结果是立即数为1的位对应的R1位全为0;
STRR1,[R0]
LDRSP,=0x3FE1000
BLxMain
B . ;注意B后有个点
END
#definerGPBCON (*(volatileunsigned*)0x56000010)//PortBcontrol
#definerGPBDAT (*(volatileunsigned*)0x56000014)//PortBdata
#definerGPBUP (*(volatileunsigned*)0x56000018)//Pull-upcontrolB
//定义了各个特殊功能寄存器地址和名称,要使用必须调用该头文件
/*===如果不调用该头文件,必须把要使用的定义名称和地址语句在主程序前声明
#definerGPBCON (*(volatileunsigned*)0x56000010)//PortBcontrol
#definerGPBDAT (*(volatileunsigned*)0x56000014)//PortBdata
#definerGPBUP (*(volatileunsigned*)0x56000018)//Pull-upcontrol*/
/* 自定义简单延迟程序 */
intdelay(inttimes)
{
inti;
for(i=0;i return0; } /* 主程序 */ voidxMain(void) //主函数名称与主函数入口地址对应,在上面汇编Init.s中有定义 { //不能随意写成main,或者Main等,要查看或编写init.s文件(见下图) rGPBCON|=0x3fc00; //GPB5-8 ableoutput rGPBCON&=0x15400; //GPBCON两位管理GPBDAT的方向(见下面对应关系,00-in,01-out,10-other,11-无用); / /方向控制GPBCON d21d20d19d18d17d16 d15d14d13d12 d11d10d9d8d7d6d5d4d3d2 d1d0 //输入输出sfrGPDAT d10 d9 d8 d7 d6 d5 d4 d3 d2 d1 d0 rGPBUP |=0x1e0; //disableGPB5-8pullupres,GPBUP一位管一位,0-链接上拉电阻,1-关闭上拉电祖 while (1) { rGPBDAT|=0x1e0;//GPB7output0 rGPBDAT&=0xeff; delay(50000000);//调用汇编语言编写的延时程序 rGPBDAT|=0x1e0;//GPB7output0 rGPBDAT&=0xf7f; delay(50000000);//调用汇编语言编写的延时程序 rGPBDAT|=0x1e0;//GPB7output0 rGPBDAT&=0xfbf; delay(50000000);//调用汇编语言编写的延时程序 rGPBDAT|=0x1e0;//GPB7output0 rGPBDAT&=0xfdf; delay(50000000);//调用汇编语言编写的延时程序 } } ARM汇编程序基本知识 1.汇编程序的基本组成 ARM汇编语言程序中,程序是以程序段为单位组织代码的。 段是相对独立的指令或者代码序列,拥有特定的名称。 段的种类有代码段、数据段和通用段,代码段的内容为执行代码,数据段存放代码运行时需要用到的数据,通用段不包含用户代码和数据,所有通用段共用一个空间。 段使用AREA伪操作来定义,并且说明相关属性,如 代码段定义 AREAInit,CODE,READONLY … 数据段定义 AREAStack1,DATA,READWRITE,NOINIT,ALIGN=3 …… ;GPIO寄存器宏定义 GPBCON EQU 0x56000010 GPBDAT EQU 0x56000014 GPBUP EQU 0x56000018 EXPORTxmain AREA LEDTESTh,CODE,READONLY ENTRY xmain ldr r0,=GPBCON ldr r1,[r0] bic r1,r1,#0x3fc00 orr r1,r1,#0x15400 str r1,[r0] ldr r0,=GPBUP ldr r1,[r0] orr r1,r1,#0x1e0 str r1,[r0] looptest ldr r2,=GPBDAT ldr r3,[r2] bic r3,r3,#0x1e0 orr r3,r3,#0xF0 str r3,[r2] ldrr0,=0x2ffffff bl delay ldr r3,[r2] bic r3,r3,#0x1e0 orr r3,r3,#0x1e0 str r3,[r2] ldrr0,=0x2ffffff bl delay blooptest delay subr0,r0,#1 cmpr0,#0x0 bnedelay ldrpc,=looptest END 一个汇编程序至少应该有一个代码段,可以有零或者多个数据段。 在格式上,一个汇编程序需要至少有一个ENTRY,ENTRY是程序代码段的入口,还需要在汇编源文件结束处,写上END表示该源文件的结束。 如一个基本的汇编源程序,虽然汇编语言大小写部分,但关键字要么都用大写要么都用小写,不能大小写混用! 如MOV和mov都正确,但Mov错误! ! ! AREAlaoyu,CODE,READONLY ENTRY CODE32 ADR r0,start+1 BX r0 CODE16 start movr0,#10 ;start为语句标号,必须写在每行的开头,前面不能有空格,用空格和语句分开 MOVr1,#3 BLdoadd stopmovr0,#0x18 ;stop为语句标号,必须写在每行的开头,前面不能有空格,用空格和语句分开 LDRr1,=0x20026 ;语句中的=是LDR伪指令和机器指令的区别符号 SWI0xAB doaddADDr0,r0,r1 ;doadd为语句标号,必须写在每行的开头,前面不能有空格,用空格和语句分开 MOVpc,lr END 当汇编程序较长时,可以分割为多个代码段和多个数据段,多个段在程序编译链接时,最终形成一个可执行的映像文件。 一个可执行映像文件通常由以下几部分组成 一个或者多个代码段,代码段属性为只读(只读数据也放在代码段? RO) 零个或者多个初始化数据的数据段,可读写(存放初始化了的变量数据,RW) 零个或者多个不包含初始化数据的数据段,可读写(所有未初始化的变量,也就是ZI) 链接器根据系统默认或者用户设定的规则,将各段安排在存储器中的相应位置,因此源程序中段之间的相对位置与可执行映像文件中的段的相对位置一般不会相同。 #include"ARMyehad.h" #include"option.h" #include"def.h" voiddelay(U16us) { while(us--); } voidxmain() { rGPBCON=0x55aa; rGPBDAT=0x7fff; } 2.汇编语句应该注意的地方 汇编语句格式 [LABEL]OPERATION,[OPERAND],[;COMMENT] LABEL必须在一行的开头写。 OPERATION包括指令、伪操作、宏指令或伪指令。 每一条操作助记符必须全部大写或者全部小写。 在写操作助记符前,必须有空格。 OPERAND表示操作的对象,可以使常量、变量、标号、寄存器或者表达式,不同的对象之间必须用逗号分开。 例子: AREAEX2,CODE,READONLY;操作助记符前面必须有空格 GBLADATA;操作助记符前面必须有空格 DATA SETA,0x20;变量名DATA前面不能留空格 ADDR0,R1,R2 ADDR0,R1,r2 addR0,R1,r2 AddR0,R1,r2;寄存器小写正确,指令助记符大小写混合错误 3.常用符号 汇编语言中,经常使用各种符号表示变量、常量和地址。 变量的定义: 使用伪操作GBLA、GBLL、GBLS,分别是定义全局的数值变量、逻辑变量和字符变量;LCLA、LCLL、LCLS定义局部的数值变量、逻辑变量和字符变量。 相应的变量使用SETA、SETL、SETS来进行赋值。 注意字符串长度不应超过512个字节。 例子: GBLADATA DATA SETA0x20 LCLSstr1 str1SETS“PEN” LCLLlc lcSETL{TRUE} 常量是在运行过程中不能改变的量。 ARM支持数值常量、逻辑常量和字符串常量。 汇编中使用EQU来定义一个数值常量,如 TestEQU10;定义标号Test的值为20. AddrEQU0x55,CODE32; 关于EQU的具体使用,看伪操作EQU。 数值常量一般为32为的整数,可以使十进制、十六进制,也可以是n进制(n=2~9)如8_247是一个八进制数。 4.常见的伪操作符 符号定义伪操作 GBLA、GBLL、GBLS LCLA、LCLL、LCLS SETA、SETL、SETS RLIST 其中RLIST用来定义通用寄存器列表名称,使用该伪操作定义的名称可以在ARM指令LDM/STM中使用。 在LDM/STM中,访问列表中的寄存器次序为寄存器编号由低到高的顺序。 如 RegListRLIST{r0-r5,r8,r10};将寄存器列表名称定义为RegList 在程序中使用 STMFDSP! RegList;存储列表到堆栈 LDMIAR5,RegList;加载列表 数据定义伪操作 DCB分配一片连续的字节存储单元并初始化 DCW(DCWU)分配一片连续的半字存储单元并初始化 DCD(DCDU)分配一片连续的字存储单元并初始化 DCDO、DCI、DCQ(DCQU) DCFS(DCFSU)为单精度浮点数分配一片连续的字存储单元并初始化 DCFD(DCFDU)为双精度浮点数分配一片连续的字存储单元并初始化 SPACE分配一片连续的存储单元 FIELD、MAP、LTORG 如: StrDCB“thisisatest”;分配一片连续的字节存储单元并初始化 DataDCW1,2,3;分配一片连续的半字存储单元并初始化 DataDCD4,5,6;分配一片连续的字存储单元并初始化 FdataDCFS2e5,-5e-7;分配一片连续的字存储单元并初始化为指定的单精度数 DspceSPACE100;分配连续100字节的存储单元并初始化为0 控制伪操作 IFELSEENDIF WHILEWEND MACROMEND;MEXIT 信息报告伪操作 ASSERT INFO OPT 其他常用伪操作 AREAALIGNCODE16/CODE32ENTRYENDEQUEXPORT(GLOBLE)IMPORTEXTERNGET(INCLUDE)INCBINRNROUT AREA 格式: AREA段名属性1,属性2,…… 常用属性有: CODE: 用于定义代码段,默认为READONLY DATA: 定义数据段,默认为READWRITE READONLY: 指定本段为只读 READWRITE: 指定本段为读写 ALIGN: 使用方式为ALIGN表达式。 在默认时,ELF(可执行链接文件)的代码段和数据段是按字对齐的。 表达式的取值范围为0~31,相应的对齐方式为2次幂。 COMMON: 定义一个通用的段,不包含任何用户的代码和数据。 各源文件中同名的COMMON段共享同一段存储单元。 ALIGN 格式: ALIGN[表达式[,偏移量]] ALIGN伪操作可通过添加填充字节的方式,使当前位置满足一定的对齐方式。 例: …… DATA1 DCB“STRIN”;定义后不能保证地址对齐 ALIGN4;确保当前地址是4字节对齐 …… 例: AREACache,CODE,ALIGN=3;指定本代码段的指令时23=8字节对齐的 …… MOVPC,LR;程序跳转后是4字节对齐,返回后需要继续8字节对齐 ALIGN8;当前位置再次满足8字节对齐 …… 注意上面,在AREA中使用和单独使用ALIGN的区别,格式和计算方式不一样。 ENTRY 用于指定汇编程序的入口点。 一个程序可以由一个或者多个源文件组成,一个源文件由一个或者多个程序段组成。 一个程序至少有一个入口点,也可有多个入口点,但是在一个源文件中,最多只能有一个ENTRY。 当有多个ENTRY时,程序的真正入口点由链接器指定。 编译程序在编译连接时根据程序入口点进行连接。 在只有一个入口点时,编译程序会把这个入口点的地址定义为系统
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- ARM 课件 S3C2440A