当前位置:首页 >> 信息与通信 >>

mcu-c编程规范


MCU- 程序基本编程规范( MCU-C 程序基本编程规范(转)
[ 2010-4-14 13:35:00 | By: gdqinci ] MCU-C 程序基本编程规范(转) 为了提高源程序的质量和可维护性,从而最终提高软件产品生产力,特编写此规范。本标准规定了程序设计人员进 行程序设计时必须遵循的规范。本规范主要针对单片机编程语言和 08 编译器而言,包括排版、注释、

命名、变量 使用、代码可测性、程序效率、质量保证等内容。 1.基本规则 格式清晰、注释简明扼要、命名规范易懂、函数模块化、程序易读易维护、功能准确实现、代码空间效率和时间效 率高、适度的可扩展性、单片机编程规范-标识符命名 2.标识符命名

2.1 命名基本原则

(1)命名清晰明了,有明确含义,使用完整单词或约定俗成的缩写。通常,较短的单词可通过去掉元音字母形成 缩写;较长的单词可取单词的头几个字母形成缩写。即"见名知意"。(2)命名风格要自始至终保持一致。

(3)命名中若使用特殊约定或缩写,要有注释说明。 (4)同一软件产品内模块之间接口部分的标识符名称之前加上模块标识。

2.2 宏和常量命名
宏和常量用全部大写字母来命名,词与词之间用下划线分隔。对程序中用到的数字均 应用有意义的枚举或宏来代替。

2.3 变量命名
变量名用小写字母命名,每个词的第一个字母大写。类型前缀(u8\s8 etc.)全局变量 另加前缀 g_。 局部变量应简明扼要。局部循环体控制变量优先使用 i、j、k 等;局部长度变量优先使 用 len、num 等;临时中间变量优先使用 temp、tmp 等。

2.4 函数命名
函数名用小写字母命名,每个词的第一个字母大写,并将模块标识加在最前面。

2.5 文件命名
一个文件包含一类功能或一个模块的所有函数,文件名称应清楚表明其功能或性质。
每个.c 文件应该有一个同名的.h 文件作为头文件。 3.注释

3.1 注释基本原则

有助于对程序的阅读理解,说明程序在"做什么",解释代码的目的、功能和采用的方 法。 一般情况源程序有效注释量在 30%左右。 注释语言必须准确、易懂、简洁。 边写代码边注释,修改代码同时修改相应的注释,不再有用的注释要删除。
汇编和 C 中都用"//",取消";" 不使用段注释" /* */ "(调试时可用)

3.2 文件注释

文件注释必须说明文件名、函数功能、创建人、创建日期、版本信息等相关信息。 修改文件代码时,应在文件注释中记录修改日期、修改人员,并简要说明此次修改的 目的。所有修改记录必须保持完整。 文件注释放在文件顶端,用"/*……*/"格式包含。 注释文本每行缩进 4 个空格;每个注释文本分项名称应对齐。 /*********************************************************** 文件名称: 作 者: 版 本: 说 明: 修改记录: ***********************************************************/

3.3 函数注释
3.3.1 函数头部注释 函数头部注释

函数头部注释应包括函数名称、函数功能、入口参数、出口参数等内容。如有必要还 可增加作者、创建日期、修改记录(备注)等相关项目。 函数头部注释放在每个函数的顶端,用"/*……*/"的格式包含。其中函数名称应简写为 Name(),不加入、出口参数等信息。 /*********************************************************** 函数名称: 函数功能: 入口参数: 出口参数: 备 注: ***********************************************************/
3.3.2 代码注释

代码注释应与被注释的代码紧邻,放在其上方或右方,不可放在下面。如放于上方则 需与其上面的代码用空行隔开。一般少量注释应该添加在被注释语句的行尾,一个函 数内的多个注释左对齐;较多注释则应加在上方且注释行与被注释的语句左对齐。 函数代码注释用"//…//"的格式。 通常,分支语句(条件分支、循环语句等)必须编写注释。其程序块结束行"}"的右 方应加表明该程序块结束的标记"end of ……", 尤其在多重嵌套时。

3.4 变量、常量、宏的注释
同一类型的标识符应集中定义,并在定义之前一行对其共性加以统一注释。对单个标 识符的注释加在定义语句的行尾。 全局变量一定要有详细的注释,包括其功能、取值范围、哪些函数或过程存取它以及 存取时的注意事项等。
注释用"//…//"的格式。 4.函数

4.1 函数设计原则

函数的基本要求:

1)封装性 1) 正确性:程序要实现设计要求的功能。 2) 稳定性和安全性:程序运行稳定、可靠、安全。 3) 可测试性:程序便于测试和评价。 4) 规范/可读性:程序书写风格、命名规则等符合规范。 5) 扩展性:代码为下一次升级扩展留有空间和接口。 6) 全局效率:软件系统的整体效率高。 7) 局部效率:某个模块/子模块/函数的本身效率高。 编制函数的基本原则: 1) 单个函数的规模尽量限制在 200 行以内(不包括注释和空行)。一个函数只完成一 个功能。 2) 函数局部变量的数目一般不超过 5~10 个。 3) 函数内部局部变量定义区和功能实现区(包含变量初始化)之间空一行。 4) 函数名应准确描述函数的功能。通常使用动宾词组为执行某操作的函数命名。 5) 函数的返回值要清楚明了,尤其是出错返回值的意义要准确无误。 6) 不要把与函数返回值类型不同的变量,以编译系统默认的转换方式或强制的转换方 式作为返回值返回。 7) 减少函数本身或函数间的递归调用。 8) 尽量不要将函数的参数作为工作变量。

