专业技术总结(电子专业职称评审)

  • 格式:pdf
  • 大小:223.54 KB
  • 文档页数:6

下载文档原格式

  / 6
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

专业技术总结

从2009年7月毕业至今,将近快10个年头了,这些年辗转于多个企业,一直从事跟电子行业相关的工作,下面就从专业角度,来阐述我对行业的一些认识。

一、底层和应用层分开编写,若底层中需要用到少量应用层的代码,又没有必要将底层的代码放到应用层调用:

1:可以采用指向空指针函数,直到函数具体的调用时在指向调用的函数指针;

2:熟悉stm32单片机朋友都直到HAL库的调用经常会用到回调函数,所以如果函数名称前面加上__weak 修饰符,我们一般称这个函数为“弱函数”。加上了__weak 修饰符的函数,用户可以在用户文件中重新定义一个同名函数,最终编译器会选择用户定义的函数,如果用户没有重新定义这个函数,那么编译器就会执行__weak 声明的函数,并且编译器不会报错,这在我们经常用的中断函数的时候,往往要重新去编写自己的函数。这种方法通常需要根据编译环境的要求去编写。

不建议采用extern语句引出需要调用的函数或者采用包含头文件的方式,这样子会造成代码结构的不清晰。

二、模块化编写的思想:

即我们在高级语言中常用到的类的思想,将一些共性的东西抽象成一个类(cla ss),类的对象对于类的本身是可见的,对于外部可以定义成可见和不可见。虽然嵌入式的编译环境往往不支持类,但我们可以采用这种思想,使编写的代码具有高内聚性低耦合性,通过接口(interface)的方式去引用,不必去关心接口本身的实现。举个我做过方案的例子:如下图:

具体的动作流程在这里不再赘述,根据软件功能模块划分为进料模块,取料模块,初拧模块,扭力测量模块,搬运模块,后焦测量并调整模块,卸料模块。每个模块定义成相对独立的整体,即不关心其他模块的运行,只关心输入条件改变和内部的状态,输出结果也可以提供给其他模块做输入条件,这样将整体运行的流程分解成模块,每个模块成为最小化单元,将复杂的逻辑简化了,同时也满足并行运动功能,可以进行流水线作业。试想,如果不采用模块化编程的方式,而采用顺序流程的方式,将整个顺序流程进行展开,你将发现整个流程图变得异常庞大,盘根错节,异常恢复的入口也不知道从何而入,能否进行流水线作业也是个未知数。作为一个嵌入式工程师,能够适时将硬件或者软件进行模块化设计选择尤为重要。

三、状态机编程的思想:

也许我们在大学时候只有在学习fpga编程中才会用到状态机方式去编程,可能我们会认为跟fpga采用编程语言或者需要考虑逻辑细节时才采用状态机编程,我想这个想法是错的。状态机编程方式,将单个模块分解成若干个状态机,由状态机形成状态转移图,容易知道什么时候在什么状态,什么时候跳入另一种状态,方便调试;避免了重用非状态机模式下的变量定义,使编程思路变得不清晰,采用状态机编程方式方便阅读,甚至软件中都可以省去注释。

四、可移植性:

编写的软件最好方便跨平台,不同编译软件之间的移植,通常每个单片机都有若干个常用的编译工具,不同编译器可以对相同数据类型长度有可能不一样。移植的过程要特别注意。如

avr单片机常用的开发环境有ICCAVR,AVRSTUDIO,IAR,PIC单片机常用的开发环境有MPLAB,HI-TECH,那么将数据类型定义在头文件在,采用宏定义来区分不同的编译器,这样不同编译器的就不用重写数据类型了。如我采用以下方式来区分不同的PIC编译器:

#ifndef __ZH_TYPEDEF_H

#define __ZH_TYPEDEF_H

#define PIC_C 1 //使用PICC编译器编译PIC10,12 , 16系列

#define PIC_C18 2 //使用PICC编译器编译PIC18

#define MPLAB_C18 3//使用MPLAB C18编译器编译PIC18

#define MPLAB_C30 4//使用C30编译器

#define COMPILER MPLAB_C30

/*

********************************************************************* *

* 自定义数据类型

********************************************************************* *

*/

/*

*PICC18,PIC16,MPLABC18对于unsigned数据类型命名全部一致

*/

/*******************8bit********************/

typedef unsigned char zh_u8; /* 无符号1个字节 */

#if (COMPILER == PIC_C18) || (COMPILER == MPLAB_C18) || (COMPILER == MPLAB_C30)

typedef char zh_s8; /* 有符号1个字节 */

#elif (COMPILER == PIC_C)

typedef signed char zh_s8; /* 有符号1个字节 */

#endif

/******************16bit*******************/

typedef unsigned int zh_u16; /* 无符号2个字节 */

#if (COMPILER == PIC_C18) || (COMPILER == MPLAB_C18) || (COMPILER == MPLAB_C30)

typedef int zh_s16; /* 有符号2个字节 */

#elif (COMPILER == PIC_C)

typedef signed int zh_s16; /* 有符号2个字节 */

#endif

/******************24bit******************/

#if (COMPILER == PIC_C18) || (COMPILER == MPLAB_C18) || (COMPILER == PIC_C)

typedef unsigned short long zh_u24; /* 有符号3个字节 */

#endif

#if (COMPILER == PIC_C18) || (COMPILER == MPLAB_C18)

typedef short long zh_s24; /* 无符号3个字节 */

#elif (COMPILER == PIC_C)

typedef signed short long zh_s24; /* 无符号3个字节 */

#endif

/******************32bit******************/

typedef unsigned long zh_u32; /* 有符号4个字节 */

#if (COMPILER == PIC_C18) || (COMPILER == MPLAB_C18) || (COMPILER == MPLAB_C30)

typedef long zh_s32; /* 无符号4个字节 */

#elif (COMPILER == PIC_C)

typedef signed long zh_s32; /* 无符号4个字节 */

#endif