【说明】
规范版本:
V0.0 临时版
规范制定
xuehui869
日期
2009年8月19日
修改
修改日期
版本描述
主要根据电机阀寿命试验台编程经验,并结合PIC单片机的实际情况而制定,同样适用于其他种类的单片机
【规范原则】
为了提高使用汇编语言所编写代码的可读性、实现高质量的编码而制定该规范。规范的制定的总体原则是:
1、 体现代码编写者清晰的思路
2、 系统的层次结构
3、 类似自然语言的描述
第一章 文件结构、注释
有别于C语言,由于汇编语言本身的特殊性,需特别注意代码说明性文档的管理。
文件结构分为 头文件描述区、代码初始化定义区、代码正文定义区、本地文件引用区。
1、文件头描述
每个单文档文件都需加上头文件描述
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 函数库说明:按键操作函数库
; 版本:
; 作者:
; 创建日期:
; --------------------------------------------------------;
; [支 持 库]
; --------------------------------------------------------;
; [版本更新]
; 修改: xuehui869
; 修改日期: 2009年8月18日14:17:47
; 版本: v0.0
; --------------------------------------------------------;
; [版本历史]
; --------------------------------------------------------;
; [使用说明]
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;/
注:每次版本的升级都要注明并写进版本历史中,以便于修改和利用文档的正确使用。
2、代码初始化定义区
代码的初始化工作分为 编译器库文件引用、端口定义、宏定义、全局变量定义、临时变量定义、指针定义。
形如:
;= = = = = = = = = = == = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ;--------------- 全局变量定义,0X20~0X4F --------------------------------------
每段的定义区间也要加以说明,便于管理
3、代码正文定义区
代码正文定义区分为 复位及中断安排部分、主函数部分
说明样式:
;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
;--------------- 复位及中断安排--------------------------------------
;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
4、函数头说明
;---------------------------------------
;函数说明:按键、屏幕操作函数值返回;只有当
; 按确定键之后,才跳出本函数;
; 用于画面2。此函数只是比上面的函
; 数多了个显示部分,若是在C++里面
; 用下其继承特性,就再合适不过了。。
; 用于画面2
;用法: 先清零LCDCoordinate
;输入 : 当前屏幕坐标的位置LCDCoordinate
; 用于保存上次操作值的变量 LCD_SCREENOPERATE2_LAST_VALUE
;输出 : LCDCoordinate,用于保存屏幕操作函数返回值,是唯一的返回值,,范围0~7
; 这就是与人进行交互的窗口函数的作用
;全局临时变量:
;调用函数:无
;---------------------------------------
注:
【函数说明】 用于说明函数的类型(Goto型 or Call型)、作用、以及设计时的一些细节,便于以后查漏补缺
【用法】 用于指出在调用该函数时需要注意的一些问题,比如初始化的工作
【输入】 输入参数的名称、作用等
【输出】 函数的返回值的名称、作用等
【全局临时变量】
根据汇编语言的特点,由于没有函数栈,在函数体中具体运用到的临时变量均采用全局变量,这些变量在使用前要加以特别的说明
【调用函数】 调用函数的类型、作用,输入参数,输出参数
5、本地文件引用区
MPLABIDE编辑的特点是:先把工程中所有的代码集合在一个单文档中,然后才把汇编语言逐条地替换为机器码,中间不涉及编译问题,只是简单的替换,这些问题在看过Intel Hex的结构之后就会很明白。
相比而言,C语言不仅有函数体的封装性,而且还有工程中多个文件相互之间的封装性,比如static、extern等的使用,而汇编语言编译器一般都没有做这些,其没有类似“.h文件”的定义。
在MPLAB IDE中,查表函数要放在工程文件前256个字节中,而且还要特别注意堆栈的溢出问题。
本地文件引用放在工程的末尾,按重要性程度依次存放。形如:
;= = = = = = = = = = == = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = #include"Key.INC"
;= = = = = = = = = = == = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
第二章 命名规则
1、 宏、函数名
汇编中的宏和函数名实质上都是为了方便记忆以及便于查找而定义的。命名规则为两者均大写,单词间使用“_”分隔。形如:
SYSTEM_SAVE_CMD
2、变量、指针
单词开头大写,其余小写。形如:
UsartRecWorkNumSum
3、标记
类似于“宏、函数名”的命名。
GOTO循环体的标记命名采用“函数名+LOOP”方式,同一个函数中若有多个循环体,则在LOOP后加序号以示区别。这样一方面也便于系统升级和维护。
同样,使用BTFSS/BTFSC语句跳转时,标记采用“函数名+NEXT”方式,结尾加序号以示区别。
每个标记体间要加两个换行,使代码清晰分明
4、库文件
基本的、写的较为完善、以后还会经常用到的库文件的名称以“API”字样结尾。
形如:
USART_API.INC
LCD12864.INC
第三章 函数定义
1、堆栈溢出问题
PIC16F914单片机中,只有8级堆栈,在使用函数的时候,要特别注意“堆栈溢出问题”,避免过深的函数调用。尽量采用“平级”调用,而不是树形结构。在一次调用之后,尽量返回初始调用态,再CALL其它函数。
而在“电机阀寿命试验台”程序的编写过程中,当出错时直接返回到了“第二级菜单”。这一过程中,堆栈区保存的函数断点不再有效,直接作了丢弃处理,程序指针直接指向空闲态代码。
总体来说,相对于C语言,使用汇编语言编写软件时,初期规划显得特别重要。软件的初期规划包括需求分析、结构、软件流程、存储空间分配等内容。本着便于升级,时间、空间结构相对紧凑的原则,在规划时,尽量多采用函数调用的形式,这样做也是避开PIC单片机换页麻烦的手段之一。
当然,说到软件工程初期所做的规划,我们一般很难达到想象与实际完美结合、不出差错的程度,最终的成果基本上都是通过理论与实践结合产生的。所以说,这个过程中,需要根据实际情况反复调试、修改代码。当然,软件规划的需求和方向是不能出错的。
由于没有设计函数堆栈,输入输出参数均采用全局变量的形式,这就需要在函数头中作出详细的说明。
2、采用函数形式的好处
考虑程序区代码总量的大小,尽量减少重复,把类似的结构尽量提炼出来而采用函数反复调用的形式。这样不仅节省代码存储空间,而且更大的一个好处是可以更加方便、快捷的改动和升级软件,一改全改,避免08年Robocon时的顾头不顾尾的情况,减少代码修改的劳动量。
第四章 PIC单片机后记
1、 PIC寄存器使用完之后,尽量切换到体0,体0作为一种默认状态。
2、 中断服务程序中注意断点的现场保护和恢复
3、通过将近两个月的“电控阀寿命试验台”程序的编写,感觉到软件这一类的工作,需要速战速决,那样才酣畅淋漓,就像3月份实习那样。而且短时间内完成,可以提高代码的正确率,好的想法也更容易产生。当自己初始构想被实际证实之后,那是一种升华。可是,不得不说,这次做的东西拖的太久了,直到很多东西最后是一节一节做出的。
另一方面,汇编代码可读性差,上面那种做法也就显的很重要了。而最后那个“贪吃蛇”编写的过程就比较好了,从最初设想到具体做出来也就是一天的时间。
更多的关于软件规划和程序编写的注意事项参看附图。
4、汇编指令集与CPU的构架
PIC16F914的汇编指令只有35条,相比其它种类的单片机具有更精简的指令集。这些汇编指令就像是建造大厦过程中所需要的砖瓦石料,虽然是很简单的东西,但经过优化设计在非线性的作用(整体大于部分之和)下就能组成绚丽多彩的软件。
和其它单片机一样,一条汇编指令中不能实现数据存储器空间(包括程序存储空间的立即数)的数据直接被传送到另一个数据存储器空间,这点和CPU的结构有关。
运用汇编编写程序的时候,要考虑代码的时间复杂度和空间复杂度。程序代码被存储在程序存储区中,循环性、跳转性、顺序性是它三大要素,虽然代码大部分时间是按顺序执行的,代码看起来是一维的,但通过这些特性的巧妙组合,其空间结构也就是立体的了。我们在编写代码的时候,要保持这个空间结构优美、简化而又不失艺术性。实际上,ALU+控制器+复用器,是纯粹的数据搬运工。而真正的、有生命力的,是被编写的千变万化的、具有空间立体结构的代码,其就像意识对人脑的作用一样。。。
当然,PIC采用过于精简的指令集带来的问题是,好多原本硬件做的东西都转移到了软件上。很明显的是乘除法指令,这造成了编写软件比起一般的单片机较为困难些,而且代码量明显增大。这些当然与微处理器的市场定位和应用范围有关,采用精简指令集可以有效降低微处理器的成本和功耗。当设计微处理器的架构时,该往一边倾斜,是采用复杂指令集还是精简指令集,这些就是考虑的因素。
还要知道,微处理器中的程序设计和在FPGA上进行数字电路设计本质是相通的,一个在微处理器上实现的功能,完全可以用纯数字电路来实现,反之亦然。两者的基础都是数理逻辑,或者可以说微处理器是数字电路的子集。