4.2 函数定义
1) 2) 3) 4) 5) 6) 函数若没有入口参数或者出口参数,应用 void 明确申明。 函数名称与出口参数类型定义间应该空一格且只空一格。 函数名称与括号()之间无空格。 函数形参必须给出明确的类型定义。 多个形参的函数,后一个形参与前一个形参的逗号分割符之间添加一个空格。 函数体的前后花括号"{}" 各独占一行。

4.3 局部变量定义
1) 2) 3) 4) 5) 同一行内不要定义过多变量。 同一类的变量在同一行内定义,或者在相邻行定义。 先定义 data 型变量,再定义 idtata 型变量,再定义 xdata 型变量.(?) 数组、指针等复杂类型的定义放在定义区的最后。 变量定义区不做较复杂的变量赋值。

4.4 功能实现区规范
1) 一行只写一条语句。 2) 注意运算符的优先级,并用括号明确表达式的操作顺序,避免使用默认优先级。 3) 各程序段之间使用一个空行分隔,加以必要的注释。程序段指能完一个较具体的功 能的一行或多行代码。程序段内的各行代码之间相互依赖性较强。(1、2、3 方式) 4) 不要使用难懂的技巧性很高的语句。 5) 源程序中关系较为紧密的代码应尽可能相邻。
6) 完成简单功能、关系非常密切的一条或几条语句可编写为函数或定义为宏。

5. 单片机编程规范-排版

5.1 缩进

代码的每一级均往右缩进 4 个空格的位置。
不使用 Tab 键

5.2 分行
每行语句(?????超过 80 个字符)要分成多行书写;长表达式要在低优先级操作 符处划分新行,操作符放在新行之首,划分出的新行要进适当的缩进,使排版整齐, 语句可读。避免把注释插入分行中。

5.3 空行
1) 2) 3) 4) 5) 文件注释区、头文件引用区、函数间应该有且只有一行空行。 相邻函数之间应该有且只有一行空行。 函数体内相对独立的程序块之间可以用一行空行或注释来分隔。 函数注释和对应的函数体之间不应该有空行。 文件末尾有且只有一行空行。

5.4 空格
1) 函数语句尾部或者注释之后不能有空格。 2) 括号内侧(即左括号后面和右括号前面)不加空格,多重括号间不加空格。 3) 函数形参之间应该有且只有一个空格(形参逗号后面加空格)。 4) 同一行中定义的多个变量间应该有且只有一个空格(变量逗号后面加空格)。 5) 表达式中,若有多个操作符连写的情况,应使用空格对它们分隔: 6) 在两个以上的关键字、变量、常量进行对等操作时,它们之间的操作符前后均加一 个空格;在两个以上的关键字、变量、常量进行非对等操作时,其前后均不应加空格; 7) 逗号只在后面加空格; 8) 双目操作符,如比较操作符, 赋值操作符"="、"+=",算术操作符"+"、"%",逻辑操 作符"&&"、"&",位操作符"<<"、"^"等,前后均加一个空格; 9) 单目操作符,如"!"、"~"、"++"、"-"、"&"(地址运算符)等,前后不加空格; 10) "->"、"."前后不加空格; 11) if、for、while、switch 等关键字与后面的括号间加一个空格;

