一. 良好的编程风格

1.排版:a. 代码缩进空格数为4 个。若是可能,尽量用空格来代替Tab键,因为有些编译器不支持Tab键(我自己至今未见过,但确实有这个风险),这给程序的移植带来了问题。

      b. 较长的语句要分2行来书写,并用‘\’符号隔开。

      c. 函数代码的参数过长,分多行来书写。void UARTSendAndRecv(UINT8 *ucSendBuf,
                                     UINT8 ucSendLength, 
                                       UINT8 *ucRecvBuf, 
                                     UINT8 ucRecvLength)

      d. if、do、while 、switch、for、case、default 等关键字,必须加上大括号{}。

      c. 函数头应该进行注释,例如函数名称、输入参数、返回值、功能说明。

      e. 复杂的宏定义同样要加上注释。

2.模块化程序设计应该理解以下概述:

     (1) 模块即是一个.c 文件和一个.h 文件的结合,头文件(.h)中是对于该模块接口的声明;

          一个嵌入式系统通常包括两类(注意是两类,不是两个)模块: 
                      (1)硬件驱动模块,一种特定硬件对应一个模块; 
                      (2)软件功能模块,其模块的划分应满足低偶合、高内聚的要求。

      下面以 keil C  编译器为例,讲一下模块化编程的步骤。下面这个程序分为三层,共 7 个模块,共同为主程序服务(它们之间也会相互调用)。

      

程序主要模块和功能简介:
一. 底层驱动
  1.  红外键盘:程序通过红外键盘进行操作。红外键盘独占定时器0 和外部中断 0 ,以实现红外解码和键盘键值的识别。红外键盘定义了五个按键,分别为上翻、下翻、左翻、右翻和确认键。 
  2. LCD 液晶显示:程序主要通过 LCD 显示信息,LCD 液晶显示驱动提供显示汉字、图形和 ASCII码的函数接口。可以全屏、单行显示汉字,任意位置显示ASCII码,还可以全屏、半屏显示图形。

二.  功能模块
  1. LCD 菜单程序:菜单程序可以使人机交互更加方便、容易。本菜单程序的菜单级别深度受 RAM 大小的限制,每增加一级菜单将多消耗 4 字节的 RAM 。菜单程序主要完成菜单功能函数的调度,LCD 显示刷新。
  2.  计算器程序:实现 65536 以内的加、减、乘、除,超出范围会出现溢出,溢出发生时,LCD 显示“错误:出现溢出”的错误提示,同时本次运算被忽略。对于负数会显示“-”号,除数为零时 LCD 显示“错误:除数为零”的错误提示。

  3.  开机次数记忆程序:主要对基于 IIC 总线的 EEPROM 进行读写,单片机每次上电后,将开机次数写入 EEPROM. 
  4.  串口测试程序: 进入该程序后,单片机向电脑发送字符串“Hello Word!”,发送数字24(以字符的形式显示)。编写此程序的目的是为了能够方便的向电脑发送字符串和变量,便于程序的调试。串口占用串口资源,与频率测量程序共享定时器 1
  5.  频率测量:复用定时器 1,占用外部中断 1,实现 5~20KHZ 频率的测量.

三.  主程序
     主程序主要完成程序的初始化,LCD 菜单显示,监视键盘程序并根据键值更新菜单。

定义  红外键盘模块:key.c 与key.h
                             菜单模块:menu.c与menu.h
                             串口通信模块:uart_.c 与uart.h
                             计算器模块:counter.c 与counter.h 
                             频率测量模块:mea_fre.c 与mea_fre.h
                            开机次数记忆模块:eepram.c 与eepram.h

1.static 关键字:在嵌入式C语言当中,它有三个作用:
       作用一:在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。

       作用说明了局部静态变量的特性:在函数体(子),一个被声明为静态的变量(也就是局部静态变量)在这一函数被调用过程中维持其值不变(子,局部会释放为0)。声明函数的一个局部变量,并设为static 类型,作为一个计数器,这样函数每次被调用的时候就可以进行计数。  

        作用二:在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。(一个C项目可以分为多个模块C文件,一个C文件可以包含多个函数体)。(相同名字的变量,不会发生冲突)

        作用三:在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用(静态函数)。(相同名字的函数,不会发生冲突;)

