单片机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) 函数设没进口参数或者说参数,应用void明确说明。

    2) 函数名及说参数类型定义间应空一格且仅空一格

    3) 函数名与括号()之间无空格。

    4) 函数形参必须给起强烈的类型定义。

    5) 多只形参的函数,后一个示与前一个形参的逗号分割符之间添加一个空格。

    6) 函数体的左右花括号”{}” 各霸一行。

4.3 局部变量定义

    1) 同一行内并非定义了多变量。

    2) 同一接近的变量在同一行外定义,或者在互相邻行定义。

    3) 先定义data型变量,再定义idtata型变量,再定义xdata型变量.(?)

    4) 数组、指针等复杂类型的概念在定义区的末段。

    5) 变量定义区不开比较复杂的变量赋值。

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文件中:

        #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  头文件的命名

   
总的来说头文件的命名应尽量做到简约易掌握,见称知意。面向硬件对象头文件的称一定要同相应的硬件对象驱动文件同名。例???

公共头文件,如果对应于相应的源程序文件要建立,必须与的同名。如,“GeneralFun.c”是工程中之通用函数定义文件,(像内存数据移动函数,延时函数都属通用函数),其他文件在为此到这些函数之前,必须开展函数原型声明,从而建立与的同名的“GeneralFun.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<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。

在《朱棣的庙号本是“太宗”,嘉靖皇帝为什么用之移化了“成祖”?》平等温情遭遇,我既涉及刘邦的庙号是“汉太祖”,之后有粉丝在评头论足着“纠正”了自身的“错误”:“小编,刘邦的庙号应该是汉高祖”、“汉高祖刘邦,不是汉太祖刘邦”。

那么,这些粉丝真的说对了吗?

虽然我们平常老是管“汉高祖刘邦”这样的话挂于嘴边,可是有无数人只知其一不知其二:“汉高祖”是刘邦是,但是把“汉高祖”或“高祖”当作刘邦的庙号则是杀摩特错。

实在,“汉高祖”既未是庙号,也未是谥号,而是“庙号+谥号”的合称。具体来说,“汉太祖”是刘邦的庙号,“高皇帝”是刘邦的谥号(谥法无“高”,以为开国立朝功最高,故特于名焉),“汉高祖”则是刘邦“庙号+谥号”的合称。那么,“汉高祖”的布道是哪位发明的也?

“汉高祖”的传教太早来司马迁所著《史记》一写。在《史记》当中,司马迁首次用“汉太祖高皇帝”合称为“汉高祖”。后人遂误以为刘邦庙号也“汉高祖”或“高祖”。

则众口庙号和谥号傻傻分不到头,但要么有广大粉丝懂历史之。看到有人误把“高祖”当作刘邦的庙号时,很多粉丝就发心急地指出来了:“汉太祖,高皇帝
太祖是庙号,高皇帝是谥号”。

理所当然,“汉高祖”三配实在蛮爱招误解。因为庙号是国王大后在尽庙里立室奉祀时追尊的称,常用“祖”字或“宗”字,而据“祖有功,宗有道”的规范,开国国王一般受称作“太祖”或“高祖”,所以广大红颜会误以为“高祖”就是刘邦的庙号。再添加确实发诸多君主之庙号就是“高祖”,比如唐高祖李渊,所以马上误会就再次甚了。

只是,在了解了“汉高祖”三单字的来头之后,大家就应当好争取清清楚楚、明明白白了咔嚓!

自,写到此,我们发必要附上司马迁《史记》一修中之初稿,以正视听:

丙寅,葬。己巳,立太子,至顶上皇庙。群臣皆曰:“高爷爷起小,拨乱世反之正,平定天下,为汉太祖,功高。”上尊号为高皇帝。

值得一提的是,刘邦还是我国古代保守王朝历史上首先只具有庙号的上。虽然庙号起源于商朝,但周朝和秦朝也尚未沿用,所以庙号一度让废止了近千年之老。于是,刘邦便成为了封建王朝历史上第一个有着庙号的国君。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图