5.5 花括号
1) if、else if、else、for、while 语句无论其执行体是一条语句还是多条语句都必须加 花括号,且左右花括号各独占一行。 2) do{}while()结构中,"do"和"{"均各占一行,"}"和"while();"共同占用一行。 if ( ) do { { } }while( ); else { }
嵌套越少越好,{}不准超过 3 层

5.6 switch 语句
1) 每个 case 和其判据条件独占一行。 2) 每个 case 程序块需用 break 结束。特殊情况下需要从一个 case 块顺序执行到下一个 case 块的时候除外,但需要花括号在交界处明确注释如此操作的原因,以防止出错。 3) case 程序块之间空一行,且只空一行。 4) 每个 case 程序块的执行语句保持 4 个空格的缩进。 5) 一般情况下都应该包含 default 分支。 Switch ( ) { case x: break; case x: break; default: break; }

6.程序结构 6.1 基本要求
1) 有 main()函数的.c 文件应将 main()放在最前面,并明确用 void 声明参数和返回值。 2) 对由多个.c 文件组成的模块程序或完整监控程序,建立公共引用头文件,将需要引 用的库头文件、标准寄存器定义头文件、自定义的头文件、全局变量等均包含在内, 供每个文件引用。通常,标准函数库头文件采用尖角号< >标志文件名,自定义头文件 采用双撇号″″标志文件名。 3) 每个.c 文件有一个对应的.h 文件,.c 文件的注释之后首先定义一个唯一的文件标志 宏,并在对应的.h 文件中解析该标志。 在.c 文件中: #define FILE_FLAG 在.h 文件中:& 6.程序结构 6.1 基本要求 1) 有 main()函数的.c 文件应将 main()放在最前面,并明确用 void 声明参数和返回值。 2) 对由多个.c 文件组成的模块程序或完整监控程序,建立公共引用头文件,将需要引 用的库头文件、标准寄存器定义头文件、自定义的头文件、全局变量等均包含在内, 供每个文件引用。通常,标准函数库头文件采用尖角号< >标志文件名,自定义头文件 采用双撇号″″标志文件名。 3) 每个.c 文件有一个对应的.h 文件,.c 文件的注释之后首先定义一个唯一的文件标志 宏,并在对应的.h 文件中解析该标志。 在.c 文件中: #define FILE_FLAG 在.h 文件中: #ifdef FILE_FLAG #define XXX #else #define XXX extern

#endif 4) 对于确定只被某个.c 文件调用的定义可以单独列在一个头文件中、单独调用。 6.2 可重入函数 可重入函数中若使用了全局变量,应通过关中断、信号量等操作手段对其加以保护。 6.3 函数的形参 1) 由函数调用者负责检查形参的合法性。 2) 尽量避免将形参作为工作变量使用。 6.4 循环 1) 尽量减少循环嵌套层数 2) 在多重循环中,应将最忙的循环放在最内层 3) 循环体内工作量最小 4) 尽量避免循环体内含有判断语句 7.工程中所包含的文件 7.1 头文件
7.1.1 头文件的形式 头文件的形式

MCU 程序中的头文件包括面向硬件对象头文件、公共头文件和总头文件。 MCU C 工程编程是面向硬件对象的。例如,要用 MCU 控制电机(Motor),在这样一个 系统中,“面向硬件对象”概念体现在,工程中会创建“Motor.c”的源程序文件专门 用于电机控制。相应的,也要创建一个同名头文件“Motor.h”,用于控制电机的 MCU 引脚定义、相关宏定义和电机控制函数声明等。像这样的头文件,就是面向硬件对象 头文件。与之同名的“*.c”文件可以包含它,来完成控制此硬件对象的 MCU 引脚定 义和相关宏定义;调用该硬件对象控制函数的文件也可以通过调用它来进行函数声明。 还有一类头文件不是专门针对于特定的硬件对象的,而是有一定的通用性。这类头文 件被称为公共头文件。如工程中包含的“Type.h”文件,该文件用于 C 语言中类型的 别名定义,用户还可以根据自己的需要,随时在该文件中添加条目。在工程的任一文 件中,需要用到这些别名时,都要包含“Type.h”。可见公共头文件并不拘泥于具体的 硬件对象,它是为整个工程的和谐运作而建立的。 总头文件(includes.h)是一个较特殊的头文件。 它只被主函数文件包含, 用于包含主函数 文件中需要的头文件,宏定义,函数声明等。它使得主函数文件能够尽量避免改动, 结构更加清晰。
7.1.2 头文件的命名

