嵌入式系统设计与应用 课件 第3、4章 ARM指令集、S5PV210微处理器与接口_第1页
嵌入式系统设计与应用 课件 第3、4章 ARM指令集、S5PV210微处理器与接口_第2页
嵌入式系统设计与应用 课件 第3、4章 ARM指令集、S5PV210微处理器与接口_第3页
嵌入式系统设计与应用 课件 第3、4章 ARM指令集、S5PV210微处理器与接口_第4页
嵌入式系统设计与应用 课件 第3、4章 ARM指令集、S5PV210微处理器与接口_第5页
已阅读5页,还剩154页未读 继续免费阅读

下载本文档

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

文档简介

第3章ARM指令集目录3.1ARM指令集概述3.2ARM指令的寻址方式3.3ARM指令简介3.4Thumb指令简介3.5ARM汇编语言简介3.6C语言与汇编语言的混合编程3.7本章小结在嵌入式系统开发中,目前最常用的编程语言是汇编语言和C语言。在较复杂的嵌入式软件中,由于C语言编写程序较方便,结构清晰,而且有大量支持库,所以大部分代码采用C语言编写,特别是基于操作系统的应用程序设计。但是在系统初始化、BootLoadr、中断处理等,对时间和效率要求较严格的地方仍旧要使用汇编语言来编写相应代码块。本章将介绍ARM指令集指令及汇编语言的相关知识。

ARM指令集概述PartOne3.1ARM处理器的指令集主要有:ARM指令集,是ARM处理器的原生32位指令集,所有指令长度都是32位,以字对齐(4字节边界对齐)方式存储;该指令集效率高,但是代码密度较低。Thumb指令集是16位指令集,2字节边界对齐,是ARM指令集的子集;在具有较高代码密度的同时,仍然保持ARM的大多数性能优势。Thumb-2指令集是对Thumb指令集的扩展,提供了几乎与ARM指令集完全相同的功能,同时具有16位和32位指令,既继承了Thumb指令集的高代码密度,又能实现ARM指令集的高性能;2字节边界对齐,16位和32位指令可自由混合。Thumb-2EE指令集是Thumb-2指令集的一个变体,用于动态产生的代码;不能与ARM指令集和Thumb指令集交织在一起。除了上面介绍的指令集外,ARM处理器还有针对协处理器的扩展指令集,如普通协处理器指令、NEON和VFP扩展指令集、无线MMX技术扩展指令集等。3.1.1指令格式ARM指令集的指令基本格式如下:<opcode>{<cond>}{S}<Rd>,<Rn>,<shift_operand>指令中“<>”内的项是必需的,“{}”内的项是可选的。符号说明opcode操作码,即指令助记符,如MOV、SUB、LDR等cond条件码,描述指令执行的条件S可选后缀,指令后加上“S”,指令执行成功完成后自动更新CPSR寄存器中的条件标志位Rd目的寄存器Rn存放第1个操作数的寄存器shift_operand第2个操作数,可以是寄存器、立即数等ARM指令集中几乎每条指令都可以是条件执行的,由cond可选条件码来决定,位于ARM指令的最高4位[31:28],可使用的条件码如表3-2所示。每种条件码的助记符由两个英文符号表示,在指令助记符的后面和指令同时执行。根据程序状态寄存器CPSR中的条件标志位[31:28]判断当前条件是否满足,若满足则执行指令。若指令中有后缀S,则根据执行结果更新程序状态寄存器CPSR中的条件标志位[31:28]。3.1.2

指令的条件码指令条件码助记符CPSR条件标志位值含义0000EQZ=1相等0001NEZ=0不相等0010CS/HSC=1无符号数大于或等于0011CC/LOC=0无符号数小于0100MIN=1负数0101PLN=0正数或零0110VSV=1溢出0111VCV=0没有溢出1000HIC=1,Z=0无符号数大于1001LSC=0,Z=1无符号数小于或等于1010GEN=V有符号数大于或等于

1011LTN!=V有符号数小于

1100GTZ=0,N=V有符号数大于

1101LEZ=1,N!=V有符号数小于或等于

1110AL任何无条件执行(指令默认条件)1111NV任何从不执行(不要执行)

ARM指令的寻址方式PartTwo3.2寻址方式是指处理器根据指令中给出的地址信息,找出操作数所存放的物理地址,实现对操作数的访问。根据指令中给出的操作数的不同形式,ARM指令系统支持的寻址方式有:立即寻址、寄存器寻址、寄存器间接寻址、寄存器移位寻址、变址寻址、多寄存器寻址、堆栈寻址、块复制寻址和相对寻址等。ARM指令集与Thumb指令集的关系Thumb指令集具有灵活、小巧的特点ARM指令集支持ARM核所有的特性,具有高效、快速的特点

操作数的值在寄存器中,指令中的地址码字段指出的是寄存器编号,指令执行时直接取出寄存器值来操作。寄存器寻址指令举例如下:MOVR1,R2 ;将R2的值存入R1SUBR0,R1,R2;将R1的值减去R2的值,结果保存到R0

0xAA0x55R2R1寻址方式分类——寄存器寻址MOVR1,R20xAA

立即寻址指令中的操作码字段后面的地址码部分即是操作数本身,也就是说,数据就包含在指令当中,取出指令也就取出了可以立即使用的操作数(这样的数称为立即数)。立即寻址指令举例如下:SUBS R0,R0,#1;R0减1,结果放入R0,并且影响标志位MOV R0,#0xFF000;将立即数0xFF000装入R0寄存器

0x55R0MOVR0,#0xFF00程序存储寻址方式分类——立即寻址MOVR0,#0xFF000xFF00从代码中获得数据

寄存器移位寻址是ARM指令集特有的寻址方式。当第2个操作数是寄存器移位方式时,第2个寄存器操作数在与第1个操作数结合之前,选择进行移位操作。寄存器移位寻址指令举例如下:MOV R0,R2,LSL#3

;R2的值左移3位,结果放入R0, ;即是R0=R2×8ANDS R1,R1,R2,LSLR3

;R2的值左移R3位,然后和R1相 ;“与”操作,结果放入R10x55R0R20x01寻址方式分类——寄存器偏移寻址(寄存器移位寻址)MOVR0,R2,LSL#30x080x08逻辑左移3位

寄存器间接寻址指令中的地址码给出的是一个通用寄存器的编号,所需的操作数保存在寄存器指定地址的存储单元中,即寄存器为操作数的地址指针。寄存器间接寻址指令举例如下:LDR R1,[R2] ;将R2指向的存储单元的数据读出

;保存在R1中SWP R1,R1,[R2] ;将寄存器R1的值和R2指定的存储

;单元的内容交换0x55R0R20x400000000xAA0x40000000寻址方式分类——寄存器间接寻址LDRR1,[R2]0xAA

