您好,欢迎访问三七文档
当前位置:首页 > 行业资料 > 国内外标准规范 > (8) 第7章 C语言应用程序开发
单片机原理与应用CollegeofCommunicationEngineering,JilinUniversity第7章C语言应用程序的开发2CollegeofCommunicationEngineering,JilinUniversity本章提要7.1C语言是开发单片机应用软件的有力工具7.2开发嵌入式应用的C编译器的特点7.3建立C语言程序运行环境7.4函数的结构与函数间参数的传递7.5应用程序的模块化及其框架3CollegeofCommunicationEngineering,JilinUniversity本章提要7.1C语言是开发单片机应用软件的有力工具7.2开发嵌入式应用的C编译器的特点7.3建立C语言程序运行环境7.4函数的结构与函数间参数的传递7.5应用程序的模块化及其框架4CollegeofCommunicationEngineering,JilinUniversity7.1C语言是开发单片机应用软件的有力工具标准ANSIANSIC:通用计算机上有操作系统的C语言嵌入式C:C编译器需特殊处理与CPU硬件相关的内容,随着单片机系统程序空间的增大(可达4M),C语言的应用越来越广泛(4K)。μC/OS-II:实时操作系统RTOS,是指当外界事件或数据产生时,能够接受并以足够快的速度予以处理,其处理的结果又能在规定的时间之内来控制生产过程或对处理系统作出快速响应,并控制所有实时任务协调一致运行的操作系统。保证系统的实时性、可靠性和稳定性。嵌入式C的优势:移植性好、库函数丰富、可读性好、便于使用RTOS。汇编语言的优势:编写系统的硬件相关部分更直观、方便,代码少、执行速度快。常用于:•系统的初始化•中断向量的初始化,开、关中断•I/O口的输入输出函数•复位向量$FFFA~$FFFB5CollegeofCommunicationEngineering,JilinUniversity集成开发环境IDE:将应用程序的编辑、编译、链接、定位、调试等集成在一个大的软件包中,简化开发工作。但用户往往不清楚操作的原理。1.编辑程序源代码:*.c,*.asm,*.h;2.预编译:对源代码文件中的文件包含(include)、预编译语句(#define)等进行分析、检查声明、定义的完整性,转换成C编译器可接受的格式;3.编译:检查和报告相关的语法错误,然后将C程序转换成汇编器可接受的代码。4.汇编:生成针对某种CPU的汇编浮动代码文件,*.obj;5.链接:将浮动的*.obj文件模块按指定顺序链接起来,并且将所用到的C语言标准库函数也从各自所在的函数库中调出,把*.obj文件中缺失的那些参数补上,*.prm;6.定位:根据目标系统硬件的情况,给程序分配程序空间的地址、数据空间的地址以及程序运行的起始地址等,生成可执行的目标代码,*.abs,*.sx;7.下载:将*.sx文件下载到单片机的程序空间的相应地址内;8.调试、运行9.反汇编:将目标代码反汇编成汇编语言,以便用户对应用程序中特别关键的部分进一步优化(project-Disassemble)。7.1C语言是开发单片机应用软件的有力工具6CollegeofCommunicationEngineering,JilinUniversity编辑、编译、链接、定位反编译器C源文件汇编源文件库文件目标文件C编译器汇编编译器链接器执行文件映射文件列表文件汇编反编译文件链接配置文件*.h*.c*.c++*.asm*.inc*.prm*.obj*.lst*.map*.sx*.abs7CollegeofCommunicationEngineering,JilinUniversity本章提要7.1C语言是开发单片机应用软件的有力工具7.2开发嵌入式应用的C编译器的特点7.3建立C语言程序运行环境7.4函数的结构与函数间参数的传递7.5应用程序的模块化及其框架8CollegeofCommunicationEngineering,JilinUniversity7.2开发嵌入式应用的C编译器的特点×inta=5;function(){a+=3;}√inta;function(){a=5;a+=3;}不使用初始化变量在嵌入式应用中,程序固化在ROM中,并直接在ROM中运行。开机或复位时,RAM中的内容是随机的。因此,不存在初始化变量和默认值。微控制器的编程是围绕存储器的:代码保存在存储器中变量使用存储器外设的控制实际是通过对存储器的访问来实现9CollegeofCommunicationEngineering,JilinUniversity7.2开发嵌入式应用的C编译器的特点注意变量的数据类型1、RAM空间有限,选择适合变量取值范围的数据类型,尤其是数组;适合的数据类型能节省代码长度,缩短执行周期;Signed/unsignedchar/int/short/long每个数据类型都用特定的范围如下,2、避免使用浮点数和双精度3、C语言数据类型的位宽取决于单片机的类型和具体的IDE中的约定;如codewarrior中工程窗口中的“target”标签下“standard”对话框中“complierfor”中“Typesizes”按钮对应的对话框。10CollegeofCommunicationEngineering,JilinUniversity7.2开发嵌入式应用的C编译器的特点4、尽量不调整编译器默认的数据类型的位宽,避免使用原始的数据类型,而是通过声明统一化的间接数据类型。#typedefunsignedcharu8_t#typedefintu16_t#typedefunsignedlongu32_tu16_ta;function(){a=5;a+=3;}11CollegeofCommunicationEngineering,JilinUniversity7.2开发嵌入式应用的C编译器的特点注意函数的可重入性在多任务环境下,允许某个函数同时被一个以上的任务调用,称该函数具备可重入性。如果知道某个库函数中使用了全局变量,就可以认为这个函数是不可重入的。12CollegeofCommunicationEngineering,JilinUniversity本章提要7.1C语言是开发单片机应用软件的有力工具7.2开发嵌入式应用的C编译器的特点7.3建立C语言程序运行环境7.4函数的结构与函数间参数的传递7.5应用程序的模块化及其框架13CollegeofCommunicationEngineering,JilinUniversity7.3建立C语言程序运行环境C语言的主程序从main()开始,必须为main()建立一个程序运行环境,主要完成四件事情:1、设置栈指针初值2、相关硬件的系统初始化3、调用函数main()使之执行4、给出main()完成后的出口,即执行exit()。最简情况下,只需1、3。CodeWarrior默认在RAM低地址保留栈空间;硬件的初始化通常包括相关寄存器初始化、时钟初始化、串行口初始化等;实际应用中,应用程序往往是一个死循环,不用4。调试时,可以把监控程序的热启动地址作为出口;14CollegeofCommunicationEngineering,JilinUniversity7.3建立C语言程序运行环境CodeWarrior自动生成Start12.c文件建立运行环境创建新工程过程中,选择了C编程语言后,有以下选择:1、选择最小化的startup代码2、选择小模式:适用于整个应用程序都在64KB寻址空间内的情况,若需分页,自行处理。3、Debug调试时,复位后单步执行,可以看到运行环境的建立过程。15CollegeofCommunicationEngineering,JilinUniversity本章提要7.1C语言是开发单片机应用软件的有力工具7.2开发嵌入式应用的C编译器的特点7.3建立C语言程序运行环境7.4函数的结构与函数间参数的传递7.5应用程序的模块化及其框架16CollegeofCommunicationEngineering,JilinUniversity7.4函数的结构与函数间参数的传递函数间传递参数通常有两种方法:使用全局变量和形参。1、全局变量全局变量从RAM低地址堆起。但由于CodeWarrior默认在RAM低地址保留栈空间,将堆栈视为第1个全局变量,所以全局变量紧随堆栈之后。例如:#includehidef.h/*commondefinesandmacros*/#includederivative.h/*derivative-specificdefinitions*/externvoiddelay1(unsignedintcountert);unsignedcharflag;……flag=0;CLR0X21000x2000~0x20FF为栈空间(STACKSIZE0x100)0x2100为定义的第一个全局变量flag的地址(见*.map文件)虽然使用全局变量传递参数非常方便,但在多任务环境下,多个任务访问某个全局变量会引起竞争(如中断服务程序和主程序都访问同一个全局变量)。17CollegeofCommunicationEngineering,JilinUniversity7.4函数的结构与函数间参数的传递2、局部变量局部变量是某个函数的“私有”变量,是在栈空间定义的,局部变量实际上是子程序要用到的一块内存空间。例如:voidmain(void){(SP=0x2100)__unsignedchari,settime;unsignedintj,m,n;(SP=0x20F8)__……}局部变量只在函数内部有意义,它所占用的一块栈空间在子程序返回前会释放掉,因此局部变量不涉及到参数传递。18CollegeofCommunicationEngineering,JilinUniversity7.4函数的结构与函数间参数的传递3、形式参数函数的形式参数也被安排在栈空间,参数传递是通过调用函数将值复制给被调用的形式参数实现的,即参数是通过堆栈传递的。使用的C编译器不同,参数进入堆栈的顺序以及最后一个参数或第一个参数保存在什么地方也会有所不同。CodeWarrior的传递规则:(1)返回参数:return(n)中的n值。charn,则在B寄存器;intn,则在D寄存器;其它类型,则返回一个指向n的指针,存在D寄存器。(2)定义函数:多个形参时,从右往左,第一个参数读D寄存器,其它依次读取以堆栈指针为基地址,加上2(绕过函数程序的返回地址)开始的堆栈空间内,左边第一个参数偏移量的值最大。DefinethefunctioninC:intAdd(inta,intb,intc){return(a+b+c);};Compilergenerate:PSHD;cLDD6,SP;aADDD4,SP;+bADDD0,SP;+cPULX;ReleaseRTS19CollegeofCommunicationEngineering,JilinUniversity7.4函数的结构与函数间参数的传递CodeWarrior的传递规则:(3)调用函数:调用函数前,从左边第一个参数开始,依次压入堆栈中,留最后一个参数在D中,然后调用函数,即将返回地址保存在堆栈中。CalltheFunctioninC:main(){d=Add(1,3,5);}LDAB#1;aCLRAPSHDLDAB#3;bPSHDLDAB#5;cBSRAdd;CallAdd()LEAS4,SP;Release:SP+=4(4)如果函数的形式参数数目是不确定的,调用函数时参数的入栈顺序和3相反,则编译器会从右往左将参数全部推入堆栈。20CollegeofCommunicationEngineering,JilinUniversity7.4函数的结构与函数间参数的传递实例分析延时子程序delay()21CollegeofCommunicationEngineering,Jil
本文标题:(8) 第7章 C语言应用程序开发
链接地址:https://www.777doc.com/doc-3479470 .html