第3章
CHAPTER3
MSP430单片机C语言
程序设计基础
3.1单片机程序设计基础
3.1.1程序流程图
在程序设计中,最重要的不是编写代码而是算法设计,这与建筑和机械制造很相似。例如,当要建设一栋高楼时,首先要做的是绘制高楼的结构图以及施工图,然后是现场施工。程序设计也是如此,当面对一个程序设计任务时,首先想要做的是先画出整个任务实现的流程图,然后再使用具体的程序设计语言进行代码实现。可见,程序流程图的绘制在整个程序设计中起着重要作用。实际上,绘制流程图的过程就是思考和形成算法的过程。由于其直观性,绘制过程本身又促进了思考。因此,程序流程图是人们对解决问题的方法、思路或算法的一种描述方法。当人们看到一个优秀的程序流程图时,就能很快地把握住程序结构和处理思路,有利于程序纠错和维护。
程序流程图具有符号规范、画法简单、结构清晰、逻辑性强、便于描述、容易理解等优点。绘制流程图所需要的基本符号如图3.1所示,它们分别是起始框、终止框、执行框和判别框。其中,起始框和终止框是程序流程图必备的;执行框中注有必要文字说明以指示具体执行了何种操作,该框所指的操作可大可小。在概要设计阶段执行框所描述的是一个大的功能模块。在详细设计阶段则是指在实现某一特定功能时需要执行的具体指令或语句。
图3.1流程图中基本符号
绘制程序框图的规则:使用标准的框图符号;框图一般按从上到下、从左到右的方向画;除判别框外,大多数程序框图的符号只有一个进入点和一个退出点,而判别框是具有超过一个退出点的唯一符号。在绘制流程图时要注意结构化程序设计中三种基本结构的流程图标准画法。尽量将复合条件转为多个单一条件。流程线不要忘记画箭头,因为它是反映流程执行的先后顺序。如果不画箭头,就难以判断执行次序。
3.1.2单片机程序设计语言
目前主要的单片机程序设计语言是汇编语言和C语言。汇编语言是面向CPU的程序设计语言。由于汇编语言程序直接利用单片机指令集中的指令实现具体的算法功能,因此汇编语言与机器语言具有较好的一致性,可以访问所有能够被访问的软、硬件资源。汇编语言程序的目标代码简短,占用内存少,执行速度快,是高效的程序设计语言。它经常与高级语言配合使用,以改善程序的执行速度和效率,弥补高级语言在硬件控制方面的不足。汇编语言的缺点是不同处理器具有不同的汇编语言语法和编译器,编译好的程序无法在不同的处理器上执行,缺乏可移植性。汇编语言程序的可读性差、不易维护。总之,汇编语言程序编写烦琐、工作量大、开发效率很低,周期长且单调。目前处理器性能不断提升、存储资源越来越丰富,使得汇编语言目标代码少、效率高的优势正在逐渐丧失。使用汇编语言从事嵌入式系统开发的人数总体呈下降趋势。
C语言是一种既具有高级语言的特点,又具有部分汇编语言特点的程序设计语言。C语言也是一种结构化的程序设计语言,因为它提供了三种基本结构语句,而且提供了定义“函数”的功能。函数可以完成子程序的所有功能,是完成程序功能的基本构件。由于函数允许将一个程序中的多个任务被分别定义、编码和单独编译,所以函数可以使程序模块化。作为一种高级语言,C语言功能齐全、应用范围大,已是目前最为流行的高级语言之一。但是C语言代码的执行效率比汇编语言要低。
在程序设计历史上汇编语言曾是非常流行的语言之一。一方面,随着硬件技术的进步,CPU性能不断提高、储存资源日益增大、成本逐渐降低;另一方面,随着软件规模的增长以及对开发进度和效率的苛刻要求,高级语言逐渐取代了汇编语言。但即便如此,高级语言也不可能完全替代汇编语言的作用。以Linux内核为例,尽管绝大部分内核代码是用C语言编写的,但在某些关键地方仍然使用了汇编代码。因为这部分代码与硬件的关系非常密切,即使是C语言也会显得力不从心,而汇编语言则能够很好地扬长避短,最大限度地发挥硬件的性能。
一般对于小程序来说,若是对硬件进行简单的控制可以用汇编语言,若更多涉及逻辑设计方面的内容,则需要使用C语言。对于稍大一些的程序来说,C语言的优势就十分明显了。就现代单片机程序设计来说,大多是以C语言为主,汇编语言为辅。即只有在那些对代码大小和效率要求较高的场合才使用汇编语言。
3.1.3单片机程序设计的一般步骤
图3.2单片机程序设计流程图
人们在嵌入式系统产品开发过程中摸索出了程序设计的一般步骤,具体如图3.2所示。该步骤对于基于单片机的产品设计与程序开发具有很好的借鉴作用。按此步骤进行产品开发可使设计者少走弯路,缩短开发周期,提高产品可靠性。
1.需求分析、明确任务
该阶段要尽可能搞清楚用户的全部需求信息,即对要完成的任务进行详细的了解与分析。然后将具体的实际问题抽象转化成计算机可以处理的问题。
2.算法设计
在明确任务之后,就需要将其转化成计算机算法。算法就是在计算机上解决问题的方法与步骤。对于复杂的大型程序,算法设计又可分为概要设计和详细设计两个阶段。对于比较小的软件两个可以同时做。详细设计完成后算法设计也就基本完成了,接下来将设计好的算法转化成使用具体程序设计语言编写出的程序,进而实现在计算机上的求解。在设计算法时一般会采用或借鉴现有的一些计算方法和日常生活中解决问题的逻辑思维推理方法等。
绘制程序流程图是在算法设计之初就开始的工作,在算法设计好之后,程序流程图也就确定了。所以说算法设计的过程,也是绘制程序流程的过程。通过画流程图可以首先从图上检验算法的正确性,减少出错的可能,使得动手编写程序时的思路更加清晰。
3.芯片选择及合理分配单片机资源
等完成算法设计之后,就需要决定在何种硬件平台上实现上述算法。在确定好主要芯片之后,就需要完成单片机系统的资源配置及分配,主要是单片机存储空间和工作单元的合理分配和外围设备的配置。在这个过程中,应充分利用不同型号单片机的特殊优点以方便资源配置和系统设计。例如,合理、正确地对存储空间进行分段和数据定义。由于MSP430单片机对16位数据处理效率最高,因此要充分利用这一特点。
4.代码编写
该步骤在单片机程序设计中是最为重要的一步。经过1~3步的准备,已完成了程序代码编写前的所有工作。编写程序时要选择好编写语言,对于同一种算法,不同的程序设计语言会有不同的实现方法。编程能力的提高是一个循序渐进的过程。对于初学者来说,一方面,要多读现有的程序,以学习别人的编程经验;另一方面,还必须多动手,亲自编写程序,不要怕失败,只有通过无数次失败,才能从中积累自己的编程经验。
5.程序调试
在源代码编写完毕之后,就要进行调试。通过调试的程序只能说明没有语法错误,但不能排除没有逻辑错误。所以能不能达到预期效果还必须用实际数据测试才可以。一般来说,这是一个反复测试的过程。对此,程序编写人员,尤其是初学者一定要有充分的心理准备。只要有足够的耐心,加上认真、细致的工作态度,就一定能找出其中的逻辑错误。事实上,即使是一个非常有经验的程序员,也没有百分之百的把握一次就成功。
6.性能评估
在程序调试完后,就需要将程序应用到产品上进行实际环境检验,其中包括功能检验、可靠性检验、极端环境下检验。凡经过检验符合要求了,整个程序设计工作就算结束了,接下来就是文档整理与使用说明书的编写工作了。若不符合要求,则需要重新开始,这是最坏的情况。一般而言,只要将任务需求分析做得足够细,一般不会出现这种极端情况。
7.文档整理与编写
程序运行无误,实际试运行正常,且经过了各种环境测试,但这并不意味着产品开发任务的结束。程序文档的编写也是程序设计的一个重要任务。其目的是为了便于修改和维护程序。程序文档一般包括含有功能要求和指标程序的设计任务书、程序流程图、存储单元分配清单、源程序清单、应用系统资源分配、参量计算和设计、错误信息的定义、实际功能及指标测试结果说明、程序使用和维护说明书等。需要注意的是,部分程序文档的编写是与上述1~6步同时进行的。
3.2MSP430单片机C语言程序设计
目前支持MSP430单片机的C语言编译器很多,国内主要使用的是IAR公司的IAREmbeddedWorkbenchforMSP430(EW430)和TI公司开发的CodeComposerStudio(CCS)。MSPGCC作为一种开源编译器也具有一定的使用者。这些C编译器功能比较强大,可以编译出高效、紧凑的机器代码。
MSP430单片机的C语言程序(以后简称C430)设计方法与标准C语言的基本上相同。但单片机的资源与PC相比,十分匮乏。为了更好地适应MSP430单片机的程序设计,C430对标准C语言进行了扩展。主要表现在数据类型及数据长度、关键字扩展以及由此引起的函数扩展等。需要说明的是,不同的C430编译器对C语言的扩展不完全相同,例如,IAR公司的C编译器与TI公司的C编译器都对C语言的支持程度略有不同,大多数情况下,MSP430单片机的源程序可以在各个版本的C430编译器上使用。
3.2.1数据类型与运算符
1.标识符与关键字
标识符是指常量、变量、语句标号、数组、文件名以及用户自定义函数的名称。C语言规定标识符只能由字母、数字、下画线组成,并且只能由字母、下画线开头,所用字母区分大小写。C语言中一些已被赋予特定含义的标识符被称为关键字或保留字,关键字不能用作标识符,在C语言中的关键词见表3.1。这些关键字将在后续章节中陆续介绍。
表3.1C语言中的32个关键词
与数据类型相关的关键字(12个)
short声明短整型变量或函数struct声明结构体变量或函数
int声明整型变量或函数union声明共用数据类型
long声明长整型变量或函数enum声明枚举类型
float声明浮点型变量或函数void声明函数无返回值或无参数,声明无类型指针
double声明双精度变量或函数unsigned声明无符号类型变量或函数
char声明字符型变量或函数signed声明有符号类型变量或函数
续表
与变量有关的关键字(6个)
auto声明自动变量extern声明变量是在其他文件正声明
const声明只读变量register声明寄存器变量
static声明静态变量volatile说明变量在程序执行中可被隐含地改变
与程序控制有关的关键字(12个)
if条件语句for一种循环语句
else条件语句否定分支(与if连用)do循环语句的循环体
switch用于开关语句while循环语句的循环条件
case开关语句分支continue结束当前循环,开始下一轮循环
default开关语句中的“其他”分支break跳出当前循环
goto无条件跳转语句return子程序返回语句(可以带参数,也可不带参数)
其他关键字(2个)
sizeof计算数据类型长度typedef用以给数据类型取别名