基址寻址就是将基址寄存器的内容与指令中给出的偏移量相加,形成操作数的有效地址。基址寻址用于访问基址附近的存储单元,常用于查表、数组操作、功能部件寄存器访问等。基址寻址指令举例如下:LDR R2,[R3,#0x0C] ;读取R3+0x0C地址上的存储单元

;的内容,放入R2STR R1,[R0,#-4]! ;先R0=R0-4,然后把R1的值寄存

;到保存到R0指定的存储单元寻址方式分类——基址(变址)寻址0x55R2R30x400000000xAA0x4000000CLDRR2,[R3,#0x0C]0xAA将R3+0x0C作为地址装载数据

多寄存器寻址一次可传送几个寄存器值,允许一条指令传送16个寄存器的任何子集或所有寄存器。多寄存器寻址指令举例如下:LDMIA R1!,{R2-R7,R12};将R1指向的单元中的数据读出到

;R2~R7、R12中(R1自动加1)STMIA R0!,{R2-R7,R12};将寄存器R2~R7、R12的值保

;存到R0指向的存储;单元中

;(R0自动加1)0x40000000R1R20x??0x010x400000000x??R3R40x??R60x??0x020x030x040x400000040x400000080x4000000C存储器寻址方式分类——多寄存器寻址LDRR1!,{R2-R4,R6}0x010x020x030x040x40000010堆栈是一个按特定顺序进行存取的存储区,操作顺序为“后进先出”。堆栈寻址是隐含的,它使用一个专门的寄存器(堆栈指针)指向一块存储区域(堆栈),指针所指向的存储单元即是堆栈的栈顶。存储器堆栈可分为两种:向上生长:向高地址方向生长,称为递增堆栈向下生长:向低地址方向生长,称为递减堆栈寻址方式分类——堆栈寻址寻址方式分类——堆栈寻址栈底栈顶栈区SP

堆栈存储区栈顶栈底栈区

SP向下增长向上增长0x123456780x12345678堆栈压栈堆栈压栈栈顶SP

栈顶SP

栈底空堆栈栈底满堆栈堆栈指针指向最后压入的堆栈的有效数据项,称为满堆栈;堆栈指针指向下一个待压入数据的空位置,称为空堆栈。寻址方式分类——堆栈寻址0x123456780x12345678栈顶SP

0x12345678栈顶SP

压栈压栈所以可以组合出四种类型的堆栈方式:满递增:堆栈向上增长,堆栈指针指向内含有效数据项的最高地址。指令如LDMFA、STMFA等;空递增:堆栈向上增长,堆栈指针指向堆栈上的第一个空位置。指令如LDMEA、STMEA等;满递减:堆栈向下增长,堆栈指针指向内含有效数据项的最低地址。指令如LDMFD、STMFD等;空递减:堆栈向下增长,堆栈指针向堆栈下的第一个空位置。指令如LDMED、STMED等。寻址方式分类——堆栈寻址

多寄存器传送指令用于将一块数据从存储器的某一位置拷贝到另一位置。如:STMIA R0!,{R1-R7} ;将R1~R7的数据保存到存储器中。

;存储指针在保存第一个值之后增加,

;增长方向为向上增长。STMIB R0!,{R1-R7} ;将R1~R7的数据保存到存储器中。

;存储指针在保存第一个值之前增加,

;增长方向为向上增长。寻址方式分类——块拷贝寻址

相对寻址是基址寻址的一种变通。由程序计数器PC提供基准地址,指令中的地址码字段作为偏移量,两者相加后得到的地址即为操作数的有效地址。相对寻址指令举例如下:

BL SUBR1 ;调用到SUBR1子程序

BEQ LOOP ;条件跳转到LOOP标号处

...LOOP MOV R6,#1 ...SUBR1 ...寻址方式分类——相对寻址简单的ARM程序;文件名:TEST1.S

;功能:实现两个寄存器相加;说明:使用ARMulate软件仿真调试

AREA Example1,CODE,READONLY ;声明代码段Example1 ENTRY ;标识程序入口

CODE32 ;声明32位ARM指令START MOV R0,#0 ;设置参数

MOV R1,#10LOOP BL ADD_SUB ;调用子程序ADD_SUB B LOOP ;跳转到LOOPADD_SUB

ADDS R0,R0,R1 ;R0=R0+R1 MOV PC,LR ;子程序返回

END ;文件结束使用“;”进行注释标号顶格写实际代码段声明文件结束简单的ARM程序;文件名:TEST1.S

;功能:实现两个寄存器相加;说明:使用ARMulate软件仿真调试

AREA Example1,CODE,READONLY ;声明代码段Example1 ENTRY ;标识程序入口

CODE32 ;声明32位ARM指令START MOV R0,#0 ;设置参数

MOV R1,#10LOOP BL ADD_SUB ;调用子程序ADD_SUB B LOOP ;跳转到LOOPADD_SUB

ADDS R0,R0,R1 ;R0=R0+R1 MOV PC,LR ;子程序返回

END ;文件结束

ARM指令简介PartThree3.3ARM指令集主要有:跳转指令、数据处理指令、程序状态寄存器处理指令、加载/存储指令、协处理器指令和异常产生指令六大类。ARM指令集是加载/存储型的,指令的操作数都存储在寄存器中,处理结果直接放入到目的寄存器中。采用专门的加载/存储指令来访问系统存储器。3.3.1

跳转指令跳转指令用于实现程序流程的跳转。在ARM程序中有两种方式可以实现程序流程的跳转:直接向程序计数器PC中写入跳转地址,可以实现4G地址空间内的任意跳转。例如:LDR PC,[PC,#+0x00FF] ;PC←[PC+8+0x00FF]使用专门的跳转指令。ARM指令集中的跳转指令可以完成从当前指令向前或向后的32MB地址空间的跳转。跳转指令有:B WAITA ;无条件跳转到标号WAITA处执行B 0x1234 ;跳转到绝对地址0x1234处1.B指令:B{条件}目标地址跳转指令B是最简单的跳转指令,跳转到给定的目标地址,从那里继续执行。示例:BL FUNC1 ;将当前PC值保存到R14中,然后跳转到标号FUNC1处执行2.BL指令BL{条件}目标地址用于子程序调用,在跳转之前,将下一条指令的地址复制到链接寄存器R14(LR)中,然后跳转到指定地址执行。示例:BLX FUNC1 ;将当前PC值保存到R14中,然后跳转到标号FUNC1处执行,;并切换到Thumb状态BLX R0 ;将当前PC值保存到R14中,然后跳转R0中的地址处执行,;并切换到Thumb状态3.BLX指令BLX{条件}目标地址BLX指令从ARM指令集跳转到指定地址执行,并将处理器的工作状态由ARM状态切换到Thumb状态,同时将PC值保存到链接寄存器R14中。示例:BXR0 ;跳转R0中的地址处执行,如果R0[0]=1,切换到Thumb状态4.BX指令BX{条件}目标地址带状态切换的跳转指令,跳转到指定地址执行。若目标地址寄存器的位[0]为1,处理器的工作状态切换为Thumb状态,同时将CPSR中的T标志位置1,目标地址寄存器的位[31:1]复制到PC中;若目标地址寄存器的位[0]为0,处理器的工作状态切换为ARM状态,同时将CPSR中的T标志位清0,目标地址寄存器的位[31:1]复制到PC中。示例:3.3.2

数据处理指令数据传输指令主要完成寄存器中数据的各种运算操作。数据处理指令的使用原则:所有操作数都是32位,可以是寄存器或立即数。如果数据操作有结果,结果也为32位,放在目的寄存器中。指令使用“两操作数”或“三操作数”方式,即每一个操作数寄存器和目的寄存器分别指定。数据处理指令只能对寄存器的内容进行操作。指令后都可以选择S后缀来影响标志位。比较指令不需要后缀S,这些指令执行后都会影响标志位。MOVR0,#0x01 ;将立即数0x01装入到R0MOVR0,R1 ;将寄存器R1的值传送到R0MOVSR0,R1,LSL#3 ;将寄存器R1的值左移3位后传送到R0,并影响标志位MOVPC,LR ;将链接寄存器LR的值传送到PC中,用于子程序返回1.MOV指令MOV{条件}{S}目的寄存器,源操作数MOV指令将一个立即数、一个寄存器或被移位的寄存器传送到目的寄存器中。后缀S表示指令的操作是否影响标志位。如果目的寄存器是寄存器PC可以实现程序流程的跳转;寄存器PC做为目的寄存器且后缀S被设置,则在跳转的同时,将当前处理器工作模式下的SPSR值复制到CPSR中。示例:MVNR0,#0x0FF ;将立即数0xFF按位求反后装入R0,操作后R0=0xFFFFFF00MVNR0,R1 ;将寄存器R1的值按位求反后传送到R02.MVN指令MVN{条件}{S}目的寄存器,源操作数MVN指令将一个立即数、一个寄存器或被移位的寄存器的值先按位求反,再传送到目的寄存器中。后缀S表示是否影响标志位。示例:ADDR0,R0,#1 ;R0=R0+1ADDR0,R1,R2 ;R0=R1+R2ADDR0,R1,R2,LSL#3;R0=R1+(R2<<3)3.ADD指令ADD{条件}{S}目的寄存器,操作数1,操作数2ADD指令将两个操作数相加后,结果放入目的寄存器中。同时根据操作的结果影响标志位。示例:SUBR0,R0,#1 ;R0=R0-1SUBR0,R1,R2 ;R0=R1-R2SUBR0,R1,R2,LSL#3 ;R0=R1-(R2<<3)4.SUB指令SUB{条件}{S}目的寄存器,操作数1,操作数2SUB指令用于把操作数1减去操作数2,将结果放入目的寄存器中。同时根据操作的结果影响标志位。示例:RSBR0,R0,#0xFFFF ;R0=0xFFFF-R0RSBR0,R1,R2 ;R0=R2–R15.RSB指令RSB{条件}{S}目的寄存器,操作数1,操作数2RSB指令称为逆向减法指令,用于把操作数2减去操作数1,将结果放入目的寄存器中。同时根据操作的结果影响标志位。示例:ADDSR0,R0,R2ADCR1,R1,R3;用于64位数据加法,(R1,R0)=(R1,R0)+(R3,R2)6.ADC指令ADC{条件}{S}目的寄存器,操作数1,操作数2ADC指令将两个操作数相加后,再加上CPSR中的C标志位的值,将结果放入目的寄存器中。同时根据操作的结果影响标志位。示例:SUBSR0,R0,R2SBCR1,R1,R3;用于64位数据减法,(R1,R0)=(R1,R0)-(R3,R2)7.SBC指令SBC{条件}{S}目的寄存器,操作数1,操作数2SBC指令用于操作数1减去操作数2,再减去CPSR中的C标志位值的反码,将结果放入目的寄存器中。同时根据操作的结果影响标志位。示例:RSBSR2,R0,#0RSCR3,R1,#0 ;用于求64位数据的负数RSCR0,R1,R2 ;R0=R2–R1-!C8.RSC指令RSC{条件}{S}目的寄存器,操作数1,操作数2RSC指令用于操作数2减去操作数1,再减去CPSR中的C标志位值的反码,将结果放入目的寄存器中。同时根据操作的结果影响标志位。示例:ANDR0,R1,R2 ;R0=R1&R2ANDR0,R0,#3 ;R0的位0和位1不变,其余位清09.AND指令AND{条件}{S}目的寄存器,操作数1,操作数2AND指令实现两个操作数的逻辑与操作,将结果放入目的寄存器中。同时根据操作的结果影响标志位。常用于将操作数某些位清0。示例:ORRR0,R0,#3 ;R0的位0和位1置1,其余位不变10.ORR指令ORR{条件}{S}目的寄存器,操作数1,操作数2ORR指令实现两个操作数的逻辑或操作,将结果放入目的寄存器中。同时根据操作的结果影响标志位。常用于将操作数某些位置1。示例: EORR0,R0,#0F ;R0的低4位取反11.EOR指令EOR{条件}{S}目的寄存器,操作数1,操作数2EOR指令实现两个操作数的逻辑异或操作,将结果放入目的寄存器中。同时根据操作的结果影响标志位。常用于将操作数某些位置取反。示例: BICR0,R0,#0F ;将R1的低4位清0,其他位不变12.BIC指令BIC{条件}{S}目的寄存器,操作数1,操作数2BIC指令用于清除操作数1的某些位,将结果放入目的寄存器中。同时根据操作的结果影响标志位。操作数2为32位掩码,掩码中设置了哪些位则清除操作数1中这些位。示例: CMPR1,R0 ;将R1的值减去R0的值,并根据结果设置CPSR的标志位 CMPR1,#0x200 ;将R1的值减去200,并根据结果设置CPSR的标志位13.CMP指令CMP{条件}操作数1,操作数2CMP指令用于把一个寄存器的值减去另一个寄存器的值或立即数,根据结果设置CPSR中的标志位,但不保存结果。示例: CMNR1,R0 ;将R1的值和R0的值相加,并根据结果设置CPSR的标志位 CMNR1,#0x200;将R1的值和立即数200相加,并根据结果设置CPSR的标志位14.CMN指令CMN{条件}操作数1,操作数2CMN指令用于把一个寄存器的值减去另一个寄存器或立即数取反的值,根据结果设置CPSR中的标志位,但不保存结果。该指令实际完成两个操作数的加法。示例: TSTR1,#0x0F ;检测R1的低4为是否为015.TST指令TST{条件}操作数1,操作数2TST指令用于把一个寄存器的值和另一个寄存器的值或立即数进行按位与运算,根据结果设置CPSR中的标志位,但不保存结果。该指令常用于检测特定位的值。示例: TEQR1,R2;将R1的值和R2的值进行异或运算,并根据结果设置CPSR的标志位16.TEQ指令TEQ{条件}操作数1,操作数2TEQ指令用于把一个寄存器的值和另一个寄存器的值或立即数进行按位异或运算,根据结果设置CPSR中的标志位,但不保存结果。该指令常用于检测两个操作数是否相等。示例:3.3.3程序状态寄存器处理指令MRS指令和MSR指令用于在状态寄存器和通用寄存器间传输数据。状态寄存器的值要通过“读取→修改→写回”三个步骤操作来实现,可先用MRS指令将状态寄存器的值复制到通用寄存器中,修改后再通过MSR指令把通用寄存器的值写回状态寄存器。示例:MRSR0,CPSR ;将CPSR的值复制到R0中ORRR0,R0,#C0;R0的位6和位7置1,即屏蔽外部中断和快速中断MSRCPSR,R0 ;将R0值写回到CPSR中MRS指令和MSR指令的格式如下:MRS{条件}通用寄存器,程序状态寄存器(CPSR或SPSR)MSR{条件}程序状态寄存器(CPSR或SPSR)_<域>,操作数其中,MSR指令中的<域>可用于设置程序状态寄存器中需要操作的位:位[31:24]为条件标志位域,用f表示。位[23:16]为状态位域,用s表示。位[15:8]为扩展位域,用x表示。位[7:0]为控制位域,用c表示。示例: MSRCPSR_cxsf,R33.3.4加载/存储指令加载/存储指令用于在寄存器和存储器之间传输数据,Load指令用于将存储器中的数据传输到寄存器中,Store指令用于将寄存器中的数据保存到存储器中。1.LDR指令LDR{条件}目的寄存器,<存储器地址>LDR指令将一个32位字数据传输到目的寄存器中。如果目的寄存器是PC,从存储器中读出的数据将作为目的地址,以实现程序流程的跳转。示例:

LDRR1,[R0,#0x12];将存储器地址为R0+0x12的字数据写入R1 LDRR1,[R0,R2];将存储器地址为(R0+R2)的字数据写入R1 STRR1,[R0,#0x12];将R1中的字数据写入以R0+0x12为地址的存储器中 STRR1,[R0],#0x12;将R1中的字数据写入以R0+0x12为地址的存储器中,;并将新地址R0+0x12写入R02.STR指令STR{条件}源寄存器,<存储器地址>STR指令用于从源寄存器中将一个32位字数据写入存储器中。示例:3.LDM和STM指令LDM(或STM){条件}{类型}基址寄存器{!},寄存器列表{∧}LDM指令和STM指令实现一组寄存器和一片连续存储空间之间的数据传输。LDM指令加载多个寄存器,STM指令存储多个寄存器,它们常用于现场保护、数据复制、参数传输等,有8种模式:IA:每次传送后地址加4。IB:每次传送前地址加4。DA:每次传送后地址减4。DB:每次传送前地址减4。FD:满递减堆栈。ED:空递减堆栈。FA:满递增堆栈。EA:空递增堆栈。可选后缀{!},选用该后缀,当数据传输完成后,将最后地址写入基址寄存器中,否则基址寄存器值不变;基址寄存器不能为R15(PC),寄存器列表可以是R0~R15的任意组合。可选后缀{∧},当指令为LDM且寄存器列表中有R15(PC),选用该后缀表示除了完成数据传输以外,还将SPSR复制到CPSR。示例: LDMIAR0,{R3-R9} ;R0指向的存储器单元的数据,保存到R3~R9中,R0值不更新 STMIAR1!,{R3-R9};将R3~R9数据存储到R1指向的存储器单元中,R1的值更新 SWPR1,R1,[R0];将R1的内容与R0指向的存储单元的内容进行交换 SWPR1,R2,[R0];将R0指向的存储单元的内容写入到R1中,并将R2的内容写入;到该内存单元中4.SWP指令SWP{条件}目的寄存器,源寄存器1,[源寄存器2]SWP指令用于将源寄存器2所指向的存储器中的字数据传输到目的寄存器中,同时将源寄存器1中的字数据传输到源寄存器2所指向的存储器中。当源寄存器1和目的寄存器为同一个寄存器时,该指令完成该寄存器和存储器内容的交换。示例:3.3.5协处理指令ARM体系结构允许通过增加协处理器来扩展指令集。ARM协处理器具有自己专用的寄存器组,它们的状态由控制ARM状态的指令的镜像指令来控制。程序的控制流指令由ARM处理器来处理,所有的协处理器指令只能同数据处理和数据传送有关。ARM协处理器指令可完成下面三类操作:ARM协处理器的数据处理操作。ARM处理器和协处理器的寄存器之间数据传输。ARM协处理器的寄存器和存储器之间数据传输。ARM协处理器指令主要包括5条,它们的格式和功能如下:助记符说明功能CDPcoproc,opcodel,CRd,CRn,CRm{,opcode2}协处理器数据操作指令用于ARM处理器通知协处理器执行特定的操作LDC{L}coproc,CRd<地址>协处理器数据读取指令从某一连续的存储单元将数据读取到协处理器的寄存器中STC{L}coproc,CRd<地址>协处理器数据写入指令将协处理器的寄存器数据写入到某一连续的存储单元中MCRcoproc,opcodel,Rd,CRn{,opcode2}ARM寄存器到协处理器寄存器的数据传输指令将ARM处理器的寄存器中的数据传输到协处理器的寄存器中MRCcoproc,opcodel,Rd,CRn{,opcode2}协处理器寄存器到ARM寄存器的数据传输指令将协处理器的寄存器中的数据传输到ARM处理器的寄存器中3.3.6异常产生指令ARM处理器有两条异常产生指令,软中断指令(SWI)和断点中断指令(BKPT)。1.SWI指令SWI{条件}24位立即数SWI指令用于产生SWI异常中断,实现从用户模式切换到管理模式,CPSR保存到管理模式下的SPSR中,执行转移到SWI向量,;其他模式下也可使用SWI指令,同样切换到管理模式。该指令不影响条件码标志。示例: SWI0x02;软中断,调用操作系统编号为02的系统例程2.BKPT指令BKPT16位立即数BKPT指令产生软件断点中断,软件调试程序可以使用该中断。立即数会被ARM硬件忽视,但能被调试工具利用来得到有用的信息。示例: BKPT0xFF32

Thumb指令简介PartFour3.4为了兼容存储系统总线宽度为16位的应用系统,ARM体系结构中提供了16位Thumb指令集,它可以看作是ARM指令压缩形式的子集,是针对代码密度的问题而提出的,它具有16位的代码密度,这对于嵌入式系统来说至关重要。Thumb不是一个完整的体系结构,不能指望处理器只执行Thumb指令而不支持ARM指令集。Thumb指令集没有协处理器指令、信号量指令以及访问CPSR或SPSR的指令,没有乘加指令及64位乘法指令等,并且指令的第二操作数受到限制;除了分支指令B有条件执行功能外,其他指令均为无条件执行;大多数Thumb数据处理指令采用2地址格式。Thumb指令集与ARM指令集的区别一般有如下4点:1.跳转指令程序相对转移,特别是条件跳转与ARM代码下的跳转相比,在范围上有更多的限制,转向子程序是无条件的转移。2.数据处理指令数据处理指令是对通用寄存器进行操作,在大多数情况下,操作的结果须放入其中一个操作数寄存器中,而不是第3个寄存器中。数据处理操作比ARM状态的更少。访问R8~R15受到一定限制:除MOV和ADD指令访问寄存器R8~R15外,其他数据处理指令总是更新CPSR中的ALU状态标志;访问寄存器R8~R15的Thumb数据处理指令不能更新CPSR中的ALU状态标志。3.单寄存器加载和存储指令在Thumb状态下,单寄存器加载和存储指令只能访问寄存器R0~R7。4.多寄存器加载和多寄存器存储指令LDM和STM指令可以将任何范围为R0~R7的寄存器子集加载或存储。PUSH和POP指令使用堆栈指针R13作为基址实现满递减堆栈。除R0~R7外,PUSH指令还可以存储链接寄存器R14,并且POP指令可以加载程序计数器PC。

ARM汇编语言程序简介PartFive3.53.5.1

伪操作ARM汇编语言程序是由机器指令、伪指令和伪操作组成的。伪操作是ARM汇编语言程序里的一些特殊的指令助记符,和指令系统中的助记符不同,这些助记符没有相应的操作码。伪操作主要是为完成汇编程序做一些准备工作,在源程序汇编过程中起作用,一旦汇编完成,伪操作的使命就完成。宏是一段独立的程序代码,通过伪操作定义,在程序中使用宏指令即可调用宏。当程序被汇编时,汇编程序校对每个宏调用进行展开,用宏定义代替源程序中的宏指令。1.符号定义伪操作符号定义伪操作用于定义ARM汇编程序中的变量、对变量赋值及定义寄存器名称等。常用伪操作有:GBLA、GBLL和GBLS:定义全局变量。LCLA、LCLL和LCLS:定义局部变量。SETA、SETL和SETS:为变量赋值。RLIST:为通用寄存器列表定义名称。CN:为协处理器的寄存器定义名称。CP:为协处理器定义名称。DN和SN:为VFP的寄存器定义名称。FN:为FPA的浮点寄存器定义名称。2.数据定义伪操作数据定义伪操作用于数据表定义、文字池定义、数据空间分配等。常用伪操作有:LTORG:声明一个数据缓冲池的开始。MAP:定义一个结构化的内存表的首地址。FIELD:定义结构化内存表的一个数据域SPACE:分配一块内存空间,并用0初始化。DCB:分配一段字节的内存单元,并用指定的数据初始化。DCD和DCDU:分配一段字的内存单元,并用指定的数据初始化。DCFD和DCFDU:分配一段双字的内存单元,并用双精度的浮点数据初始化。DCFS和DCFSU:分配一段字的内存单元,并用单精度的浮点数据初始化。DCQ和DCQU:分配一段双字的内存单元,并用64位整型数据初始化。DCW和DCWU:分配一段半字的内存单元,并用指定的数据初始化。3.汇编控制伪操作汇编控制伪操作用于条件汇编、宏定义、重复汇编控制等,常用伪操作有:IF、ELSE和ENDIF:根据条件把一段源程序代码包括在汇编程序内或排除在程序之外。WHILE和WEND:根据条件重复汇编相同的源程序代码段。MACRO和MEND:MACRO标识宏定义的开始,MEND标识宏定义结束。用MACRO和MEND定义一段代码,称为宏定义体,在程序中可以通过宏指令多次调用该代码段。MEXIT:用于从宏中跳转出去。4.其它伪操作其它伪操作常用的有段定义伪操作、入口点设置伪操作、包含文件伪操作、标号导出或引入声明等:ALIGN:边界对齐。AREA:段定义。CODE16和CODE32:指令集定义。END:汇编结束。ENTRY:程序入口。EQU:常量定义。EXPORT和GLORBAL:声明一个符号可以被其它文件引用。IMPORT和EXTERN:声明一个外部符号。GET和INCLUDE:包含文件。INCBIN::包含不被汇编的文件。RN:给特定的寄存器命名。ROUT:标记局部标号使用范围的界限。3.5.2

伪指令ARM中的伪指令并不是真正的ARM或Thumb指令,这些伪指令在汇编编译器对源程序进行汇编处理时被替换成对应ARM或Thumb指令(序列)。常用的伪指令有:ADR:小范围的地址读取伪指令,该指令将基于PC的相对偏移地址或基于寄存器的相对偏移地址读取到寄存器中。格式为:ADR{cond}register,exprcond是可选的指令执行条件。register是目的寄存器。expr是基于PC或基于寄存器的地址表达式,当地址值是字节对齐时,取值范围在-255~255B;当地址值是字对齐时,取值范围在-1020~1020B;当地址值是16字节对齐时,取值范围更大。ADRL:中等范围的地址读取伪指令,该指令比ADR的取值范围更大。格式为:ADRL{cond}register,exprcond是可选的指令执行条件。register是目的寄存器。expr是基于PC或基于寄存器的地址表达式,当地址值是字节对齐时,取值范围在-64~64KB;当地址值是字对齐时,取值范围在-256~256KB;当地址值是16字节对齐时,取值范围更大;在32位的Thumb-2指令中,取值范围在可达-1~1MB。LDR:大范围的地址读取伪指令,将一个32位的常数或者一个地址值读取到寄存器中。格式为:LDR{cond}register,=[expr|label-expr]cond是可选的指令执行条件。register是目的寄存器。expr是32位常量。NOP空操作伪指令,在汇编时被替换成ARM中的空操作。3.5.3

汇编语言格式ARM(Thumb)汇编语言的语句格式为:[标号]<指令|条件|S><操作数>[;注释]在ARM汇编程序中,ARM指令、伪操作、伪指令、伪操作的助记符全部用大写字母,或者全部用小写字母,不能既有大写也有小写字母。所有标号在一行的顶格书写,后面不要添加“:”,所有指令不能顶格书写。注释内容以“;”开头到本行结束。源程序中允许有空行,如果单行太长,可以用字符“\”将其分开,“\”后不能有任何字符,包括空格和制表符等。变量的设置,常量的定义,其标识符必须在一行顶格书写。3.5.4

汇编语言的程序结构段(section)是ARM汇编语言组织源文件的基本单位,是独立的、具有特定名称的、不可分割的指令或数据序列。段分为代码段和数据段,代码段存放执行代码,数据段存放代码执行时需要的数据。一个ARM汇编程序至少需要一个代码段,较大的程序可以包含多个代码段和数据段。ARM汇编语言源程序经过汇编后生成可执行的映像文件,格式有axm、bin、elf、hex等。可执行的映像文件通常包括三个部分:一个或多个代码段,代码段的属性为只读。零个或多个包含初始化数据的数据段,属性为可读可写。零个或多个不包含初始化数据的数据段,属性为可读可写。连接器根据一定的规则将各个段安排到内存的相应位置。源程序中段之间的相对位置与可执行的映像文件中段的相对位置不一定相同。下面的程序说明了ARM汇编语言程序的基本结构:AREA BUF,DATA,READWRITE ;声明数据段BUF count DCB 30 ;定义一个字节单元countAREA EXAMPLE1,CODE,READONLY ;声明代码段EXAMPLE1ENTRY ;程序入口CODE32 ;声明32位ARM指令START LDRB R0,count ;R0=count MOV R1,#10 ;R1=8 ADD R0,R0,R1 ;R0=R0+R1 B STARTENDC语言与汇编语言的混合编程PartSix3.6在嵌入式开发中,C语言是一种常见的程序设计语言。C语言程序可读性强,易维护,可移植性和可靠性高。ARM体系结构不仅支持汇编语言也支持C语言,在一些情况下需要采用汇编语言和C语言混合编程。3.6.1

C程序中内嵌汇编在C语言程序中嵌入汇编可以完成一些C语言不能完成的操作,同时代码效率也比较高。在ARMC语言程序中使用关键词__asm来标识一段汇编指令代码,格式为:__asm //asm前2个下划线{ instruction[;instruction]

… [instruction]}如果一行有多条汇编指令,指令间用“;”隔开;如果一条指令占多行,要使用续行符号“\”。在ARMC语言程序中也可以使用关键词asm来标识一段汇编指令代码,格式为: asm(“instruction[;instruction]”);3.6.2汇编中访问C语言程序变量在C语言中声明的全局变量可以被汇编语言通过地址间接访问。例如,在C语言程序中已经声明了一个全局变量glovbvar,通过IMPORT伪指令声明外部变量的方式访问:AREA EXAMPLE2,CODE,REDAONLYIMPORT glovbvar ;声明外部变量glovbvarSTART LDR R1,=glovbvar ;装载外部变量地址 LDR R0,[R1] ;读出全局变量glovbvar数据 ADD R0,R0,#1 STR R0,[R1] ;保存变量值 MOV PC,LREND3.6.3ARM中的汇编和C语言相互调用为了使单独编译的C语言程序和汇编语言程序之间能够相互调用,必须遵守ATPCS规则。ATPCS即ARM-THUMBprocedurecallstandard(ARM-Thumb过程调用标准)的简称。ATPCS规定了应用程序的函数可以如何分开地写,分开地编译,最后将它们连接在一起,所以它实际上定义了一套有关过程(函数)调用者与被调用者之间的协议。基本ATPCS规定了在子程序调用时的一些基本规则,包括3个方面的内容:各寄存器的使用规则机器相应的名称。数据栈的使用规则。参数传递的规则。1.C程序调用汇编程序C程序调用汇编程序首先通过extern声明要调用的汇编程序模块,声明中形参个数要与汇编程序模块中需要的变量个数一致,且参数传递要满足ATPCS规则,然后在C程序中调用。示例:#include<stdio.h>externvoidstrcopy(char*d,char*s);//使用关键词声明intmain(){char*srcstr="first";char*dststr="second";strcopy(dststr,srcstr); //汇编模块调用;}被调用的汇编程序:AREA Scopy,CODE,REDAONLYEXPORTstrcopy //使用EXPORT伪操作声明本汇编程序strcopyLDRB R2,[R1],#1STRB R2,[R0],#1CMP R2,#0BNE strcopyMOV PC,LREND2.汇编程序调用C程序在调用之前必须根据C语言模块中需要的参数个数,以及ATPCS参数规则,完成参数传递,即前四个参数通过R0~R3传递,后面的参数通过堆栈传递,然后再利用B、BL指令调用。示例:intg(inta,intb,intc,intd,inte) //C语言函数原型{ return(a+b+c+d+e);}//汇编程序调用C程序g()计算i+2*i+3*i+4*i+5*i的结果;EXPORTfAREA f,CODE,REDAONLYIMPORTg //声明C程序函数g()STRLR,{SP,#-4}! //保存PCADDR1,R0,R0ADDR2,R1,R0ADDR3,R1,R2STRR3,{SP,#-4}!ADDR3,R1,R1BLg //调用C程序函数g()ADDSP,SP,#4LDRPC,[SP],#4END本章小结PartSeven3.7本章首先对ARM处理器指令的九种寻址方式进行了说明,并详细介绍了ARM指令集中各种指令的格式、功能和使用方法,简单介绍了16位的Thumb指令。随后介绍了ARM汇编语言的伪操作、伪指令和汇编语句格式,通过示例讲述了汇编语言程序的结构。最后讲述了C语言和汇编语言混合编程的规则和方法。通过本章,读者了解到ARM程序设计的基本知识,为基于ARM处理器的嵌入式软硬件开发奠定基础。第4章S5PV210微处理器与接口目录4.1基于S5PV210微处理器的硬件平台体系结构4.2存储系统4.3时钟系统4.4GPIO接口4.5串行通信接口4.6A/D转换器4.7本章小结S5PV210又名“蜂鸟”(Hummingbird),是三星推出的一款适用于智能手机和平板电脑等多媒体设备的应用处理器。S5PV210采用了ARMCortex-A8内核,ARMV7指令集,主频可达1GHZ,64/32位内部总线结构,32/32KB的数据/指令一级缓存,512KB的二级缓存,可以实现2000DMIPS(每秒运算2亿条指令集)的高性能运算能力。该处理器同时也提供了丰富的外设,以应用于各种嵌入式系统设计之中。本章将简要介绍S5PV210处理器的硬件结构,主要外设的功能及其接口。

基于S5PV210微处理器的硬件平台体系结构PartOne4.14.1.1S5PV210处理器简介S5PV210是一款高效率、高性能、低功耗的32位RISC处理器,它集成了ARMCortex-A8核心,实现了ARM架构V7并且支持众多外围设备。S5PV210采用64位内部总线结构,为3G和3.5G通信服务保证最优化的硬件性能,并且提供了许多强大的硬件加速器,例如运动视频处理、显示控制及缩放等。它内部集成的多格式转码器支持MPEG-1/2/4、H.263和H.264等的编解码,硬件加速器支持视频会议和模拟电视输出,高清晰度多媒体接口提供NTSC和PAL模式的输出。S5PV210处理器主要由6大部分组成,分别为CPU核心、系统外设、多媒体、电源管理、存储器接口和Connectivity模块。CPU和各个部分之间通过多层次AHB/AXI总线进行通信。存储系统PartTwo4.24.2.1S5PV210的地址空间S5PV210的存储器地址映射如图4-2所示。S5PV210的存储器地址空间分为7各部分,从下往上分别是引导区、动态随机存储器(DRAM)区、静态只读存储器(SROM)区、Flash区、音频存储区、隔离ROM区和特殊功能寄存器区。地址大小描述备注0x0000_00000x1FFF_FFFF512MBBootarea系统启动配置区,此映射区域由启动模式决定0x2000_00000x3FFF_FFFF512MBDRAM0存配置区,用于DDR2SDRAM寻址0x4000_00000x5FFF_FFFF512MBDRAM10x8000_00000x87FF_FFFF128MBSROMBank0外接总线型设备寻址区0x8800_00000x8FFF_FFFF128MBSROMBank10x9000_00000x97FF_FFFF128MBSROMBank20x9800_00000x9FFF_FFFF128MBSROMBank30xA000_00000xA7FF_FFFF128MBSROMBank40xA800_00000xAFFF_FFFF128MBSROMBank50xB000_00000xBFFF_FFFF256MBOneNAND/NANDControllerandSFROneNAND和NAND寻址区0xC000_00000xCFFF_FFFF256MBMP3_SRAMoutputbufferMP3_SROM输出缓存区0xD000_00000xD000_FFFF64KBIROMIROM区,设备引导使用0xD001_00000xD001_FFFF64KBReserved保留区0xD002_00000xD003_7FFF96KBIRAMIRAM区,设备引导使用0xD800_00000xDFFF_FFFF128MBDMZROM0xE000_00000xFFFF_FFFF512MBSFRregion特殊功能寄存器SFR区域S5PV210的引导区分为两个部分,分别是0x0000_0000~0x1FFF_FFFF和0xD002_0000~0xD003_FFFF的空间。系统上电后,从引导区开始执行BootLoader程序。S5PV210的SROM分为6个Bank,每个Bank大小都为128M。可支持8/16位的NORFlash、PROM和SDRAM,并支持8/16位的数据总线(Bank0只支持16位的数据总线)。S5PV210支持OneNAND和FlexOneNAND存储器的外部16位总线。S5PV210具有两个独立的DRAM控制器和接口,即DMC0和DMC1,分别支持8GB和4GB大小的DRAM存储器。4.2.2S5PV210启动流程S5PV210的启动过程由BL0、BL1和BL2(BL为BootLoader的简称,在本书第七章中将有详细介绍)3部分代码实现,其中BL0在出厂时已经被固化到64KB的iROM中。图4-3S5PV210的启动流程S5PV210上电后首先执行BL0,该段代码主要的工作序列如下所示:

(1)关看门狗时钟。

(2)初始化指令cache。

(3)初始化栈、堆。

(4)初始化块设备复制函数。

(5)初始化PLL及设置系统时钟。

(6)根据OM引脚设置,从相应启动介质复制BL1到片内SRAM的0xD002_0000地址处(其中0xD002_0010之前的16个字节存储的是BL1的校验信息和BL1的大小),并检查BL1的checksum信息,如果检查失败,IROM将自动偿试第二次启动(从SD/MMCchannel2启动)。

(7)检查是否是安全模式启动,如果是则验证BL1完整性。

(8)跳转到BL1起始地址处。从图4-3中可以看到,BL1的大小只有16KB,因而一般情况下BL1负责完成的工作较少。BL1被执行后首先初始化系统时钟、内存、串口等,然后将BL2代码拷贝到InternalSRAM的BL2区中并跳转执行。从图中可以看到SRAM的BL2区的大小有80KB,但很多情况下BL2代码的大小远远超过80KB,所以将BL2代码拷贝到SRAM中意义不大。更好的做法是直接将BL2拷贝到容量更大的内存中,不过在拷贝之前一定要先初始化好系统时钟和内存。BL2实际上是整个BootLoader的主体部分,因此它需要完成更多的初始化工作,例如初始化网卡、Flash等,之后BL2读取操作系统镜像到内存中运行。操作系统镜像的存放位置根据具体的开发平台而定,一般放到Flash上,也可以放到SD卡上。时钟系统PartThree4.34.3.1S5PV210时钟概述图4-4S5PV210的时钟域CPU的系统时钟源主要是外部晶振,内部其他部分的时钟都是将外部时钟源经过一定的分频或倍频得到的。外部时钟源的频率一般不能满足系统所需要的高频条件,所以往往需要PLL(锁相环)先进行倍频处理。S5PV210的时钟系统包括三个时钟域(Domain),分别是主系统时钟域(MSYS)、显示相关的时钟域(DSYS)、外围设备的时钟域(PSYS)。MSYS:用来给CORTEX-A8处理器、DRAM控制器、3D、内部存储器(IRAM和IROM)、芯片配置界面(SPERI)、中断控制器等提供时钟。DSYS:用来给显示相关的部件提供时钟,包括FIMC、FIMD、JPEG、IPS多媒体等。PSYS:用来给外围设备(I2S、SPI、I2C、UART等)、安全子系统、低功率音频播放等提供时钟。每个总线系统操作在200MHz(最大)、166MHz和133MHz,分别由异步总线桥梁(BRG)连接两个不同的域。4.3.2S5PV210的时钟结构图4-5S5PV210顶层时钟图

GPIO接口PartFour4.44.4.1

GPIO概述GPIO(General-PurposeInput/OutputPorts)全称是通用编程I/O端口。它们是CPU的引脚,可以通过它们向外输出高低电平,或者读入引脚的状态,这里的状态也是通过高电平或低电平来反应的,所以GPIO接口技术可以说是CPU众多接口技术中最为简单、常用的一种。每个GPIO端口至少需要两个寄存器,一个是用于控制的“通用I/O端口控制寄存器”,一个是存放数据的“通用I/O端口数据寄存器”。控制和数据寄存器的每一位和GPIO的硬件引脚相对应,由控制寄存器设置每一个引脚的数据流向,数据寄存器设置引脚输出的高低电平或读取引脚上的电平。除了这两个寄存器以外,还有其它相关寄存器,比如上拉/下拉寄存器设置GPIO输出模式是高阻、带上拉电平输出还是不带上拉电平输出等。S5PV210共有237个GPIO端口,分成15组:GPA0:8输入/输出引脚。GPA1:4输入/输出引脚。GPB:8输入/输出引脚。GPC0:5输入/输出引脚。GPC1:5输入/输出引脚。GPD0:4输入/输出引脚。GPD1:6输入/输出引脚。GPE0、GPE1:13输入/输出引脚。GPF0、GPF1、GPF2、GPF3:30输入/输出引脚。GPG0、GPG1、GPG2、GPG3:28输入/输出引脚。GPH0、GPH1、GPH2、GPH3:32输入/输出引脚。GPP1:低功率I2S、PCM。GPJ0、GPJ1、GPJ2、GPJ3、GPJ4:35输入/输出引脚。MP0_1、MP_2、MP_3:20输入/输出引脚。MP0_4、MP_5、MP_6、MP_7:32输入/输出存储器引脚。GPIO的15组引脚除了作为输入、输出引脚外,一般都还有其它功能,称为引脚复用。具体要使用引脚的哪个功能,需要通过相关的控制寄存器来设置。图4-7GPIO端口功能框图4.4.2

GPIO寄存器每组GPIO端口都有两类控制寄存器,分别工作在正常模式和掉电模式(STOP、DEEP-STOP、睡眠模式)。S5PV210处理器工作在正常模式下时,正常寄存器(如GPA0控制寄存器GPA0CON,GPA0数据寄存器GPA0DAT,GPA0上拉/下拉寄存器GPA0PUD,GPA0驱动能力控制寄存器GPA0DRV)工作;进入掉电模式时,所有配置和上拉/下拉控制由掉电寄存器(如GPA0的掉电模式配置寄存器GPA0CONPDN,GPA0的掉电模式上拉/下拉寄存器GPA0PUDPDN)控制。GPIO主要的相关寄存器:GPIO控制寄存器GPxnCON。用于控制GPIO的引脚功能,向该寄存器写入数据来设置相应引脚是输入/输出,还是其它功能。该寄存器中每4位控制一个引脚,写入0000设置为输入IO口,从引脚上读入外部输入的数据;写入0001设置为输出IO口,向该位写入的数据被发送到对应的引脚上;写入其它值可设置引脚的第二功能,具体功能可查阅S5PV210处理器的芯片手册。GPIO数据寄存器GPxnDAT。用于读写引脚的状态,即该端口的数据。当引脚被设置为输出引脚,写该寄存器的对应位为1,设置该引脚输出高电平,写入0设置该引脚输出低电平;当引脚被设置为输入引脚,读取该寄存器对应位中的数据可得到端口电平状态。GPIO上拉/下拉寄存器GPxnPUD,用于控制每个端口上拉/下拉电阻的使能/禁止。对应位为0时,该引脚使用上拉/下拉电阻;对应位为1时,该引脚不使用上拉/下拉电阻。GPIO掉电模式上拉/下拉寄存器GPxnPUDPDN,用于掉电模式下使用。每两位对应一个引脚,为00时输出0,01时输出1,10时为输入功能,11时保持原有状态。4.4.3

GPIO操作步骤S5PV210处理器GPIO端口操作步骤如下:首先,确定所使用的GPIO端口的功能,如作为输入/输出引脚使用时,是否需要设置上拉/下拉电阻;作为其它功能使用时,对应S5PV210处理器的芯片手册进行设置。其次,确定GPIO端口的输入/输出方向,通过端口设置寄存器完成端口的输入/输出功能或其它功能设置。最后,对数据寄存器操作。如果设置为输入引脚,读取数据寄存器对应位值,实现引脚状态的读取;如果设置为输出引脚,通过写数据寄存器对应位值,实现引脚状态的设置。4.4.4一个LED灯的例子IO口的操作是硬件控制的基础,本例子是一个最简单的IO口操作。8个LED灯分别用8个GPIO口来进行单独控制,通过I/O控制发光二极管的亮和灭。图4-8GPIO与LED灯的连接通过电路原理图可以得到的物理连接如下表所示:原理图led灯标识ARM芯片接口标识Led1XEINT16/GPH2_0Led2XEINT17/GPH2_1Led3XEINT18/GPH2_2Led4XEINT19/GPH2_3Led5XEINT24/GPH3_0Led6XEINT25/GPH3_1Led7XEINT26/GPH3_2Led8XEINT27/GPH3_3查看GPH2相关的寄存器:GPH2相关的寄存器有:GPH2CON,GPH2DAT,GPH2PUD以及GPH2DRV。通过对不同寄存器的操作,可以配置GPIO的功能。寄存器物理地址读/写属性描述初始值GPH2CON0Xe020_0C40R/WGPH2CON端口配置寄存器0x00000000GPH2DAT0Xe020_0C44R/WGPH2DAT端口数据寄存器0x00GPH2PUD0Xe020_0C48R/WGPH2PUD端口上拉寄存器0x5555GPH2DRV0Xe020_0C4CR/WGPH2DRV端口驱动能力寄存器0x0000表4-3GPH2寄存器族GPH2CON位描述初始值GPH2CON[0][3:0]0000=Input0001=Output0010=Reserved0011=KP_COL[0]0100~1110=Reserved1111=EXT_INT[16]0000表4-4GPH2CON端口配置寄存器表4-5GPH2DAT端口数据寄存器GPH2DAT位描述初始值GPH2DAT[7:0][7:0]8位数据输入或者输出0x00表4-6GPH2PUD端口上拉寄存器GPH2PUD位描述初始值GPH2PUD[n][2n+1:2n]N=0~700=禁止上拉/下拉01=下拉使能10=上拉使能11=Reserved0x5555表4-7GPH2DRV端口驱动能力寄存器GPH2DRV位描述初始值GPH2DRV[n][2n+1:2n]N=0~700=1x01=2x10=3x11=4x0x00本例通过使用mmap方法实现不经过内核驱动直接在用户区映射的方式来控制寄存器,从而最终控制LED灯的功能。由于在应用程序中不能直接操作物理地址,因此通过mmap将一个文件或者其它对象映射进物理地址,应用程序就可以直接操作地址,从而达到控制寄存器的目的。在向端口写函数port_write中我们可以看到mmap方法。intport_write(unsignedintn, unsignedintfd, volatileunsignedintADDR_CON_OFFSET, volatileunsignedintGPIO_WR_CON, volatileunsignedintGPIO_WR_DAT){ADDR_START=(volatileunsignedchar*)mmap(NULL,1024*n,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0xE0200000); if(ADDR_START==NULL){ printf("mmaperr!\n"); return-1; } *(volatileunsignedint*)(ADDR_START+ADDR_CON_OFFSET)= GPIO_WR_CON; GPIO_DAT= (volatileunsignedint*)(ADDR_STAR

温馨提示

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

评论

0/150

提交评论