总的来说头文件的命名应尽量做到简短易懂,见名知意。 面向硬件对象头文件的名称一定要与相应的硬件对象驱动文件同名。例??? 公共头文件,如果对应于相应的源程序文件而建立,必须与之同名。如,“GeneralFu n.c” 是工程中的通用函数定义文件,(像内存数据移动函数,延时函数都属于通用函数), 其他文件在用到这些函数之前,必须进行函数原型声明,从而建立与之同名的“Gener alFun.h”文件,专门用于相应的函数声明。其它的公共头文件没有同名要求,只要表 清文件含义即可,如“Type.h”,“GP32C.h”等。 总头文件在一个工程中只有一个,它的名称较为固定,一般取为“Includes.h”。
7.1.3 头文件注意事项

1) 为了防止重复定义需要使用伪指令 #ifndef VarType …… 例: #ifndef VarType

#define VarType typedef unsigned char INT8U; //无符号 8 位数 typedef signed char INT8S; //有符号 8 位数 typedef unsigned int INT16U; //无符号 16 位数 typedef signed int INT16S; //有符号 16 位数 typedef unsigned long INT32U; //无符号 32 位数 typedef signed long INT32S; //有符号 32 位数 typedef float FP32; //单精度浮点数 typedef double FP64; //双精度浮点数 #endif 2) 对于一个项目中的头文件与芯片相关的寄存器映像文件不可擅自改动,如果的确存 在需要改动的地方另外开辟头文件。 3) typedef 和#define 的用法 ① typedef 的用法 在 C/C++语言中,typedef 常用来定义一个标识符及关键字的别名,它是语言编译过程 的一部分,但它并不实际分配内存空间,实例像: typedef int INT; typedef int ARRAY[10]; typedef (int*) pINT; typedef 可以增强程序的可读性,以及标识符的灵活性,但它也有“非直观性”等缺点。 ② #define 的用法 #define 为一宏定义语句,通常用它来定义常量(包括无参量与带参量),以及用来实现 那些“表面似和善、背后一长串”的宏,它本身并不在编译过程中进行,而是在这之 前(预处理过程)就已经完成了,但也因此难以发现潜在的错误及其它代码维护问题,它 的实例像: #define INT int #define TRUE 1 #define Add(a,b) ((a)+(b)); #define Loop_10 for (int i=0; i&lt;10; i++) ③ typedef 与#define 的区别 从以上的概念便也能基本清楚,typedef 只是为了增加可读性而为标识符另起的新名称 (仅仅只是个别名),而#define 原本在 C 中是为了定义常量,到了 C++,const、enum、 inline 的出现使它也渐渐成为了起别名的工具。为了尽可能地兼容,一般都遵循#define 定义“可读”的常量以及一些宏语句的任务,而 typedef 则常用来定义关键字、冗长的 类型的别名。 宏定义只是简单的字符串代换(原地扩展),而 typedef 则不是原地扩展,它的新名字具 有一定的封装性,以致于新命名的标识符具有更易定义变量的功能。请看上面第一大 点代码的第三行: typedef (int*) pINT; 以及下面这行: #define pINT2 int* 效果相同?实则不同!实践中见差别: pINT a,b;的效果同 int *a; int *b; 表示定义了两个整型指针变量。

而 pINT2 a,b;的效果同 int *a, b;表示定义了一个整型指针变量 a 和整型变量 b。 注意:两者还有一个行尾;号的区别哦!(???) 7.2 源程序文件 源程序文件包括主函数文件、通用函数文件、硬件对象控制文件、芯片初始化文件、 中断向量定义文件和中断使能文件。 源程序文件的分类和命名类同于头文件,但也有它自己的特点。
7.2.1 主程序文件

