第七章08C语言主要内容单片机的C语言编程概述标准C语言的基本语法08C语言的使用08C语言程序编程框架08C语言的编译过程08C编程技巧7.1单片机的C语言编程概述7.1单片机的C语言编程概述7.1.1单片机编程语言汇编语言优点:执行效率高,时序控制精确C语言优点:①程序开发速度快,提高开发工作效率;②软件调试直观;③可维护性好;④可移植性好(与汇编语言相比较)。7.1单片机的C语言编程概述7.1.2单片机C语言单片机C语言和标准C语言的用法基本相同,但是单片机C语言是针对于资源少的MCU,它的编程方法和编程手段与PC机上使用C语言还是有很大差别。返回7.2标准C语言的基本语法7.2标准C语言的基本语法7.2.1数据类型(1)基本类型表7-1C语言基本数据类型数据类型简明含义位数字节数值域signedchar有符号字节型81-128~+127unsignedchar无符号字节型810~255signedshort有符号短整型162-32768~+32767signedint有符号短整型162-32768~+32767unsignedint无符号短整型1620~65535signedlong有符号长整型324-2147483648~+2147483647unsignedlong无符号长整型3240~4294967295float浮点型3243.4E-38~3.4E+38double双精度型6481.7E-308~1.7E+3087.2标准C语言的基本语法7.2.1数据类型(2)构造类型构造类型有数组、结构、联合、枚举、指针和空类型。结构和联合是基本数据类型的组合。枚举是一个被命名为整型常量的集合。空类型字节长度为0,主要有两个用途:一是明确地表示一个函数不返回任何值;二是产生一个同一类型指针(可根据需要动态地分配给其内存)。7.2标准C语言的基本语法7.2.2运算符C语言的运算符与大多数计算机语言基本相同,分为:算术运算符逻辑运算符关系运算符和位运算符增量和减量运算符复合赋值运算符指针和地址运算符输出格式转换符7.2标准C语言的基本语法7.2.3流程控制(1)顺序结构顺序结构就是从前向后依次执行语句。从整体上看,所有程序的基本结构都是顺序结构,中间的某个过程可以是选择结构或循环结构。语句1语句2……语句N7.2标准C语言的基本语法7.2.3流程控制(2)选择结构①if结构(双分支):if(条件表达式)语句项;或if(条件表达式){语句块}else{语句块}语句1语句1条件表达式if真假7.2标准C语言的基本语法7.2.3流程控制(2)选择结构②switch结构(多分支):switch(表达式){case常数1:语句项1;break;case常数2:语句项2;break;……default:语句项n}表达式语句项1语句项2……语句项Nswitch常数1常数2……default7.2标准C语言的基本语法7.2.3流程控制(3)循环结构①for循环:for(表达式1;表达式2;表达式3){语句}表达式2求解表达式1语句求解表达式3For语句的下一个语句for真假7.2标准C语言的基本语法7.2.3流程控制(3)循环结构②while循环:while(表达式){语句}表达式语句while真假7.2标准C语言的基本语法7.2.3流程控制(3)循环结构③do....while循环do{语句}while(表达式);表达式2语句do假真7.2标准C语言的基本语法7.2.3流程控制(4)break语句和continue语句在循环中常常使用break语句和continue语句,这两个语句都会改变循环的执行情况。break语句用来从循环体中强行跳出循环,终止整个循环的执行;continue语句只用来结束本次循环。7.2标准C语言的基本语法7.2.4函数(1)函数定义类型标识符函数名(类型参数1,类型参数2,类型参数3,……){说明部分语句}(2)函数的声明类型标识符函数名(类型[参数1],类型[参数2],类型[参数3],……);(3)函数的返回值return表达式;return语句用来立即结束函数,并返回一确定给调用程序。如果函数的类型和return语句中表达式的值不一致,则以函数类型为准。对数值型数据,可以自动进行类型转换。7.2标准C语言的基本语法7.2.5指针(1)指针变量的定义类型说明符*变量名;(2)指针变量的赋值指针变量同普通变量一样,使用之前不仅要定义说明,而且必须赋予具体的值。未经赋值的指针变量不能使用,否则将造成系统混乱,甚至死机。指针变量的赋值只能赋予地址。(3)指针的运算•取地址运算(&)•取内容运算(*)•加减算术运算:针对指针数组变量进行7.2标准C语言的基本语法7.2.6结构体(1)结构体的说明和结构体变量的定义①struct结构体名②struct结构体名{成员列表};{成员列表}结构体变量;(2)结构体变量的使用结构体变量也可以象其它类型的变量一样赋值运算,不同的是结构体变量以成员作为基本变量。结构体成员的表示方式为:结构体变量.成员名(3)结构体指针结构体指针是指向结构体的指针。结构体指针对结构体成员的访问表示为:结构体指针名-结构体成员7.2标准C语言的基本语法7.2.7编译预处理(1)宏定义#define宏名表达式(2)条件编译#if表达式#else表达式#endif(3)“文件包含”处理“文件包含”是指一个源文件将另一个源文件的全部内容包含进来,其一般形式为:#include“文件名”7.2标准C语言的基本语法7.2.8用typedef定义类型typedef用来定义新的类型名来代替已有的类型名:typedef类型名新的类型名;说明:①用typedef可以定义各种类型名,但不能用来定义变量。②用typedef只是对已经存在的类型增加一个类型名,而没有创造新的类型。③当不同源文件中用到各种类型数据(尤其是像数组、指针、结构体、共用体等较复杂数据类型)时,常用typedef定义一些数据类型,并把它们单独存放在一个文件中,而后在需要用到它们的文件中用#include命令把它们包含进来。返回7.308C语言的使用7.308C语言的使用7.3.1寄存器和I/O口的使用使用08C语言,大部分寄存器都可以直接操作,但对寄存器A、HX、CCR和SP的操作只能通过嵌入汇编代码来完成。(1)I/O口和寄存器的定义在08C语言中操作寄存器及I/O口时,通常预先在头文件中使用宏定义,其定义方法如下:#define寄存器名*(volatileunsignedchar*)寄存器地址#defineI/O口名*(volatileunsignedchar*)I/O口地址(2)I/O与寄存器的操作使用上面定义的I/O口或寄存器宏,可以方便对I/O置高低电平或读取I/O的状态,读写寄存器。7.308C语言的使用7.3.2使用汇编指令在08C语言中,使用汇编代码有两种方法:(1)asm(“汇编指令”)(2)定义汇编子程序定义格式如下:_子程序名代码…rts7.308C语言的使用这种使用方法要注意以下几点:①在子程序名前加‘_’;②汇编子程序只能放在*.s文件中,然后将该文件加入到工程中;③在C代码中调用汇编子程序时可直接调用:子程序名();④汇编子程序的编写时,如果使用了A或HX,则需要保护寄存器A或HX。因为08C的编译器把A和HX封装在下层,不需要用户管理,如果汇编子程序没有保存这些寄存器,在返回时将造成不可预测的后果。7.3.2使用汇编指令7.308C语言的使用在HC08系列单片机Flash地址空间中,有一段是用来存储所有的中断矢量,每两个字节存储的是一个中断处理函数的地址。编写中断处理函数,需要按照以下步骤:①新建一个vectors.c,并加入工程中;②定义中断处理函数;③定义中断向量表;④在中断向量表中填入中断处理函数名称;7.3.3中断处理7.308C语言的使用08C提供一系列函数库供程序员使用,其中囊括了标准C所具有的大部分库函数和一些08C特有的函数,但是08C中的有些函数和标准C中的函数的功能不一样。这些函数的头文件位于安装目录的include目录下,库文件位于安装目录的lib目录下。更多的函数库说明参见附录F。7.3.408C的常用库函数返回7.408C语言程序编程框架7.408C语言程序编程框架7.4.1实践环境SD-HC08在线编程开发系统中的C语言编程是按工程进行管理,一个08C工程所包含的文件最好放在同一文件夹下,一般由.prj、.src、.h、.c等类型文件构成,编译后还将产生.lst、.s19等文件。编译过程还会产生一些中间文件,可以不去理会这些文件。7.408C语言程序编程框架一个完整的08C语言程序通常至少包含如下5部分:汇编语言的启动文件存储器映像及I/O端口的头文件主程序模块中断服务程序模块中断向量表文件7.4.208C语言程序的组成7.408C语言程序编程框架一个完整的08C语言程序通常至少包含如下5部分:汇编语言的启动文件存储器映像及I/O端口的头文件主程序模块中断服务程序模块中断向量表文件7.4.208C语言程序的组成7.408C语言程序编程框架编写第一个可执行的08C语言程序:(1)新建文件①新建C工程。②新建GP32C.h文件,该文件包含了MC68HC908GP32的I/O及寄存器的宏定义。③新建main.c程序(2)编译程序7.4.3第一个08C语言例程返回7.508C语言的编译过程7.508C语言的编译过程7.5.1编译过程在SD-HC08在线编程开发系统中编辑了源程序以后,使用编译命令就可以把源程序翻译成目标程序。①编译的脚本文件:包含了编译指令及相关的参数,文件存放的位置在.prj的同一文件夹下。②C程序向汇编程序的转化:启动08C编译器,根据.mak文件的编译脚本将所有.c文件编译成.s文件及.lis文件。③汇编代码向机器码的转化:汇编程序将所有的汇编文件编译成.o的中间目标文件,即所有的汇编语句都编译成机器码。④连接:启动连接器,连接器根据.mak文件中的连接脚本,把所有的.o文件统一连接成一个.s19文件,该文件可以下载到目标机器上执行,同时还可根据用户需求生成.lst文件和.mp文件。7.508C语言的编译过程7.5.2编译文件输出单片机的文件都有自己的后缀规则,不同的C编译器产生的文件后缀在某些方面有些差异。下表为08C编译过程中产生的文件类型。08C编译所产生的文件类型文件扩展名说明mak编译脚本文件Lis浮动地址空间的汇编代码s浮动地址空间的汇编代码o目标文件Lst编译列表文件mp连接后生成的地址映像文件S19绝对地址目标文件返回7.608C编程技巧7.608C编程技巧7.6.1数据类型的选用单片机C要和程序存储器资源结合起来,虽然其提供的数据类型十分丰富,但是只有bit和char等数据类型是机器语言直接支持的数据类型,用此类数据类型的语句所生成的代码较短;而其它的数据类型如整型、浮点型等数据要有一定的内部程序或内部函数的支持,相对来说用该类数据类型的语句生成的代码要长。有些C语言程序表面上看起来十分的简单,但在实际编译时,生成的代码却相当长。因此我们要按照实际需要,尽量选用占用存储空间少的数据类型,可以大大的减少所生成的代码长度。7.608C编程技巧7.6.2算法设计问题单片机C语言和标准C语言存在着很大差别,在计算机上进行C语言程序设计时可以不必考虑程序代码的长短,只需考虑程序功能实现,但是在单片机上进行C语言程序设计就必须考虑系统的硬件资源。有时并不是程序的算法越简单、长度越短越好,因为有一些算法要调用一些内部的子程序和函数,生成的机器代码可能非常长。不同的算法对程序代码长度影响十分大,因此在进行程序设计时,就尽量采用程序生成代码短的算法,在不影响程序功能实现的情况下可以采用一些优化算法。7.608C编程技巧7.6.3数据存储器的分配单片机内部数据存储器RAM只有几百字节,内部处理器、内部堆栈、压缩栈、所有程