最后说一下存储说明符,在标准C语言中,存储说明符有以下几类:
     auto、register 、extern 和static  对应两种存储期:自动存储期和静态存储期。
     auto和register 对应自动存储期。具有自动存储期的变量在进入声明该变量的程序块时被建立,它在该程序块活动时存在,退出该程序块时撤销。
     关键字extern 和static 用来说明具有静态存储期的变量和函数。用static 声明的局部变量具有静态存储持续期(static storage duration),或静态范围(static extent)。虽然他的值在函数调用之间保持有效,但是其名字的可视性仍限制在其局部域内。静态局部对象在程序执行到该对象的声明处时被首次初始化。

2.  const 关键字

a. const关键字修饰的变量可以认为有只读属性,但它绝不与常量划等号。const int i=5;
                                           int j=0;

              i= j;     // 非法,导致编译错误,因为只能被读 
                     j=i;     // 合法

      b. const关键字修饰的变量在声明时必须进行初始化。如下代码:
                                    const int i=5;     // 合法 
                                         const int j;       // 非法,导致编译错误

      c. 用const声明的变量虽然增加了分配空间,但是可以保证类型安全。

      d. C 标准中,const定义的常量是全局的。

      e. 必须明白下面语句的含义,方法是:若是想定义一个只读属性的指针,那么关键字const要放到‘*  ’后面。
             char *const cp; //指针不可改变,但指向的内容可以改变
           char const *pc1; // 指针可以改变,但指向的内容不能改变
           const char *pc2; // 同上(后两个声明是等同的)

        f.  将函数传入参数声明为const,以指明使用这种参数仅仅是为了效率的原因,而不是想让调用函数能够修改对象的值。 
        参数const通常用于参数为指针或引用的情况,且只能修饰输入参数;若输入参数采用“值传递”方式,由于函数将自动产生临时变量用于复制该参数,该参数本就不需要保护,所以不用const修饰。例子:
        void fun0(const    int  * a );  
        void fun1(const    int  & a);
       调用函数的时候,用相应的变量初始化const常量,则在函数体中,按照const所修饰的部分进行常量化,如形参为const  int  * a,则不能对传递进来的指针所指向的内容进行改变,保护了原指针所指向的内容;如形参为const  int  & a,则不能对传递进来的引用对象进行改变,保护了原对象的属性。 
        g. 修饰函数返回值,可以阻止用户修改返回值。(在嵌入式C 中一般不用,主要用于C++ ) 
        h. const消除了预处理器的值替代的不良影响,并且提供了良好的类型检查形式和安全性,在可能的地方尽可能的使用const对我们的编程有很大的帮助,前提是:你对const有了足够的理解。
  最后,举两个常用的标准C 库函数声明,它们都是使用const的典范。
  1. 字符串拷贝函数:char *strcpy(char *strDest,const char *strSrc );
  2. 返回字符串长度函数:int strlen (const char *str);