(Main.s 或 Main.c)(?????) 工程中有且仅有一个主程序文件,它包含了工程的主处理流程。 主函数文件中包含: (1)工程描述 ①工程名 工程名中每个意义单词(或单词缩写)的首字母大写,后缀为.prj。 ②硬件连接索引 工程所要控制的硬件对象索引,详细描述在相应的硬件对象控制文件中给出。 ③工程的功能、目的和说明 ④注意要点 可以注明编程要点和心得 ⑤日期 注明工程完成日期 (2)总头文件 (3)主函数 如:
7.2.2 芯片初始化文件(“SetUp.c”或 “SetUp.s”) 芯片初始化文件( ” ”

该文件与具体的芯片型号有关,并且只包含一个芯片初始化函数,若想由编译器自动 调用芯片初始化函数,其函数名必须为"_HC08Setup",否则编译器会自动建立并调用 一个空的"__HC08Setup"汇编子程序, 而不理会用户创建的芯片初始化函数。 为了统一, 将该函数起名为"MCUInit",并在主函数中调用该函数。
7.2.3 通用函数头文件和通用函数文件

通用函数头文件和通用函数文件,“GenneralFun.h”和“GeneralFun.c”。 //[GenneralFun.h]通用函数头文件---------------------------------------------#i nclude"Type.h " //类型别名定义 void Delay(INT16U); //延时函数声明 “GenneralFun.h”中包含: (1)文件名 (2)通用函数所需用到的头文件 (3)通用函数用到的宏定义 (4)通用函数声明 外部函数要用到通用函数时,可包含这个头文件进行函数声明。
7.2.4 对象控制文件 7.2.5 中断处理函数和中断向量表文件

9. 硬件封装的思想 1) 与硬件相关的程序文件 与某个硬件相关的子程序放到 1 个程序文件中,该硬件的头文件放到一个文件中。 程序文件的开始处是有关说明:本文件所包含的子程序及简要的功能说明,子程序分 为内部调用和外部调用;硬件的连接说明。 2) 中断的开放和禁止 使用宏定义方式开放或禁止中断,宏定义语句放在 EnDisInt.h 头文件中。宏名的定义 方法: 开放中断以 Enable 标识,宏名中包含中断名,宏名最后以 Int 结束。如:开放串行接 收中断的宏名为:EnableSCIReInt。 禁止中断以 Disable 标识,宏名中包含中断名,宏名最后以 Int 结束。如:禁止串行接 收中断的宏名为:DisableSCIReInt。 开放所有中断宏名:EnableMCUInt。 禁止所有中断宏名:DisableMCUInt。


相关文章:
MCU-C程序编码规范
MCUC编程说明 4页 1财富值 C-C++程序编码规范sdf 25页 5财富值如要投诉违规内容,请到百度文库投诉中心;如要提出功能问题或意见建议,请点击此处进行反馈。 ...
mcu-c编程规范
MCU- 程序基本编程规范( MCU-C 程序基本编程规范(转) [ 2010-4-14 13:35:00 | By: gdqinci ] MCU-C 程序基本编程规范(转) 为了提高源程序的质量和可维...
单片机程序设计编程规范
单片机程序设计编程规范本规范适用于松翰科技 8-bit MCU 部门汇编程序编写准则,...Description: Version: Hardware&IDE Copyright (C), SONIX TECHNOLOGY Co., Ltd...
mcu 单片机c语言经典程序-实例
mcu 单片机c语言经典程序-实例_信息与通信_工程科技_专业资料。单片机实验 C ...该软件 位于单片机开发辅助工具文件夹中。 * 创建人 : 东流,2009 年 4 月 ...
MCU软件开发百花齐放
介​绍​M​C​U​软​件​开​发​工​具​的​现​...MCU 软件开发百花齐放中国 MCU 正进入自 2011 年以来开始的快速发展阶段。有...
C语言编写单片机程序的注意要点
C语言编写单片机程序的注意要点_计算机软件及应用_IT...年代开始而趋成熟, 成为 专业化的 MCU 高级语言了...都由 C 编译器代办; ·提供常用的标准函数库,以...
mcu-sample
mcu_2 61页 1下载券m​c​u​-​s​a​m​p​l​e ...STC-U7 USB 型脱机/联机 ISP 下载编程工具 工具分 5V 和 3.3V,有此工具的...
快速掌握MCU的方法
MCU 程序的编写: MCU 的程序的编写与 PC 下的程序的编写存在很大的区别,虽然现在在基于 CMCU 开发工具越来越流行,但对于一个高效的程序代码和喜欢使用汇编...
Microchip PIC24FJ1024GB61016位MCU开发方案
Microchip PIC24FJ1024GB61016 位 MCU 开发方案时间:2016-10-31 16:38:02 ...C 编译器优化指令集架构 两个地址生成单元,用于数据存储器的独立读取和写入寻址...
MCU综合实验2013
借助 Keil 编程环境和 Proteus 仿真软件,参考相关资料...2、 请注意文件名的规范。压缩文件文件名“MCU2013...二、硬件框图 74LS47 74LS47 AT89C51 74LS47 ...
更多相关标签:
c 编程规范 | 华为c语言编程规范 | c语言编程规范 | c 编程规范 pdf | google c 编程规范 | 嵌入式c语言编程规范 | 华为c编程规范 | c语言编程规范考试题 |