arm原理与c程序设计 第六章

上传人:a**** 文档编号:243345135 上传时间:2024-09-21 格式:PPT 页数:212 大小:1.54MB
返回 下载 相关 举报
arm原理与c程序设计 第六章_第1页
第1页 / 共212页
arm原理与c程序设计 第六章_第2页
第2页 / 共212页
arm原理与c程序设计 第六章_第3页
第3页 / 共212页
点击查看更多>>
资源描述
单击此处编辑母版标题样式,第六章,C 语言程序设计,第六章C 语言程序设计,6.1 C程序框架实例,6.2 SDRAM重定位技术,6.3 C语言语法,6.4 混合语言程序设计,6.5 中断效劳程序设计,本章小结,6.1 C程序框架实例6.1.1 跑马灯工程设计 进入RealView MDK集成开发环境,通过点击菜单“Project | New uVision Project,创立新工程ex6_1,保存目录为E:ARM9BOOKex6_1,添加启动代码文件到工程ex6_1中。编写C程序,并添加到工程ex6_1中。此时,工程ex6_1的主界面如图6-1所示。,图6-1 工程ex6_1的主界面,工程ex6_1中的文件代码罗列于小节中。翻开工程选项,设置其“Target页签如图6-2所示。,图6-2 目标选项卡设置,图6-2说明,NAND FLASH只使用了低32MB,SDRAM使用了高32MB。然后,设置“Output、“Debug和“Utilities页签如第四章图4-28、图4-9、图4-10以及图4-16图4-19所示。设置“Linker页签如图6-3所示。,图6-3 连接选项卡设置,此时,先不要编译工程ex6_1,需要按图6-4至图6-10配置启动代码文件。,图6-4 堆、栈、中断向量表和看门狗配置,图6-5 时钟管理器配置一,图6-6 时钟管理器配置二,图6-7 存储器配置一,图6-8 存储器配置二,图6-9 存储器配置三和I/O口配置一,图6-10 I/O口配置二,图6-7至图6-9中,Bank2Bank5的配置与Bank1的相同,Bank7的配置与Bank6的相同。最后,修改文件的第09781043行,即从“IF PIO_SETUP0开始的行,修改为如下所示代码:IF PIO_SETUP 0 LDR R14, =PIO_BASEIF PIOA_SETUP 0 ADR R0, PIOA_CFGLDR R2, R0 ; Added by ZY STR R2, R14, #PCONA_OFS ; Changed by ZY ENDIF,IF PIOB_SETUP 0 ADR R0, PIOB_CFGLDR R2, R0 ; Added by ZY LDR R1, R0,#4 STR R2, R14, #PCONB_OFS ; Changed by ZY STR R1, R14, #PUPB_OFS ENDIF IF PIOC_SETUP 0 ADR R0, PIOC_CFGLDR R2, R0; Added by ZY,LDR R1, R0,#4 STR R2, R14, #PCONC_OFS ; Changed by ZY STR R1, R14, #PUPC_OFS ENDIF IF PIOD_SETUP 0 ADR R0, PIOD_CFGLDR R2, R0; Added by ZY LDR R1, R0,#4 STR R2, R14, #PCOND_OFS; Changed by ZY STR R1, R14, #PUPD_OFS ENDIF,IF PIOE_SETUP 0 ADR R0, PIOE_CFGLDR R2, R0 ; Added by ZY LDR R1, R0,#4 STR R2, R14, #PCONE_OFS; Changed by ZY STR R1, R14, #PUPE_OFS ENDIF IF PIOF_SETUP 0 ADR R0, PIOF_CFG LDR R2, R0 ; Added by ZY,LDR R1, R0,#4 STR R2, R14, #PCONF_OFS; Changed by ZY STR R1, R14, #PUPF_OFS ENDIF IF PIOG_SETUP 0 ADR R0, PIOG_CFG LDR R2, R0 ; Added by ZY LDR R1, R0,#4 STR R2, R14, #PCONG_OFS; Changed by ZY STR R1, R14, #PUPG_OFS ENDIF,IF PIOH_SETUP 0 ADR R0, PIOH_CFG LDR R2, R0 ; Added by ZY LDR R1, R0,#4 STR R2, R14, #PCONH_OFS; Changed by ZY STR R1, R14, #PUPH_OFS ENDIF ENDIF,现在,编译连接并下载工程ex6_1,可以看到UP-NETARM2410实验箱上的LED13循环依次闪烁,实现了跑马灯的功能。工程ex6_1只有两个文件,即和,其中,文件在前几章已经讲述了,这里把该文件的完整代码附于附录四,供读者对照参考;文件将在下一小节中介绍。,6.1.2 跑马灯程序解释,C语言文件的代码如下:1 #define GPCDAT_ADDR (*(volatile unsigned int *)0x56000024)2 #define LED1_MASK 0x20 3 #define LED2_MASK 0x404 #define LED3_MASK 0x805 6 void Delay(int n)7 8 int i,j;,9 for(i=0;in;i+)10 11 for(j=0;jn;j+)12 13 14 15 16 17 int main()18 19 int nLED;,20 nLED = 0;21 while(1)22 23 nLED = 0;24 nLED =(LED2_MASK | LED3_MASK);/ LED1 light25 GPCDAT_ADDR = nLED;26 Delay(0x300);27 28 nLED = 0;29 nLED =(LED1_MASK | LED3_MASK); / LED2 light30 GPCDAT_ADDR = nLED;,31 Delay(0x300);32 33 nLED = 0;34 nLED =(LED1_MASK | LED2_MASK);/ LED3 light35 GPCDAT_ADDR = nLED;36 Delay(0x300);37 38 39 40 ,上述程序代码按行解释如下:第1行:定义C口的数据存放器地址,该地址固定为0x56000004。第24行:定义LED13灯的屏蔽位,对应于第57位,为1时灭,为0时亮。第615行:延时子程序。第17行:主函数,格式应该为int main()的形式,MDK要求函数返回值为int,但是,不要求函数有return语句(返回值)。函数名为main,是由于中的跳转至C语言程序时使用了标号_main。,ARM的C语言程序设计中没有主函数的概念,如果中跳转标号为_C_Entry,那么函数名应为C_Entry。 第1920行:定义整型量nLED,并赋为0。第21行:死循环。第2326行:只有LED1亮,并延时一段时间。第2831行:只有LED2亮,并延时一段时间。第3336行:只有LED3亮,并延时一段时间。,6.1.3 C程序框架 基于RealView MDK设计ARM芯片级的C程序,需要考虑系统初始化、接口初始化、控制算法和数字信号处理算法等,一般地,系统初始化代码由汇编语言编写,至少异常向量表由汇编语言编写,其他局部均可由C语言实现。从程序与硬件的联系方面考虑,ARM程序可以分为两局部:其一为与硬件密切相关的系统初始化和接口设计;其二为与硬件无关的控制信号和数字信号处理算法。,C程序框架是指实现了前一局部功能的程序工程,且该工程尽可能地用C语言编写,能实现系统初始化和几乎所有硬件接口的抽象,以变量的形式向算法提供接口。在C程序框架的根底上,只需要添加C语言控制算法或数字信号处理算法即可以实现相应的功能。新建工程ex6_2(与工程ex6_1相同),在中添加数组赋值语句,并添加一个头文件。工程ex6_2如图6-11所示。,图6-11 工程ex6_2的工作界面,工程ex6_2中头文件的代码如下:1 / filename: 2 float mysin(float v)3 4 float res;5 res=vv*v*v/6+v*v*v*v*v/120v*v*v*v*v*v*v/(7*6*120);6 return res;7 主程序文件代码如下:1 #include ,2 3 #define GPCDAT_ADDR (*(volatile unsigned int *)0x56000024)4 #define LED1_MASK 0x20 5 #define LED2_MASK 0x406 #define LED3_MASK 0x807 8 int arr10=1,2,3,4,5,6,7,8,9,10;9 10 void Delay(int n)11 12 int i,j;,13 for(i=0;in;i+)14 15 for(j=0;jn;j+)16 17 18 19 20 21 int main()22 23 int nLED;,24 int i;25 26 float val = mysin(1.57f);27 28 for(i=0;i10;i+)29 arri=arri*arri;30 31 32 nLED = 0;33 while(1)34 ,35 /Rand3();36 nLED = 0;37 nLED =(LED2_MASK | LED3_MASK); / LED1 light38 GPCDAT_ADDR = nLED;39 Delay(0x300);40 41 nLED = 0;42 nLED =(LED1_MASK | LED3_MASK); / LED2 light43 GPCDAT_ADDR = nLED;44 Delay(0x300);45,46 nLED = 0;47 nLED =(LED1_MASK | LED2_MASK);/ LED3 light48 GPCDAT_ADDR = nLED;49 Delay(0x300);50 51 52 53 工程ex6_2展示头文件及函数调用方法,在此根底上,再添加各种中断响应效劳程序,即可构成一个典型的C程序框架工程。中断效劳程序设计将在第节中介绍,绝大局部控制功能和数据处理算法应放在中断效劳程序中完成。,6.2 SDRAM重定位技术,UP-NETARM2410实验箱支持从NAND型FLASH启动,前面所有的工程均是将执行代码下载到NAND型FLASH芯片K9F1208中,并在FLASH中运行的。SDRAM重定位技术是指上电复位后,FLASH映射到地址0x00000000开始的区段,代码从FLASH开始执行,代码初始化系统完毕后,将FLASH代码搬移到SDRAM中,并把SDRAM映射到地址0x00000000开始的区段,程序代码从SDRAM运行。由于SDRAM访问速度快,所以,实际的工程文件均需要进行SDRAM重定位。,新建工程ex6_3,其中包括的文件与工程ex6_2完全相同。修改ex6_3工程目标选项卡,如图6-12所示,即ROM1映射到0x00x1000000,RAM1映射到0x10000000x2000000。,图6-12 工程ex6_3目标选项卡,修改启动代码文件的配置向导如图6-13所示,即中断向量表的地址修改为0x010FFF20处。,图6-13 启动代码设置向导,在启动代码文件的代码中添加代码段,如图6-14所示。,图6-14 横线中间的代码为添加的代码段,图6-14中第10441055行的代码表示将FLASH中从0x00x1000的代码拷贝到SDRAM的0x300000000x30001000处。如果想把图6-12中设置的ROM空间内容全部拷贝到SDRAM中,只需要将第1048行的0x1000修改为0x01000000即可。这里,由于工程ex6_3的代码长度缺乏0x1000,故只需拷贝FLASH的0x00x1000存储区。第10561060行的代码为设置协处理器p15的存放器13,使SDRAM的0x300000000x32000000映射到0x00x2000000处。这样,SDRAM被重定位到地址0x0处,使得代码在SDRAM中执行。,这样,在SDRAM重定位后,图6-12中的配置表示SDRAM的低16MB用于存放只读的可执行代码,而高16MB用于存储可读写的数据。这样配置的工程,SDRAM中有32MB没有使用。如果想使得SDRAM的低16MB存放代码,而高48MB存放数据,可采用如图6-15所示配置。无论采用图6-12还是图6-15所示配置,64MB的FLASH存放程序代码(代码长度可从HEX文件中查到)后,还有大量充裕的空间,这些空间在SDRAM重定位后,均可用作永久性存储空间使用,在编程这些空间时,切记不可编程已写入代码的区块。在第节将介绍K9F1208的编程方法。,图6-15 工程目标选项卡,6.3 C语言语法6.3.1 数据类型在ARM的C语言程序设计中,具有char、short、int、long、float、long long以及double等根本数据类型,分别表示8位、16位、32位、32位、32位、64位以及64位的数据,每种数据可以加上unsigned表示无符号型。同时,ARM的C语言支持结构体以及基于根本数据类型的自定义数据类型,自定义数据类型使用typedef关键字,例如:,typedef int INT32;需要注意的是,在通用C编程时,针对浮点数,人们更偏爱double;而在ARM的C程序设计中,由于float占32位,double占64位,ARM为32位机,故人们更倾向于使用float。例如,定义一个单精度浮点数变量,并初始化为,其语句如下:float PI = 3.14159f;众所周知,上述语句为定义一个常数,这里一般定义它为常量,即const float PI = 3.14159f;在ARM的C程序中,最常用的数制为32位的十六进制数,以0x开头,例如:0x30000000、0x10、0x800等。,常量也称为常数,对应的地址空间的内容保持不变;而变量是指ARM内存中可变内容的地址,定义例如如下:char ch_1;short sh_2;long lg_3;float fl_4;unsigned int * p1;变量名和常量名必须为字符或以下划线开头。工程ex6_3中的中出现过以下语句:#define GPCDAT_ADDR (*(volatile unsigned int *)0x56000024),表示地址0x56000024的值,而(*(volatile unsigned int *)0x56000024) = 0x0;表示地址0x56000024的值赋为0x0,这里volatile表示该地址标号固定不变,不会被编译器优化掉,用于外设存放器地址等固定地址访问时使用,一般的内存地址,可以直接使用unsigned int *。数据类型中最常用的是指针,此外,数组和结构体用得也比较多。工程ex6_3的中定义了一个整型数组,并初始化如下:int arr10=1,2,3,4,5,6,7,8,9,10;在主函数中用for循环对该数组进行了赋值,即,for(i=0;ish_fra1 = 0x1234;枚举和联合体类型与通用C语言的语法相同。例如,定义一个枚举型变量:,enum TrueOrFalse false, true;enum TrueOrFalse en_trueorfalse;枚举型变量从0开始算起,即false代表0,而true代表1。赋值方法如下:en_trueorfalse = false;联合体用得较少,不再举例。特别需要注意的是,在MDK中单精度浮点数需要在数值后添加“f!,6.3.2 常用运算符,C语言由函数组成,函数由语句组成,语句是指以分号结尾的表达式,表达式是指由常量或变量经过运算符连接起来的式子。常用的运算符包括赋值运算符、数学运算符、关系运算符、逻辑运算符、位运算符、sizeof运算符、逗号运算符、三元运算符、数组下标运算符、结构/联合成员运算符、结构/联合成员指针运算符、地址运算符、强制类型转换运算符等。,1赋值运算符赋值运算符只有一个,即“=。例如:int x1;x1 = 5;此外,赋值运算符可以和数学运算符结合,构成复合赋值运算符,例如:x1 = 0;x1+= 1;相当于 x1 = x1 + 1;复合赋值运算符主要有+=、=、*=、/=和%=等。,2数学运算符 数学运算符包括+(加)、 (减)、*(乘)、/(除)、%(取余)、+(加加)和 (减减)等。 假定变量a1为10,a2为3,那么依次执行以下语句:b1 = a1 + a2;b2 = a1 a2; b3 = a1 * a2; b4 = a1 % a2;b5 = a1 +;b6 = a1 ;b7 = + a1;b8 = a1;,上述运算结果为:b1=13,b2=7,b3=30,b4=1,b5=10,b6=11,b7=11,b8=10,全部执行完后,a1的值为10,a2的值为3。3关系运算符关系运算符可用于比较两个数值,关系表达式返回0表示假,返回1表示真,如表6-1所示。,运算符,含 义,示 例,值,=,等于,0x08=0x0A,0,!=,不等于,0x08!=0x0A,1,大于,0x0A0x08,1,=,大于等于,0x0A=0x08,1,小于,0x0A0x08,0,=,小于等于,0x08(右移)位运算符主要用于整型数据。,6sizeof运算符,sizeof运算符返回一个变量或类型占有存储空间的字节数,例如:struct numStruct int i1; float f1; double d1;struct numStruct num1;struct numStruct *num2;int iS1=sizeof(num1);int iS2=sizeof(num2);int iS3=sizeof(float);,上述语句执行完后,iS1 = 16,iS2 = 4,iS3 = 4。因为,整型占4个字节,单精度浮点型占4个字节,双精度浮点型占8个字节,指针类型占4个字节。7逗号运算符 使用逗号“,连接起来的表达式,按从左向右的次序依次计算各个表达式的值,整个逗号表达式的值为最后一个表达式的值,例如: i=(num1.i1=5),sizeof(short);执行完后,num1结构体的成员i1为5,但i的值为2。,8三元运算符C语言中仅有一个三元运算符,或称三目运算符 ,即“? :,它有三个参加运算的元素,而且有返回值,调用格式为:(表达式)?(值1):(值2)其功能是先判断“表达式的真假,为真时返回“值1,为假时返回“值2。例如,求两个整数a和b的最大值:int a,b,c;a = 0x56;b = 0x78;c = (ab)?a:b;其运算结果为c = 0x78,即为b的值。,9数组下标运算符数组下标运算符用“ 表示,通过这个运算符可以访问数组中任意位置的元素,例如如下:short sh_a10;sh_a8 = 0x1234;数组下标从0开始算起,上述数组sh_a的第一个元素为sh_a0,最后一个元素为sh_a9。,10结构/联合成员运算符结构体或联合体成员运算符为“.,该运算符也用于C+的对象成员访问中,例如如下:struct st_table short sh_ord; float fl_val;struct st_table st_table_list; = 0x01; = 0.7329; / 赋值,11结构/联合成员指针运算符 结构体或联合体指针运算符为“-,例如如下:struct st_table short sh_ord; float fl_val;struct st_table *st_table_list2; st_table_list2-fl_val = 0.7329; / 赋值,12地址运算符 地址运算符“上述语句执行后,sh_org = 0x10。,13强制类型转换运算符不同类型之间可以相互赋值,例如,short型和int型之间可以相互赋值。在C程序中,不同类型的变量间赋值时不可能产生溢出的情况下赋值是允许的,例如,short型变量赋给int型变量。相反情况下赋值,例如,int型变量赋给short型变量那么可能出现截断现象,此时编译器会给出警告信息,这种情况下,必须采用显式的强制类型转换方法,即在变量前添加变量类型,如下:,short sh_val1, sh_val2;int int_val = 0x1234;float fl_val = 78.8; sh_val1 = (short)int_val;sh_val 2= (short)fl_val;执行完上述语句后,sh_val1 = 0x1234,sh_val2 = 78,6.3.3 程序控制语句 函数是C程序的组成单元,语句又是函数的根本单元。C程序的语句组有三种执行方式,即顺序、分支和循环。无论功能如何强大的C程序,在程序流程上只有这三种方式。1顺序结构 顺序执行是最根本的程序执行方式,容易被接受和理解。顺序结构形式的语句组中,语句是依次被执行的,即前一条语句执行完后,再去执行下一条语句。,2分支结构 分支结构形式的语句组中,通过判断关系式或逻辑表达式的值,决定哪些语句将被执行,哪些语句不会被执行。有两种实现形式,即if结构和switch结构。if结构的根本形式为:if(表达式) 语句组1else 语句组2,当语句组1或语句组2中只有一个语句时,上述花括号“可以去掉。当表达式的值为真时,执行语句组1;否那么,执行语句组2。当判断条件表达式较多时,可以用以下形式,如图6-16所示:图6-16 分支结构if(表达式1) 语句组1else if(表达式2) 语句组2,else if(表达式n) 语句组nelse 语句组n+1 if语句支持嵌套,二级if嵌套的典型形式如下:if(表达式1), if(表达式11) 语句组11else 语句组12else if(表达式2), if(表达式21) 语句组21 else 语句组22 else if(表达式3),if(表达式31) 语句组31 else 语句组32 ,else 语句组4if语句亦支持多级嵌套。if语句可以没有else局部。switch语句的语法如下:switch(表达式) case 常量表达式1: 语句组1; break;,case 常量表达式2: 语句组2; break; case 常量表达式3: 语句组3; break; case 常量表达式n: 语句组n; break; default: 语句组n+1;,图6-16 分支结构,当switch关键字后的表达式值为某一常量表达式的值时,程序会跳转到相应的语句组去,执行完该语句组后,将通过执行“break;语句跳出switch语句。如果有多种情况对应于同一组操作时,可以使用如下形式:case 常量表达式2: case 常量表达式21:case 常量表达式22:语句组2;break;,上述语句中,表达式的值为常量表达式2、21或22中的某一个时,都将执行语句组2。当switch语句中的表达式的值不等于case中任一值时,那么执行default后的语句,并且,default语句可以省略。3循环结构C语言语句循环模式有三种,即当型循环、直到型循环和指定次数或条件的循环,均可以用来实现死循环,而且,循环可以多级嵌套。循环结构如图6-17所示。,图6-17 三种循环模式,(a) 当型循环; (b) 直到型循环; (c) 指定次数或条件的循环,实现循环的C语句如下:1) goto语句goto语句实现循环的一般格式为:g_Label: / 指定一个标号 语句组; goto g_Label;跳出循环的方法为:g_L1: 语句组1; if(条件表达式) break; 语句组2;goto g_L1;,关键字break可用于跳出循环,即结束循环;另一个关键字continue用于跳出本次循环,而从循环头再继续下一次循环。在结构化语言程序设计中,goto语句普遍不受欢送,但是,在一些多级循环嵌套中,使用goto跳出循环体是有效的方法。在ARM的C程序中,goto语句可以使用。2) while语句while语句实现的循环体有两种,即while(条件表达式1) 语句组1; / 当条件表达式1为真时循环执行语句组1,为假时跳出循环,或do 语句组2;while(条件表达式2) / 当条件表达式2为真时循环执行语句组2,为假时跳出循环 上述循环体的不同之外在于“do while();该结构中语句组2至少可以执行一次,而“while()结构中,当表达式1为假时,语句组1得不到执行。常用如下形式实现死循环,即,while(1) 语句组;3) for语句for语句实现的循环体如下:for(表达式1 ; 循环条件 ; 表达式2) 语句组;,表达式1在开始for循环时计算,表达式2从第二次循环起每次循环时都计算,循环条件在每次循环时都判断。当循环条件为假时,跳出循环,因此,语句组有可能一次也得不到执行。可以在语句组中添加break关键字,跳出循环体,该关键字只能跳出一级循环体;可以添加continue语句跳出本次循环。“表达式1、“循环条件以及“表达式2均可省略,但是“;号不能省略。例如,下面的形式可构成死循环:for(;) 语句组;,6.3.4 C语言函数C语言函数由函数头部和函数体组成,函数头部常被复制到主函数前作为函数的声明,即函数原型,告诉编译器该函数的主体在主函数后面定义了。语法形式如下:返回类型 函数名(形式参数列表) 函数体; 返回类型可以为根本数据类型,也可以为扩展的数据类型或空类型。当函数有返回值时,使用return语句。,形式参数列表可以为空,也可以有多个,用来向函数体内部传递数据或地址。形式参数和函数体内部定义的变量均为局部变量,它们的作用域仅限于函数体内部,而定义于主函数的变量或主函数体外的变量(又称全局变量),其作用域为从定义开始到主函数结束或主程序结束。调用函数时,必须用实际的数据变量代替形式参数(形参),这些实际的变量称为实参。实参对形参的传递方式有两种:其一为传值方式;其二为传址方式。,在传值方式中,实参的值传给形参,形参在函数体内参与运算受到改变时,不会影响到实参的值,这时,实参和形参占用完全不同的地址空间;在传址方式中,实参的地址传给了形参,实参和形参存储在同一个地址空间,对形参的修改就是对实参的修改。当函数需要有多个返回值时,往往需要采取传址的函数工作方式,主要针对指针和引用类型参数。C语言支持递归调用,即函数可以调用其本身。一个著名的例子如下:int iFib(int iNum),if(iNum 0.75)14 led3=led3+1;15 else 16 led2=led2+1;17 end18 x0=y0;19 end20 disp( led1= );disp(led1);21 disp(led2= );disp(led2);22 disp(led3=);disp(led3);,根据上述程序设定了左右阈值为和。在RealView MDK中新建工程ex6_4(与工程ex6_3相同),修改文件,该文件源码如下:1 #define GPCDAT_ADDR (*(volatile unsigned int *)0x56000024)2 #define LED1_MASK 0x20 3 #define LED2_MASK 0x404 #define LED3_MASK 0x805 6 float logistic4(float); / function protype,7 void Delay(int n) / Delay function8 9 int i,j;10 for(i=0;in;i+)11 12 for(j=0;jn;j+)13 14 15 16 ,17 float x0;18 float y0;19 20 int main()21 22 int nLED;23 x0 = 0.22f;24 25 while(1)26 27,28 y0=logistic4(x0);29 30 nLED = 0;31 32 if(y00.75f)37 ,38 nLED =(LED1_MASK | LED2_MASK);/ LED3 light39 40 else41 42 nLED =(LED1_MASK | LED3_MASK); / LED2 light43 44 45 GPCDAT_ADDR = nLED;46 Delay(0x500);47 x0 = y0;48,49 50 51 52 float logistic4(float x0)53 54 float y0;55 y0=4.0f*x0*(1.0f - x0);56 57 return y0;58 此时,工程ex6_4的工作窗口如图6-18所示。,图6-18 工程ex6_4的工作界面,6.3.6 演示实例二 新建工程ex6_5(与工程ex6_4完全相同),修改文件,使用代码如下所示:1 #include “2 3 #define GPCDAT_ADDR (*(volatile unsigned int *)0x56000024)4 #define LED1_MASK 0x20 5 #define LED2_MASK 0x406 #define LED3_MASK 0x807,8 float logistic4(float);/ Function protype9 10 void Delay(int); / Delay function11 12 float x0;13 float y0;14 15 double valx1;16 int main()17 ,18 int nLED;19 20 x0 = mysin(0.57f); /0.22f;21 22 23 while(1)24 25 26 y0=logistic4(x0);27 28 nLED = 0;,29 30 if(y00.75f)35 36 nLED =(LED1_MASK | LED2_MASK);/ LED3 light37 ,38else39 40 nLED =(LED1_MASK | LED3_MASK); / LED2 light41 42 43 GPCDAT_ADDR = nLED;44 Delay(0x500);45 x0 = y0;46 47 48 ,49 50 51 float logistic4(float x0)52 53 float y0;54 y0=4.0f*x0*(1.0f - x0);55 56 return y0;57 58 59,60 void Delay(int n) / Delay function61 62 int i,j;63 for(i=0;in;i+)64 65 for(j=0;jn;j+)66 67 68 69 ,编写头文件,在文件的右键弹出菜单中选中Include Dependencies,那么头文件在编译时自动添加到工程中。代码如下:/ filename: float mysin(float v) float res;res=vv*v*v*v*v*v*v/(7.0f*6.0f*120.0f);return res;,随着程序代码的增长,编译连接后的可执行文件越来越大,因此,需要修改图6-19中的R3。这里设置R3为0x100000,即假定可执行代码不会越过1MB;按图6-15的配置,最大可以设为16MB。R3的值越大,启动时间越长,因此,R3的最正确值为程序可执行代码的长度。,图6-19 FLASH到SDRAM的代码复制,此时的工程ex6_5如图6-20所示。,图6-20 工程ex6_5的工作界面,配置工程选项卡如图6-21至图6-23所示,没有改动的地方与工程ex6_4选项卡相同。这些配置的作用在于编译连接后的可执行代码全部为ARM指令,而不再是ARM与Thumb指令交叉的代码。在图6-22中,优化方法使用“或“level 3(-O3)。现在,可以编译连接并下载工程ex6_5到UP-NETARM2410实验箱的FLASH中,可以看到三个LED灯随机闪烁。,图6-21 “目标选项卡,图6-22 “C/C+选项卡,图6-23 “Asm选项卡,6.4 混合语言程序设计 从第节例子中可知,在ARM工程文件中,C语言程序和汇编语言程序可以并存,启动代码文件使用汇编语言编写,可以通过“BX R0地址跳转指令跳到C语言函数地址处执行C语言的程序。这说明第节的例子也属于混合语言程序设计。事实上,通过地址和参数传递,可以实现汇编语言跳转到C函数、汇编语言调用C函数、C函数中嵌套汇编语句、C函数调用汇编子程序等操作。相关的资料有“ARM Developer Suite Developer Guide等。本节重点介绍C函数嵌套汇编语句和C函数调用汇编子程序形式的混合语言程序设计方法。,6.4.1 C函数嵌套汇编语句 C函数中嵌套汇编语句,使用关键字“_asm,汇编语言中不能使用R0等操作符,只能使用C语言中定义的变量作为操作符,可能是.c文件在编译时没有定义R0
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 商业管理 > 商业计划


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!