嵌入式C语言进行曲之要诀相关推荐

  1. uml+oopc嵌入式c语言开发精讲_当前火爆的嵌入式领域,为什么选择C语言作为开发语言?了解一下...

    C语言和嵌入式C编程有什么区别?其区别在于嵌入式的C语言是跑在嵌入式的开发板上的,CPU和电脑不一样,所以编译器也是不一样的,生成的可执行程序也是不一样的.选择嵌入式开发语言归结于嵌入式系统开发的特点 ...

  2. c语言里变量列表,嵌入式C语言里的土豪们之变量类型

    嵌入式C语言里的土豪们之变量类型本文引用地址:http://www.eepw.com.cn/article/184332.htm 上一篇我们谈到了运算奢华大户除法(详见<嵌入式C语言里的土豪们之 ...

  3. 嵌入式c语言为什么变量定义在前面,嵌入式C语言数据类型和变量详解

    原标题:嵌入式C语言数据类型和变量详解 一般来讲,标准的C语言类型在嵌入式编译器中是合法的.但由于嵌入式控制器的受限环境.嵌入式c语言的变量和数据类型具有新的特征,这些特征体现在如下方面. 嵌入式C语 ...

  4. 16道嵌入式C语言面试题(经典) 预处理器(Preprocessor)

    16道嵌入式C语言面试题(经典) 预处理器(Preprocessor) 1. 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题) #define SECONDS_PER_ ...

  5. 嵌入式C语言基础(一)

    嵌入式C语言基础: system函数:功能是运行windows命令 #include <stdio.h> #include <stdlib.h> int main() {//m ...

  6. c语言编码风格,讲嵌入式C语言编码风格.ppt

    讲嵌入式C语言编码风格 目 录 简介及说明 语言规则 1.基础 2.数据 3.说明与表达式 4.函数 5.内存及资源 6.源文件 风格指导 7.程序书写 8.命名 9.文档 简介及说明 正确性 易维护 ...

  7. 嵌入式c语言移植,嵌入式C语言位操作的移植方法

    单片机的应用越来越广泛,种类也越来越多.由于嵌入式C语言可读性强.移植性好,与汇编语言相比大大减轻了软件工程师的劳动强度,因而越来越多的单片机工程师开始使用C语言编程.但C语言的可移植性仅限于与硬件无 ...

  8. uml+oopc嵌入式c语言开发精讲_新的程序开发模式出现,传统的嵌入式C语言程序员快要灭绝了?...

    来源:嵌入式时代@头条号 在2000年前后,嵌入式软件工程师有着一套非常具体的技能,他们通常是电气工程师,不仅了解底层硬件的工作原理,还可以在底层编写汇编代码或者C语言代码,以使系统满足实时需求.嵌入 ...

  9. c语言 怎么访问64位地址_大神用10000字总结了嵌入式C语言必学知识点……

    导读:怎么做好嵌入式?相信这个问题无论问谁你都会得到一句学好C语言!今天推荐一篇大佬写的嵌入式C语言知识点总结,非常值得一读. 从语法上来说C语言并不复杂, 但编写优质可靠的嵌入式C程序并非易事,不仅 ...

最新文章

  1. 技术分析:搞懂链路追踪
  2. npm package.json文件解读
  3. delphi编码规范文档
  4. 安置和设置Opera9.50Beta2
  5. 零c语言txt下载,C语言问题c-0是什么意思
  6. ios开发第一步--虚拟机安装MAC OS X
  7. 【CodeForces - 633D】Fibonacci-ish (离散化,暴力枚举+STPmap,fib数列收敛性质)
  8. IOS资源丰富的听书软件<白鲨听书>
  9. IPC--进程间通信三(共享内存)
  10. PAT A1096 质因子分解
  11. 计算机组成原理mw,计算机组成原理 存储器
  12. Digilent提供的PmodOLEDrgb驱动程序
  13. 光敏电阻控制led亮度程序_Arduino动手做(2)光敏电阻模块
  14. 四个Python爬虫案例,带你掌握xpath数据解析方法!
  15. cad字体安装_拿了CAD字体不知道怎么装?看过来
  16. 波长间隔与频率间隔换算
  17. 微信状态栏隐藏 HTML,微信里几个实用的隐藏小技巧!
  18. 网络流媒体(七)———PTSP
  19. 【Python机器学习基础教程】(三)
  20. 一种开环控制的两轮差速驱动小车的设计

热门文章

  1. java对于app版本号比较,Java对比APP版本号大小
  2. 清华大学梁宸计算机系,应用数学专业论文
  3. VScode 无法创建文件或者无法保存文件
  4. 汉诺塔问题java编程,Java经典编程300例之实例047 汉诺塔问题求解(递归)
  5. 青羊区光华中心机器人_北京大学招收机器人工程本科生
  6. sharding-jdbc分库分表的 4种分片策略
  7. Tomcat(五):Tomcat 参数调优教程
  8. telnet给服务器发消息,[摘抄]使用telnet命令直接发送
  9. 用Python几行代码实现简单的人脸识别,10分钟完成(附源码)
  10. Python的零基础超详细讲解(第六天)-Python的数字类