ARM嵌入式开发实例-第4章_第1页
ARM嵌入式开发实例-第4章_第2页
ARM嵌入式开发实例-第4章_第3页
ARM嵌入式开发实例-第4章_第4页
ARM嵌入式开发实例-第4章_第5页
已阅读5页,还剩54页未读 继续免费阅读

下载本文档

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

文档简介

1在前面的内容中已经向读者介绍过有关STM32F103XX系列处理器的指令系统。尽管目前处理器的编译技术完全可以支持高级语言在嵌入式开发系统中的运行,但汇编语言的作用仍然不可替代。在STM32F103XX系列处理器的嵌入式系统开发过程中,最常用的编程语言就是汇编语言和C语言。这两种程序设计语言各自具有不同的特点,并且两者混合使用还能有助于用户理解嵌入式系统的原理,提高嵌入式系统的调试能力。在本章内容中,主要向读者介绍ARM嵌入系统中汇编语言和C语言程序设计的方法。通过本章的学习,用户可以掌握汇编语言和C程序语言在嵌入式系统编程中的具体使用方法。第4章STM32F103XX程序设计本章节重难点2【本章重点】1汇编语言的程序设计;2C语言的程序设计;3汇编语言与C语言的混合编程;【本章难点】1程序设计中的变量定义;2C语言与汇编语言的交叉使用;3ARM嵌入式系统中的程序文件,通常也被称为源文件,可以由任意一种文本编辑器来编写。在ARM程序设计中,常用的源文件可以简单的分为以下几种,如表4.1所示。第4章STM32F103XX程序设计4.1STM32F103XX处理器的汇编程序开发框架表4.1ARM嵌入式系统中的源文件

44.1STM32F103XX处理器的汇编程序开发框架源程序文件文件后缀名说明汇编程序文件*.s用ARM汇编语言编写的ARM程序或Thumb程序代码C程序文件*.c用C语言编写的程序代码头文件*.h为了简化源程序代码,将程序中经常使用的常量命名、宏定义、数据结构定义等,单独放到一个文件中,该文件即为头文件1、在ARM处理器中,汇编语言的语法结构如下所示:标号操作码操作数1,操作数,…… ;注释标号是代表地址的符号,必须在一行的顶格书写,其后不能添加冒号“:”,而所有指令均不能顶格书写。ARM汇编语言对标识符的大小写敏感,书写标号及指令时字母大小写要一致。在ARM汇编语言中,ARM指令、伪指令、存放器名等可以全部大写或者全部小写,但不能大小写混合使用。为了使源文件易读,可以将一条长的指令通过使用反斜杠字符“\”将其分成几行书写。每行从第一个分号开始到本行结束为注释内容,所有的注释内容均被汇编起忽略。54.1STM32F103XX处理器的汇编程序开发框架〔第二章课件〕2、ARM汇编语言程序的根本结构在ARM汇编语言程序中,以程序段为单位来组织代码。段是相对独立的指令或数据序列,具有特定的名称。段可以分为代码段和数据段,代码段的内容为执行代码,数据段存放代码运行时所需的数据。可执行映像文件通常由以下几局部构成:一个或多个代码段,代码段为只读属性。零个或多个包含初始化数据的数据段,数据段的属性为可读写。零个或多个不包含初始化数据的数据段,数据段的属性为可读写64.1STM32F103XX处理器的汇编程序开发框架〔第二章课件〕73.1STM32F103XX系统简介4.1STM32F103XX处理器的汇编程序开发框架4.1.1ARM汇编语言中的代码程序段将通过下面的汇编代码向读者介绍有关汇编语言中的代码程序段。

AREAexample,CODE,READONLY ENTRYStartMOVR1,#0x1 MOVR2,#0x02 MOVR3,R1,R2 END8“AREAexample,CODE,READONLY”定义了一个名为example的代码段。需要说明的是,AREA是汇编代码中的一个伪指令,其功能是用来定义汇编语言中的代码段或者数据段。AREA的根本语法格式为:AREA段名称{,段的属性1}{,段的属性2}此外,伪指令CODE那么是对该段的属性进行设定,即表示该段的属性为代码段。与其对应的是,如果伪指令是DATA,那么表示该段的属性为数据,即该段为数据段。1.1

