《单片机程序设计编程规范》由会员分享,可在线阅读,更多相关《单片机程序设计编程规范(19页珍藏版)》请在金锄头文库上搜索。
1、单片机程序设计编程规范单片机程序设计编程规范本规范适用于松翰科技 8-bit MCU 部门汇编程序编写准则, 同样适用于代理商及重要客户工程师编程规范参考。本规范的目的为统一编程风格,保证程序编写质量,提高程序的可移植性和维护性。大部分的规范严格,品质要求高的软件公司对员工编写代码的风格都有硬性规定,例如缩排的使用,TAB 的长度,函数变量的命名方式. 这些规定的明显好处是可以统一规范不同程序员所编制的代码,提升程序代码的可读性与可维护性,同时统一格式的编程风格也为 code review提供方便.目录目录一一、 设计总则设计总则二二、排版风格排版风格三三、程序可读性及可维护性程序可读性及可维
2、护性四四、注释注释五五、变量命名规则变量命名规则六六、常量命名规则常量命名规则七七、标号命名规则标号命名规则八八、文件命名规则及文件分割文件命名规则及文件分割九九、标准程序模块标准程序模块十十、附录附录2一、一、一、一、设计总则设计总则设计总则设计总则1 1 1 1程序质量的评估程序质量的评估程序的优劣可以从两个方面进行评估,定量指标和定性指标。 定量指标包括: 1)程序代码执行效率; 2)程序占用资源多少。 定性指标包括: 1)可调试性,即是否方便排除程序语法错误; 2)可测试性,即是否方便验证程序功能的正确性; 3)可维护性,即是否方便程序的修改和升级; 4)可移植性; 5)可读性。2 2
3、 2 2、程序架构程序架构为了便于维护和移植,推荐使用层次化的软件设计方法。可把整个软件分为三层:应用层、 界面层和底层驱动层。各层之间的关系如下图所示。层次化设计说明: 1)底层驱动层主要包含直接和硬件相关的驱动程序,如数码管显示、按键、峰鸣器、 继电器和电机控制等。底层的各个模块间要保持各自的独立性,不产生直接的数据交互, 底 层也不直接访问应用层,如果有需要,都要通过界面层进行数据交互。 2)界面层主要提供数据交互, 为应用层和底层驱动之间以及底层驱动层各模块之间提 供数据的交互。 3)应用层主要完成具体功能的实现, 它要通过界面层控制底层驱动层各模块来完成所 需功能,而不能越过界面层直
4、接访问底层驱动层。所有的用户接口要在应用层来实现. 4)一个好的架构必须将底层硬件包装起来, 为应用程序提供一组丰富的函数操作 (buffer or parameter) , 例如在中断的处理中, 应用程序不需要资料中断的堆栈如何保护不 需要知道地址操作, 只需要读取中断产生的旗标动作. 5)在即时性软件系统里面,对达到高效率的实时性与反应力, 所以程序使用大量的事 件触发方式来设计任务.事件有可能来自外部的触发(key ,rxdata , sensor detect, ) 也可 能是系统内部自行产生的(Timer, alarm, flag),与事件触发方式相对应的是定时查询方式 (polli
5、ng), 一般来说polling 效率较差 因为有多余的动作而且系统反应时间与查询polling时 间间隔有关, 但是在小型的 MCU 系统里面用 Polling 方式反而简单许多3 3 3 3、设计基本原则设计基本原则1)尽量减少各个子程序功能模块间的耦合度 (耦合度是指一个程序的执行对另一个程 序的影响力) ,保证各自的独立性。一般情况下,建议子程序模块功能的划分要尽可能细化, 功能尽量单一,减少子程序模块间的数据交互。 2)在满足功能需求的情况下,可适当牺牲代码的执行速度,以保证程序的透明度。 3)主要子程序模块间的交互,要通过特定的界面跟应用层进行沟通,可使用 FIFO (First
6、in,First out)或是 Buffer 两种方式。每种子程序模块都可以有自己的 FIFO。例如:3就按键来说,一般有 Key buffer、Key FIFO 或直接进入 AP FIFO 三种设计方式。 KeyKeyKeyKey bufferbufferbufferbuffer:一般用于保存数字按键信息。例如:在电话机的设计中,需要记录按 键内容用于 LCD 显示、最后数字确认、数字存储等,这时候需要把按键值的信息 (0123456789*#)记录在 Key buffer 中; KeyKeyKeyKeyFIFOFIFOFIFOFIFO: 一些功能按键可以将相应信息列入到 Key FIFO
7、中, 等待应用层的取用, 这样可根据不同的工作模式进行不同的处理及动作。 这些类似的观念可以应用在许多周边中: 输入类:Key、RF Data input、UART data input、Switch input 等; 输出类:LCD display、LED display、UART data output 等。 APPAPPAPPAPP FIFOFIFOFIFOFIFO(应用界面层应用界面层) :主要是将发生的事件储存在 APP FIFO 里面等待适当的 时间依序处理,不然有可能造成系统在某一程序物件里面循环,从而降低系统的实时性 (Real-Time) 。 4)每个子程序模块只能有唯一一个
8、程序入口地址在程序的首部, 只能有唯一一个程序 出口地址在程序的尾部。例如: 以下的写法是不规范的(两个 RET 出口,存在调试时不易设立断点,程序可读性降低等问 题) : lable: b0bts0fz ret clry ret 应该改为(只有一个出口位置,标号为 lable90,便于程序检查) : lable: b0bts0fz jmplable90 . clry lable90: ret 5)上电复位时要对所有的 RAM 空间进行初始化(建议用户寄存器清零,系统寄存器 进行必要设定) ,不要使用未经初始化的变量。RAM 未经过完整的初始化,容易导致程序执 行的不确定性, 这一不良现象往往
9、在批量生产中有所体现。 ( 这点是工程师经常犯错的地方, 须特别注意) 6)系统中如果需要等待一些未知的应答信号, 如通信或等待输入信号时,必须进行超 时或异常处理,以防止程序进入“死等”状态。 例如在红外接收中, 由于信号的突然消失或干扰从而无法得到一帧完整或正确的信 息,这时需要复位接收程序的入口条件并退出接收程序,而不是一直等待信号的来临。不然 无法进行下次接收甚至会影响到其它程序的执行。 7)通过对系统数据结构的划分与组织的改进,以及对程序算法的优化来提高空间效 率。这种方式是解决软件空间效率的根本办法。 8)保证循环体内的工作量最小化。 应仔细考虑循环体内的语句是否可以放在循环体之4
10、外,使循环体内工作量最小,从而提高程序的执行效率。 9)在多重循环中,应将最忙的循环放在最内层。 10)中断处理程序应尽量短。有效的作法为:在中断中进行标记,在主程序中进行处 理。 但一些实时性要求较高的程序例外。 此外, 进入中断时应该保存涉及到的变量和寄存器。 11)看门狗的正确使用。看门狗主要用于微控制器死机时的时间溢出复位,需要程序 适时清除。正确的处理方式为:整个系统程序中尽量保证只有一处清看门狗位置,而且应处 在主循环的主干位置。 切记不可在定时中断中清狗, 因为微控制器有时只是在主循环中死掉。 (所有 AC 电源的应用程序 都必须强迫加入看门狗选项尤其是条件式的看门狗 有利于系统
11、 发生异常后的重启动)二、二、二、二、排版风格排版风格排版风格排版风格1、程序采用缩进风格编写,缩进为1个 Tab 键,1个 Tab 键定义为8个空格位。 2、程序中的标号要从第一列开始书写。以“.”开头的预编译命令也要从第一列开始书写, 其他预编译命令采用缩进风格编写。 例如: 1)以“.”开头的预编译命令要从第一列开始书写,其他预编译命令采用缩进风格书 写。 .LIST;从第一列开始书写 INCLUDESTDmacro1.h .CONST NUMBEREQU55h .DATA wk00DS1 .CODE ORG0h 2)标号要从第一列开始书写。 main:;从第一列开始 jmpmain;缩
12、进8个空格位 3) 变量或常量的定义采用缩进风格。 例如: .DATA keybufDS1 .CONST NUMBEREQU8 4) 定义变量或常量时,变量名或常量名与命令符之间使用2个 Tab 键(相当于16个空 格位)分开,命令符与后面的操作数用1个 Tab 键(相当于8个空格位)分开。 例如: keybufDS1 NUMBEREQU55h 5) 操作码与操作数之间用1个 Tab 键(相当于8个空格位)分开。5例如: ORG80h mova,NUMBER table: DW1234h 6.) 程序中两个操作数之间用一个“,”作为分隔符,“”号与立即数之间不需要分隔 符。 例如: mova,
13、#55h 7) 标号要单独占一行。 8) 相对独立的程序块之间必须加空行。 例如: ORG10hINCLUDEsys.asm INCLUDEint.asm INCLUDEkey.asm 9) 程序语句后面若有注释,所有的注释要遵守上下对齐的原则。 例如: b0movl,#7fh; use dp0x(hl) pointer mova,#00; set pointer = 007fh 应该书写为: b0movl,#7fh; use dp0x(hl) pointer mova,#00; set pointer = 007fh三、三、三、三、程序可读性与可维护性程序可读性与可维护性程序可读性与可维护性
14、程序可读性与可维护性1. 程序中的语句、标号、变量使用小写英文字母,常量与预编译命令使用大写英文字母, 以便和一般的语句进行区分。 例如: NUMBEREQU55h .DATA accbufDS1 .CODE mova,#NUMBER 2. 表示不同进制的立即数,要在立即数后面加上不同的进制符号。 例如: mova,#00100011b mova,#23h 不建议使用: mova,#0x23 3. 一般情况下,变量和常量要分开定义,不要混在一起。变量在 ”.DATA” 段中定义,采用 命令符 “DS” ,常量在 ”.CONST” 段中定义,采用命令符 “EQU”。6例如: .CONST NUM
15、BEREQU10 .DATA accbufDS1 4. 程序中不使用未定义或意义不明确的常量。 例如: 下面的赋值方法要避免使用: mova,#3;不要直接使用意义不明确的数字, 在常量中做定义 movr,a 建议采用如下赋值方法: .CONST NUMBEREQU3;循环次数 .CODE mova,#NUMBER movr,a 5. 整个程序的结尾要以 “ENDP” 语句结束。 6. 当一段代码在程序中有多个地方使用时,建议采用子程序调用或宏命令的方式来替代。 如此,对该代码段的修改就可在一处完成,增强代码的可维护性。 7. 程序中关系较为密切的子程序代码尽可能相邻。 8. 避免程序中的垃圾
16、代码,预留代码应以注释的方式出现。程序中的垃圾代码不仅占用额 外的空间,而且还可能影响到程序的功能与性能,很可能给程序的测试、维护等造成不必要 的麻烦。四、四、四、四、注释注释注释注释1. 程序应该包括两个部分注释,说明部分和语句注释。一般情况下,源程序有效注释量必 须在30以上。 2. 说明部分: 1)源文件说明部分位于每个源文件的最前面,主要描述:文件名、作者、生成日期、 联络方式、功能描述、版本号、软硬件平台、版权说明、修改记录等的简要说明,以英文书 写。 例如: /* File name:;文件名 Author:;作者 Date:;日期 Email:;邮箱地址 Description:;功能描述 Version:;版本号7Hardware软硬件平台 Copyright (C),SONIX TECHNOLOGY Co., Ltd. History:;修改记录 *