ARM嵌入式系统简介4.1STM32F103XX处理器的汇编程序开发框架9伪指令READONLY是表示该代码段的读写属性为“只读”。除此之外,用户还可以通过使用伪指令READWRITE来表示当前该代码段的读写属性为“可读写”;伪指令ENTRY用来标识当前代码段的入口。在每一个汇编文件中,只能有一个伪指令ENTRY,即只能有一个程序入口;伪指令END标志当前程序段的结束。需要提醒用户注意的是,END结束标识符必须和ENTRY伪指令匹配使用。1.1

ARM嵌入式系统简介4.1STM32F103XX处理器的汇编程序开发框架10用DATA伪指令来定义了一段数据代码段。

AREA

DataField,DATA,READWRITE DATA1SPACE256;分配一段连续的存储单元;并初始化0 DATA2SPACE128 DATADCD2,3,4;1.1

ARM嵌入式系统简介4.1STM32F103XX处理器的汇编程序开发框架4.1.2ARM汇编语言中的数据程序段11在ARM汇编语言中有着对应的宏定义的方法,其伪指令是MACRO,并与MEND配对使用,用于表示宏定义的结束。

MACRO

MULTI2 $DATA1;当前宏定义代码段的名称 MOV R0,$DATA1 MOV R1,$DATA1 ADD R0,R0,R1;实现功能$DATA1*2

MEND

MULTI20x12;实现0x12*21.1

ARM嵌入式系统简介4.1STM32F103XX处理器的汇编程序开发框架4.1.3ARM汇编语言中的宏定义12在任何一个编程语言中,符号数据的使用可以给程序员带来很大的便捷。如果没有符号数据,在程序设计的过程中必须使用嵌入式系统中操作数的内存地址才能实现对数据的访问。并且还需要在用到常量的地方注明当前内存空间的数值,一旦常量的数值发生改变就需要重新替换程序代码中所有使用该常量的地方。在ARM嵌入式汇编代码中,用户可以使用符号数据来简化程序代码中变量。在使用符号数据的过程中,用户必须遵守以下3个条件:〔1〕符号数据必须使用大小写字母、数字或下划线的组合来命名;

1.1

ARM嵌入式系统简介4.1STM32F103XX处理器的汇编程序开发框架4.1.4ARM汇编语言中的符号数据13〔2〕符号数据的名称去区分大小写。相同字符但大小写不同的符号数据,系统默认为2个不同的符号数据;〔3〕符号数据的名称不可以与汇编语言中的伪指令重复;1、常量的定义在所有的编程语言中,常量是较为常见的数据。在ARM汇编语言中,常量是32bit的整数。用户可以使用伪指令EQU来定义数字常量。需要提醒用户注意的是,用户在定义完数字常量后,不可以再改变其数值。2、变量的定义在程序设计的过程中,变量是最常用的数据格式。在ARM汇编语言中,根据变量自身的作用范围,可以将其分为全局变量和局部变量。

1.1

ARM嵌入式系统简介4.1STM32F103XX处理器的汇编程序开发框架14在ARM汇编语言中,用户可以通过GBLA、GBLL和GBLS来申明全局变量;通过LCLA、LCLL和LCLS来声明局部变量;同时,还可以使用SETA、SETL和SETS来对申明后的变量进行赋值操作。1.1

ARM嵌入式系统简介4.1STM32F103XX处理器的汇编程序开发框架15在ARM嵌入式系统中,虽然汇编语言与其他编程语言相比可以用更高的代码效率,但实际上C/C++语言仍然是ARM嵌入式系统开发的主流编程语言。C/C++编程语言执行效率较高,语法格式自由,模块化性能好,因此受到很多ARM嵌入式开发工程师的青睐。在本章节的内容中,将向读者介绍C语言在ARM嵌入式系统中的应用。需要说明的是,关于ARM嵌入式中C/C++编程语言的根本语法格式,与常用计算机软件开发中用到的C/C++编程语言的语法格式根本相同。因此,本章节将主要就C语言在ARM嵌入式系统开发过程中,相对计算机软件开发而言比较特殊的方面进行详细的介绍。第四章STM32F103XX程序设计4.2STM32F103XX处理器的数据操作图4-1C语言中的数据类型

16在C语言程序中,数据类型可分为:根本数据类型,构造数据类型,指针类型,空类型四大类,如图4-1所示。4.2

STM32F103XX处理器的数据操作4.2.1C语言中数据类型表4.3C语言中的常用和数据类型

171.1

ARM嵌入式系统简介4.2

STM32F103XX处理器的数据操作基本数据类型类型说明符字节长度数值范围字符型char1C字符集基本整型int2-32768~32767短整型shortint2-32768~32767长整型longint4-214783648~214783647无符号型unsigned20~65535无符号长整型unsignedlong40~4294967295单精度实型float43/4E-38~3/4E+38双精度实型double81/7E-308~1/7E+308在ARM嵌入式操作系统中,常用的根本数据类型可以大致归结为以下几种,具体如表4.3所示。用户可以在该表中查询常用数据类型的说明符、数据占据的存储空间〔字节长度〕,以及数据类型所能表示的数值范围。18在C语言程序设计中,用户可以使用printf函数实现对数据的输出操作。与此对应的是,用户可以使用scanf函数实现对数据的输入操作。关于这两个输入输出的函数的根本内容,用户都可以在标准C函数库中查询到。具体的语法格式为:〔1〕printf(格式控制,输出表列〕;〔2〕scanf(格式控制,&输出表列〕;从上述两个函数的根本语法格式可以看出,printf函数和scanf函数的根本格式都是一致的。唯一不同的是,在scanf函数中,参数表列的前面需要添加取地址操作符-&。1.1

ARM嵌入式系统简介4.2

STM32F103XX处理器的数据操作4.2.2C语言中数据输入/输出格式19在ARM嵌入式C语言中,对于根本数据类型量,按其取值是否可改变又分为常量和变量两种。在程序执行过程中,数值不发生改变的量称为常量,数值可变的量称为变量。同时,ARM嵌入式代码中的变量和常量还可以与数据类型结合起来分类。例如整型常量、整型变量、浮点型常量、浮点型变量、字符常量、字符变量、枚举常量、枚举变量。需要说明的是,在ARM嵌入式程序代码中,常量是可以不经申明而直接引用的,而变量那么必须先定义后使用。1.1

ARM嵌入式系统简介4.2

STM32F103XX处理器的数据操作4.2.3C语言中的变量和常量201、常量的定义和使用在代码执行的过程中,数值不发生改变的量称为常量。在ARM嵌入式语言中,常见的常量类型可以分为以下几种:〔1〕直接常量〔2〕标识符〔3〕符号常量2、变量的定义和使用在代码运行的过程中,数值可以改变的量称为变量。在ARM嵌入式程序代码中,任何一个变量都必须有一个变量名,并且在内存中占据一定的存储单元。ARM嵌入式代码中,变量定义与常量的定义有所区别,用户必须在变量使用之前对其进行申明操作。通常情况下,变量的申明放在函数体的开头局部。1.1

ARM嵌入式系统简介4.2

STM32F103XX处理器的数据操作21整型〔INTEGER〕数据是不包含小数局部的数值型数据,用字母I表示。整型数据只用来表示整数,以二进制形式存储。1.整形变量的格式〔1〕十进制整常数(13)〔2〕八进制整常数〔015〕〔3〕十六进制整常数(0x1101)2.整形变量的分类在ARM嵌入式C语言程序代码中,根据数据类型的长度,可以将其分为根本型,短整型,长整形,无符号型。

1.1

ARM嵌入式系统简介4.2

STM32F103XX处理器的数据操作4.2.4C语言中的整型数据223.整形变量的定义在ARM嵌入式程序代码的设计过程中,用户在使用变量前必须进行声明和定义,这是与C语言中常量不同的地方。变量定义的一般形式为:类型说明符

变量名标识符,变量名标识符,...;在C语言中,用户可以通过下面的几行代码来声明定义整型变量,例如:inta,b,c; //定义3个整型变量a,b,c为整型变量longx,y; //x,y为长整型变量unsignedp,q; //p,q为无符号整型变量1.1

ARM嵌入式系统简介4.2

STM32F103XX处理器的数据操作23在ARM嵌入式编程语言中,实型数据也称为浮点型数据。与整型数据类似的是,实型数据也可以有常量和变量之分。在程序运行过程中可以改变其值的实型数据被称为实型变量。在程序运行过程中不可以改变其值的实型数据被称为实型常量。1.实型常量的格式实型常量也称为实数或者浮点数。在C语言中,实数只能采用十进制的表达格式。但实型常量可以使用2种不同形式的表达方法,即十进制数形式,指数形式。1.1

ARM嵌入式系统简介4.2

STM32F103XX处理器的数据操作4.2.5C语言中的实型数据242.实型变量在ARM嵌入式系统中,实型数据一般占4个字节〔32bit〕内存空间,且按指数形式存储在系统的内存空间中。从实型变量的格式上来看,小数局部占的位〔bit〕数愈多,数的有效数字愈多,精度愈高。而指数局部占的位数愈多,那么能表示的数值范围愈大。根据数据的长度,可以将实型变量分为以下3种类型:单精度float型、双精度double型和长双精度longdouble型。1.1

ARM嵌入式系统简介4.2

STM32F103XX处理器的数据操作25字符型〔Character〕数据是不具计算能力的文字数据类型,通常情况下用字母C表示。它包括中文字符、英文字符、数字字符和其他ASCII字符,其长度〔即字符个数〕范围是0-254个字符。与前面几种数据类型相似的是,C语言中的字符型数据同样分为字符型常量和字符型变量。1.1

ARM嵌入式系统简介4.2.6C语言中的字符型数据4.2

STM32F103XX处理器的数据操作26在ARM嵌入式程序代码中,字符串常量是由一对双引号括起的字符序列。例如:“CHINA”,“Cprogram”,“$12.5”等都是合法的字符串常量。字符串常量和字符常量是不同的数据类型,但两者之间也有不同之处,主要有以下几点区别:〔1〕字符型常量通常由单引号来引用,字符串常量那么通常由双引号来引用;‘a’“china”〔2〕字符常量只能是单个字符,字符串常量那么可以含一个或多个字符;1.1

ARM嵌入式系统简介4.2

STM32F103XX处理器的数据操作4.2.7C语言中的字符串常量27〔3〕用户可以把一个字符常量赋予一个字符变量,但不能把一个字符串常量赋予一个字符变量。需要注意的是,在ARM嵌入式程序代码中,没有相应的字符串变量。这是与其他编程语言不同的。但是用户可以用一个字符数组来存放一个字符串常量;〔4〕字符常量占一个字节的内存空间。字符串常量占的内存字节数等于字符串中字节数加1。增加的一个字节中存放字符"\0"(ASCII码为0)。这也是字符串结束的标志。1.1

ARM嵌入式系统简介4.2

STM32F103XX处理器的数据操作28在ARM嵌入式程序代码中,变量的数据类型是可以相互转换的。转换的方法有两种,一种是自动转换,一种是强制转换。〔1〕数据类型的自动转换通常情况下,自动转换常用在不同数据类型的量混合运算时,由编译系统自动完成。〔2〕数据类型的强制转换强制类型转换是通过类型转换运算来实现的,具体的语法格式如下所示:(类型说明符)(表达式)〔float〕〔a〕其功能主要是把表达式的运算结果强制转换成类型说明符所表示的类型。1.1

ARM嵌入式系统简介4.2

STM32F103XX处理器的数据操作4.2.8不同类型数据之间的混合运算29第四章STM32F103XX程序设计4.3STM32F103XX处理器的数据运算在ARM嵌入式程序代码中,系统支持了大量C语言格式的运算符和表达式。因此,用户可以通过不同的运算符和表达式在ARM嵌入式系统中实现各种对数据处理的功能,这也是ARM嵌入式程序设计的主要特点之一。与通用C语言的数据运算相同的是,ARM嵌入式程序代码中的运算符不仅具有不同的优先级,而且还具有一定的结合性。用户在使用在表达式对数据进行处理的过程中,参与运算的各个数据参与运算的先后顺序不仅要遵守运算符优先级别的规定,还要受到运算符结合性的制约,以便确定是自左向右进行运算还是自右向左进行运算。这种结合性是其它高级语言的运算符所没有的,因此也增加了C语言的复杂性。30在ARM嵌入式程序代码中,常见的算术运算操作符有加法运算符“+”、减法运算符“-”、乘法运算符“*”和除法运算符“/”。一般而言,ARM嵌入式系统中的乘法和除法操作具有专用的乘法器和除法器,主要是由于在ARM处理器中进行乘法和除法运算需要占用大量的系统时间和资源,因此局部ARM处理器中,系统为用户提供了专用的硬件乘法器和除法器。这种做法在很大程度上减轻了处理器的排队任务,有利于提高数据运算的效率。但该方法的缺点也比较明显,即系统需要配备硬件乘法器和除法器,提供了ARM处理器的本钱。4.3

STM32F103XX处理器的数据运算4.3.1ARM程序代码中的算术运算符31在ARM嵌入式程序代码中,算术运算表达式是由常量、变量、函数和运算符组合起来的式子。一个表达式有一个值及其类型,它们等于计算表达式所得结果的值和类型。表达式求值按运算符的优先级和结合性规定的顺序进行,例如最常见的是数学运算中的四那么运算。从某种意义上而言,单个的常量、变量、函数可以看作是表达式的特例。在ARM嵌入式程序代码中,运算符的运算优先级共分为15级,其中1级最高,15级最低。在表达式中,优先级较高的先于优先级较低的进行运算。而在一个运算量两侧的运算符优先级相同时,那么按运算符的结合性所规定的结合方向处理。1.1

ARM嵌入式系统简介4.3

STM32F103XX处理器的数据运算4.3.2算术运算符的优先级和结合性32除了上述的算术优先级外,用户在执行运算操作的过程中还需要注意运算符之间的结合性。在ARM嵌入式程序代码中,运算符的结合性分为两种,即左结合性(自左至右)和右结合性(自右至左)。通常情况下,算术运算符的结合性是自左至右,即先左后右。例如在表达式x-y+z中,参数y应先与“-”号结合,执行x-y运算,然后再执行+z的运算。这种自左至右的结合方向就称为“左结合性”。除了上述的“左结合性”外,在局部算术表达式中还支持“右结合性”,即自右至左的结合方式。最典型的右结合性运算符是赋值运算符。例如在赋值表达式x=y=z中,由于“=”的右结合性,应先执行y=z再执行x=(y=z)运算。

1.1

ARM嵌入式系统简介33在ARM嵌入式程序代码中,不同的数据类型之间可能需要相互转化。需要说明的是,除了可以实现对变量类型的数据转换外,同样还可以对表达式的数据类型进行强制转换。用户可以通过数据类型的强制转换来实现不同数据类型的变通,具体的语法操作格式如下所示:〔类型说明符〕〔表达式〕该语法功能是将表达式的运算结果强制转换成类型说明符所表示的类型。1.1

ARM嵌入式系统简介4.3

STM32F103XX处理器的数据运算4.3.3数据类型的强制转换34在ARM嵌入式代码中,为了简化循环操作,系统为用户提供了自增与自减操作。在ARM嵌入式程序代码中:〔1〕自增1运算符记为“++”,其功能是使变量值自增1;〔2〕自减1运算符记为“--”,其功能是使变量值自减1。需要说明的是,ARM嵌入式程序代码中的“自增1”和“自减1”运算符均为单目运算,且都具有右结合性。1.1

ARM嵌入式系统简介4.3

STM32F103XX处理器的数据运算4.3.4自增与自减操作35常用的自增与自减操作主要有以下几种形式:++i i自增1后再参与其它运算--i i自减1后再参与其它运算i++ i参与运算后,i的值再自增1i-- i参与运算后,i的值再自减1在理解和使用上容易出错的是i++和i--。特别是当它们出在较复杂的表达式或语句中时,常常难于弄清,因此应仔细分析。一般情况下,除了在一些功能比较明确的程序代码中,如循环累加、累加运算,可以使用外,在其他的嵌入式代码中,特别是存在全局变量的程序代码中,不建议用户过多的使用自增或自减操作。1.1

ARM嵌入式系统简介4.3

STM32F103XX处理器的数据运算36在ARM嵌入式程序代码中,需要对变量以及表达式进行赋值操作。通常情况下,用户可以通过赋值运算符“=”对变量或表达式进行赋值操作,其中简单赋值运算符用“=”来表示。在ARM嵌入式程序代码中,由赋值运算符“=”连接的表达式称为赋值表达式。其根本的语法格式如下所示:变量=表达式用户除了可以对变量和表达式进行赋值操作外,还可以将赋值表达式组成赋值语句,按照C语言规定,任何表达式在其末尾加上分号“;”就构成为赋值语句。1.1

ARM嵌入式系统简介4.3

STM32F103XX处理器的数据运算4.3.5赋值运算符和赋值表达式37在ARM嵌入式程序设计语言中,用户还可以在赋值符“=”之前加上其它二目运算符构成复合赋值符,如+=,-=,*=,/=,%=,<<=,>>=,&=,^=,|=等。

构成复合赋值表达式的一般形式为:变量

双目运算符=表达式需要说明的是,根据不同的符合赋值表达式的定义,可以将其等效于如表4.9所示的赋值表达式,即:变量=变量运算符表达式1.1

ARM嵌入式系统简介4.3

STM32F103XX处理器的数据运算38在ARM嵌入式程序代码中,逗号“,”也是一种运算符,称为逗号运算符。其功能是将两个表达式连接起来组成一个新的表达式,称为逗号表达式。有关逗号表达式的语法格式具体如下所示:表达式1,表达式2有关逗号表达式求值的过程是分别求逗号前后两个表达式的值,并以表达式2的值作为整个逗号表达式的值。用户可以通过下面的例子对逗号运算符进行了解。1.1

ARM嵌入式系统简介4.3.6逗号运算符4.3

STM32F103XX处理器的数据运算39有关逗号表达式以及逗号运算符的内容,还需要补充说明以下2点:〔1〕在逗号表达式的一般形式中,逗号运算符前后的表达式1和表达式2不仅可以是简单的算术运算,也同样可以是逗号表达式,即在逗号表达式中嵌套逗号表达式;〔2〕通常情况下,用户在程序代码中使用逗号表达式,是要分别求逗号表达式内各表达式的值,并不一定要求整个逗号表达式的值。但需要提醒用户注意的是,并不是在所有出现逗号的地方都会组成逗号表达式,例如在变量声明、定义的过程中,函数参数表中逗号只是用作各变量之间的间隔符。

1.1

ARM嵌入式系统简介4.3

STM32F103XX处理器的数据运算40通常情况下,ARM嵌入式程序中代码的执行是过程化的,即从上往下依次逐行执行。但在实际的代码设计过程中,经常需要指定程序代码执行某局部而不执行某局部,或者反复执行某局部,这些就是流程控制。在ARM嵌入式程序代码中,流程控制语句有两类,具体有〔1〕判断语句〔2〕循环语句。除此之外,在ARM嵌入式系统中还有一个能综合使用判断语句和起来的条件循环语句,即C语言中的while循环语句。第四章STM32F103XX程序设计4.4STM32F103XX的流程控制语句41在ARM嵌入式程序代码中,用户可以通过if语句来构成分支结构。它根据给定的条件进行判断,以决定执行某个分支程序段。C语言的if语句有三种根本形式,if语句、if-else语句和if-else-if语句。1.If语句:if判断语句的第一种形式为根本形式,也是if判断语句中最为简单的一种形式,具体的语法格式如下所示:if(表达式)执行语句;该if判断语句的根本含义是:如果伪指令if后表达式的值为真,那么执行其后的执行语句,否那么将不执行该语句。4.4

STM32F103XX的流程控制语句4.4.1ARM中的if条件判断语句422.If-else语句:在ARM嵌入式程序代码中,用户除了可以在满足if判断条件时通过判断语句进行流程控制外,还可以在不满足if判断条件的状况下进行流程控制,即if-else判断语句。该判断语句的根本语法格式如下所示:if(表达式)语句1;else语句2;该if-else判断语句的根本含义是:如果伪指令if后表达式的值为真,那么执行语句1;否那么程序将执行语句2。1.1

ARM嵌入式系统简介4.4

STM32F103XX的流程控制语句433.If-else-if语句:从上述2中if判断语句的根本用法来看,在ARM嵌入式系统中,用户不仅可以在符合if判断语句条件的情况下执行指定的操作代码,也同样可以在不满足if判断语句条件的情况下执行指定的操作代码。除此之外,在ARM嵌入式程序代码中,用户还可以使用if-else-if形式来实现条件判断操作。前面介绍的2种形式的if条件判断语句一般都用于两个分支的情况。当有多个分支需要选择的时候,可采用if-else-if语句,其一般语法形式为:if(表达式1) 语句1;elseif(表达式2)语句2;1.1

ARM嵌入式系统简介4.4

STM32F103XX的流程控制语句44elseif(表达式3)语句3;…elseif(表达式m)语句m;else语句n;上述代码的根本语义是:编译器依次判断表达式的值,当出现某个值为真时,那么执行其对应的语句,然后程序将跳到整个if语句之外继续执行其他的程序代码。如果所有的表达式均为假,那么执行语句n,然后跳出if-else-if语句并继续执行后续程序。1.1

ARM嵌入式系统简介4.4

STM32F103XX的流程控制语句45在ARM嵌入式程序系统中,用户除了可以通过if条件判断语句进行流程控制,还可以通过分支选择语句来实现多重分支的选择。C语言中,用户可以通过switch语句来完成上述分支选择的功能,具体的语法格式如下所示:switch(表达式){case常量表达式1:语句1;case常量表达式2:语句2;…case常量表达式n:语句n;default:语句n+1;}1.1

ARM嵌入式系统简介4.4

STM32F103XX的流程控制语句4.4.2ARM中的switch分支选择语句46在上述的程序代码中,其根本的语义是:计算表达式的值,并逐个与其后case中的常量表达式值相比较。当表达式的值与某个常量表达式的值相等时,即执行其后的语句,继而不再进行判断,执行后面所有case中的语句。如表达式的值与所有case后的常量表达式均不相同时,那么执行default后的语句。需要提醒用户注意的是,在使用switch语句时还应注意以下几点:〔1〕在case分支语句后的各常量表达式的值不能相同,否那么会出现错误;〔2〕在case分支语句后,系统允许有多个执行语句,也允许用户不使用{}括起来;〔3〕每一个case和default子句的先后顺序可以相互变动,而不会影响程序执行结果;〔4〕default子句可以省略不用;1.1

ARM嵌入式系统简介4.4

STM32F103XX的流程控制语句47在ARM嵌入式程序代码中,循环结构是一种很重要的控制语句。其特点是在给定条件成立时,反复执行某程序段,直到条件不成立为止。其中,给定的条件被称为循环条件,反复执行的程序段称为循环体。通常情况下,ARM嵌入式系统中向用户提供了以下四种循环语句。用户可以使用这些循环语句组成各种不同形式的循环结构,具体如下所示:〔1〕用goto语句和if语句构成循环;〔2〕用while语句;〔3〕用do-while语句;〔4〕用for语句;1.1

ARM嵌入式系统简介4.4.3ARM中的循环控制语句4.4

STM32F103XX的流程控制语句48顺序程序设计选择结构程序设计循环结构程序设计利用函数处理批量数据利用函数模块化程序设计1.1

ARM嵌入式系统简介4.4

STM32F103XX的流程控制语句

4.5C语言与汇编语言混合编程在C程序和ARM汇编程序之间相互调用时必须遵守ATPCS规那么。ATPCS规定了一些子程序间调用的根本规那么,比方:1.存放器的使用规那么子程序之间通过存放器r0~r3来传递参数,当参数个数多于4个时,使用堆栈来传递参数。在子程序中,使用存放器r4~r11保存局部变量。存放器r12用于保存堆栈指针SP,当子程序返回时使用该存放器出栈,记作IP。存放器r13用作堆栈指针,记作SP。存放器r14称为链接存放器,记作LR。该存放器用于保存子程序的返回地址。存放器r15称为程序计数器,记作PC。

4.5汇编语言和语言混合编程

4.5C语言与汇编语言混合编程2、堆栈的使用规那么堆栈采用满递减类型〔FD,FullDescending〕,即堆栈通过减小存储器地址而向下增长,堆栈指针指向内含有效数据项的最低地址。3、参数的传递规那么整数参数的前4个使用r0~r3传递,其他参数使用堆栈传递;浮点参数使用编号最小且能够满足需要的一组连续的FP存放器传递参数子程序的返回结果为一个32位整数时,通过r0返回;返回结果为一个64位整数时,通过r0和r1返回;依此类推。结果为浮点数时,通过浮点运算部件的存放器F0、D0或S0返回汇编程序调用C程序的方法为:首先在汇编程序中使用IMPORT伪指令事先声明将要调用的C语言函数;然后通过BL指令来调用C函数。例如在一个C源文件中定义了如下求和函数:intadd(intx,inty){return(x+y);}调用add()函数的汇编程序结构如下:

IMPORTadd;声明要调用的C函数…MOVr0,1MOVr1,2BLadd;调用C函数add4.5C语言与汇编语言混合编程

4.5.2汇编程序调用C程序的方法C程序调用汇编子程序的方法为:首先在汇编程序中使用EXPORT伪指令声明被调用的子程序,表示该子程序将在其他文件中被调用;然后在C程序中使用extern关键字声明要调用的汇编子程序为外部函数。4.5C语言与汇编语言混合编程

4.5.2C程序调用汇编程序的方法例如在一个汇编源文件中定义了如下求和函数:EXPORTadd;声明add子程序将被外部函数调用…add;求和子程序addADDr0,r0,r1MOVpc,lr…在一个C程序的main()函数中对add汇编子程序进行了调用:externintadd(intx,inty);//声明add为外部函数voidmain(){inta=1,b=2,c;c=add(a,b);//调用add子程序…}在C语言中内嵌汇编语句可以实现一些高级语言不能实现或者高级语言不容易实现的功能以及时间紧迫的功能。内嵌的汇编器支持大局部ARM指令和Thumb指令,但是不支持诸如直接修改PC实现跳转的底层功能,也不能直接引用C语言中的变量。4.5C语言与汇编语言混合编程

4.5.3C语言中嵌套汇编语句的方法嵌入式汇编语句在形式上表现为独立定义的函数体,其语法格式为:__asm{指令[;指令]…[指令]}基于ARM的C语言与汇编语言混合编程举例举例:一个向串口不断发送0x55的例子。#include"..\inc\config.h"//将有关硬件定义的头文件包含进来unsignedchardata;//定义全局变量voidMain(void){ Target_Init();//对目标板的硬件初始化

Delay(10);//延时

data=0x55;//给全局变量赋值

while(1){Uart_Printf("%x",data);//向串口送数

Delay(10);}}…IMPORTMainAREAInit,CODE,READONLY;ENTRY…BLMain;跳转到Main()函数处的C/C++程序…END;标识汇编程序结束启动代码的整体框架C语言写的主函数55硬件启动程序的工作一般包括:〔1〕分配中断向量表〔2〕初始化存储器系统〔3〕初始化各工作模式下的堆栈〔4〕初始化有特殊要求的硬件模块〔5〕初始化用户程序的执行环境〔6〕切换处理器的工作模式〔7〕呼叫主应用程序第四章STM32F103XX程序设计4.6基于ARM的硬件启动程序中断地址复位0x00未定义0x04软件中断0x08预取中止0x0C数据中止0x10保留0x14IRQ0x18FIQ0x1CARM要求中断向量表必须放置在从0x0地址开始的连续32个字节空间内。AREAInit,CODE,READONLYENTRYBResetHandlerBUndefHandlerBSWIHandlerBPreAbortHandlerBDataAbortHandlerB.BIRQHandlerBFIQHandler

中断向量表的程序通常如下

温馨提示

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

评论

0/150

提交评论