一个完整的信号采集系统项目开发流程

一. 摘要前端

    这篇文章详细介绍了一个“多路信号采集系统”的开发过程。“多路信号采集系统”是一个可伸缩的信号采集系统,通道能够选择从0~100路不一样的信号源。单个采集板都可以采集10路数据,用户能够根据本身的需求方便地扩展或者收缩信号通道数。本系统能够用于常见的民用或者工业现场监控、仪器仪表等数据采集场合。该系统基于Arm Context M3内核处理器实现,有基板和采集板两大部分组成,基板主要负责整个采集时序的控制,而采集板则完成真是的数据采集并将采集到的数据发送到数据总线,进而传输到主机端。数据传输采用了串口通讯的方式(RS485),并采用Modbus协议实现,从而方便地实现了采集板地址的检索、数据量控制、以及CRC校验值肯定等功能。软件系统则采用了固件库编程的方式,全程开发均使用C语言完成,从而为之后升级作好准备。开发使用了今日标企业工做平台以及Github代码托管平台相结合完成开发的方式,使用今日标企业工做平台管理项目开发流程,而使用Github则方便地实现了不一样地区开发者协做开发的目的。而系统调试则选择了传统的调试方式,先进行单个功能模块测试,再测试系统功能,进而Burning实验。
 

二. 本文提纲git

    1. 摘要
    2. 本文提纲
    3. 项目起始
    4. 开发方式选择
    5. 系统构架
    6. 硬件设计
    7. 软件设计
    8. 系统调试
    9. 总结
 

三. 项目起始github

    该系统是应兰州交通大学自动化研究所(一下简称为研究所)的项目需求进行开发。项目开始的时候谈的最多的问题主要有两个,一个是“钱”的问题,还有一个就是项目需求了。至于钱最后的商定结果为,天佑电子有限公司(如下简称天佑)只负责产品研发,开发过程当中全部的元器件、材料、以及测试系统的全部成本均由研究所承担,而天佑则只承担人力成本。最后研究所应该支付天佑XXX研发费用。因为之前有过不少次的合做经历了,因此谈判过程也比较顺利,也没有书面的合同约束双方。不过这也仅仅创建在双方已经有过不少次的合做经历,彼此都是很熟的人,项目自己技术上没有太大的复杂度,并且最终产品的应用场合也不会形成大的损失的基础之上。不过通常的项目合同是很重要的一个方面,合同不只仅为双方的行为创建起了约束,并且若是项目失败等形成损失,双方也可以明确本身的责任。至于项目需求,则只有如下几点需求:
    1. 信号通道数必须在50~100路之间(可伸缩)
    2. 单路信号偏差限定在0.03V以内
    3. 数据传输使用485协议
    4. 数据协议遵循Modbus协议
    5. 传送数据中必须包含数据量以及CRC校验值
    6. 上电或者数据传送过程都须要有相应的指示灯指示其状态
    项目自己是个很简单的项目,几乎没有技术上的难点。产品需求也一目了然,看了项目需求以后解决方案就已经呼之欲出了。经初步分析,整个设计过程当中惟一可能须要仔细斟酌的也就是多个板子之间通讯时的时序问题,事实证实,这部分到后面的确测试了挺长时间才实现功能,并且测试了好多边界条件才最终肯定下来最后的最优化参数。
 

四. 开发方式选择编程

    项目的开发方式选择了“今日标企业工做平台”和Github结合进行开发的方式。
    在本次开发中使用金目标的目的在于管控项目开发流程,实现整个开发过程简单的文档化。虽然该开发过程与如今所倡导的敏捷开发模式相违背,可是考虑到目前咱们的开发条件,最后仍是决定使用传统的文档化开发模式。在本次开发中因为参与开发的主要人员在不一样的地方(软件开发在江苏,而硬件开发在广东),形成了沟通上的诸多不便,而文档化则会改善一些沟通上的困难。将全部的开发过程都存放在一个公共平台上,你们能够随时查阅。这样也最大化地下降了沟通歧义所带来的项目风险。
    众所周知,Github是一个不只强大并且简单易用的分布式代码托管平台。对于不一样地域开发人员之间的协做开发来讲,拥有一个强大的代码共享平台相当重要。而Github恰好知足这些需求:
    1. 多方开发人员同时参与一个工程的开发
    2. 平台必须是分布式的,开发人员同时必须能编辑同一个文件
    2. 整个调试过程当中各个开发人员的代码必需要保持一致
    有关这两个平台的使用方法,这里就不作介绍了,在各自的官网上都有很详细的教程。在这里只提供两个平台分别的连接。金目标的连接为:http://www.jingoal.com ,Github的连接为:https://github.com 。
 

五. 系统架构安全

   
 
  系统架构
 
  系统设计时考虑到可伸缩性,以及采集通道要求太多,故而将数据采集任务分给多个采集板去完成。每一个采集板各自完成本身的采集任务,并将采集到的数据传送到数据总线。而具体的什么时候采集数据,以及什么时候传送数据到数据总线并交给PC段,则有Base Board控制。在这里设计的时候并无将采集到的数据由Base Board传送到PC上,而是放到数据总线上直接由PC提取。这种设计是基于如下考虑,若是全部采集到的数据全都交由Base Board向上传送,则至关于多了一级路由,这样会下降整个系统的数据采集速率。也加剧了Base Board的工做任务,使其控制逻辑变得复杂,严重违背“简单即为美”的编程原则。
 

六. 硬件设计数据结构

    有关硬件设计的部分,因为我本人对于硬件不是很擅长,因此可能总结很差。故而请了咱们团队中的另外一位硬件工程师撰写。在这里我就只上两张设计的电路图。
采集板电路图
 
基板电路图

七. 软件设计架构

    在本系统中软件设计分为两个部分,采集板软件设计和基板软件设计。下面分别就这两方面介绍整个软件开发的过程。
    1. 采集板软件设计:
    在肯定了采集板功能的状况下再开始软件设计。本次设计中采用了“从两端到中间”的软件开发模式。所谓“从两端到中间的开发模式”是指在软件开发过程当中,首先按照软件的架构层次习惯,将软件分为前端界面、中间逻辑控制层、以及底层的模型层(这是PC软件的开发框架)。而对于咱们嵌入式软件来讲,也能够分为相似的层。我在此次开发过程当中,则是将整个软件分为:业务逻辑、中间件、以及底层驱动模型。而从两端到中间的开发则是指先开发底层驱动,而后再肯定 业务逻辑 ,而后经过中间件将两个部分衔接起来,并进行测试的方法。
    首先根据需求肯定软件中须要使用到的底层硬件驱动分别有:AD、USART、DMA、GPIO、外部硬件中断。而在嵌入式系统中,通常还须要一些延时之类的功能,故而还须要提供一些延时函数的驱动。下图显示的是本次设计中用到的全部驱动,虽然开发过程选择了使用STM32官方提供的固件库编程方式,可是若是彻底使用固件库中的函数,而没有通过封装。则主函数将会显得很臃肿,并且整个软件系统的业务逻辑和底层驱动也严重耦合在一块儿,不便于之后系统维护、升级,也会大大下降系统的可移植性。
    这里的驱动设计,其实从本质上来说的话只是对固件库中的一些函数或者是宏定义进行进一步的封装。例如ADC部分的驱动,在~/ADC/adc.c文件中只须要系统一个Adc_Init函数,在该函数中完成对CPU ADC资源的初始化。而对应的USART设备。不只要提供初始化函数,还须要提供一些发送数据以及接收数据等的函数。并且为了调试方便期间,通常按照我我的的习惯的话还会添加一部分代码,用以支持printf函数,利用该函数经过串口向PC端,打印出一些程序执行的信息,这样会大大方便嵌入式软件调试。对于STM32来讲,要支持printf函数只须要加入如下代码:
//加入如下代码,支持printf函数,而不须要选择use MicroLIB
#if 1
#pragma import(__use_no_semihosting)             
//标准库须要的支持函数                 
struct __FILE 
{ 
int handle; 
 
}; 
 
FILE __stdout;       
//定义_sys_exit()以免使用半主机模式    
_sys_exit(int x) 
{ 
x = x; 
} 
//重定义fputc函数 
int fputc(int ch, FILE *f)
{      
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   
    USART1->DR = (u8) ch;      
return ch;
}
#endif
View Code

驱动文件列表
 
    完成了驱动程序的设计以后,则设计业务逻辑。 业务逻辑 是指从用户需求的角度完成用户须要的功能的一部分代码。这部分代码通常都是指Main函数中的逻辑。在这次设计中主要的执行流程可使用如下的图表示。
 
业务逻辑
 
    最后设计的是中间件,中间件的设计不只要考虑到业务逻辑的需求,更要兼顾底层驱动模型的实现方式。只有将这二者比较好地结合起来,最终才能获得比较理想的产品。
    从底层往上层看,中间件是对底层驱动更高一级的封装,底层驱动只是实现独立的单个功能点。而经过中间件不只实现了这些功能点,并且融入了一部分系统功能的成分在里面。从上层往底层看,中间件则能够理解成对于系统业务逻辑的细化。业务逻辑相似于将用户需求文本化或者“代码化”,从本质上来说,它仍是在用户需求一级。而经过中间件的做用,则将抽象的业务逻辑实现了具体化,成为对于处理器来讲可以识别并执行的真实代码。
    以上就是采集板的整个软件开发思路以及开发过程,这里的程序从其流程来看,的确是几乎没有复杂度。可是在这里提出了一些软件开发过程当中的框架,一种分层机制。框架的出现将系统级的软件分红各个不一样的模块,或者分为不一样的层。从而实现了软件良好的可维护性,也大大方便了后期系统升级。对于软件框架的理解,我也只是一个初学者,在这里提出权当是抛砖引玉了吧。
    1. 基板软件设计:
    从软件的角度来说,基板是整个系统时序的控制者。就仿佛人的大脑通常,它能够发出各类指令让系统的各个部分可以各司其职,而不会致使系统紊乱。本次设计中,基板主要的工做流程以下:
基板的主要工做流程
 
    设计过程当中基板中有一个惟一值得注意的地方就是板子复位后在线板的检测,在这个系统中挂在基板上的采集板的个数在0~10个之间是随意的,而控制板发送采集信号命令的时候应该只对当前系统中已经挂载的采集板发送。故而在设计之时,软件中设计了一个链表,你们知道链表是一个大小能够动态分配的数据结构,因此咱们能够讲在线板的信息存储在这个链表当中,而每次须要发送控制命令的时候只要遍历整个链表,并发送控制命令便可。
 

八. 系统调试并发

    在完成了系统硬件设计以及软件设计以后,接下来的主要任务就是单个模组测试以及系统测试。测试过程主要地能够分为如下几个部分:
    1. 单个驱动功能点测试
    2. 采集板功能测试
    3. BaseBoard功能测试
    4. 系统功能测试
    5. 系统稳定性测试
 
    下面分别介绍这次开发过程当中针对前面5个测试点的具体实现过程。
    1. 单个驱动功能点测试:
    单个驱动功能点测试是指在测试单个功能块,好比在系统中用到的串口通讯模块、GPIO模块、中断模块等。包括硬件电路测试和软件驱动测试。这部分的测试对于整个系统测试来讲是一个基础测试,但也是相当重要的部分。只有保证了全部单个功能点可以正确地工做才使得后续系统逻辑无误成为可能。根据前面的介绍,在本次设计过程当中,用到的全部驱动全都封装在相应的驱动文件中,而且单个功能点都很是独立。前面全部的驱动都可以独立出来造成一个完整的测试用例。而个人作法则是先建立一个通用的测试模板(一个没有实现任何功能只包含main函数的工程)。在测试过程当中只须要分别将须要测试的驱动移植到该测试工程中,而且在main函数中调用驱动中提供的函数进行测试便可。
    2. 采集板功能测试:
    在本系统中,采集板的主要任务是根据基板的控制命令,完成采集数据的动做,并将采集到的数据按照以前的协定进行整理,而后传送到基板数据总线。因此对于基板的测试,则须要再使用一个模拟基板控制流程的电路板,或信号发生器之类的控制器。而个人作法是使用了一个51板,该板只完成产生一个定时跳变的功能。
采集板功能测试
    3. BaseBoard功能测试
    对于基板而言,测试的关键有两个方面:
        1> 检测在线板,并将在线板信息保存在队列中
        2> 按照队列中的信息,将控制信息发送到采集板中
    其测试过程反而比较简单,只须要将测试的信息所有经过串口发送到PC段,根据PC端的显示信息便可判断是否实现了须要的功能。可是在测试的过程当中发现了一个问题:串口要使用printf函数向上位机发送信息,则须要实现前面所示代码,可是这部分代码与工程中使用的malloc函数所在库stdlib冲突,故而产生了编译不过去的问题。也就是说在一个工程中这两个功能只能使用其中一个。而malloc函数是实现双向链表的关键,不能却去掉。因此我选择了本身实现一个向上位机发送字符串的方法。具体实现的代码以下:
void Send_Data(USART_TypeDef* usartx, uint16_t data)
{
USART_SendData(usartx, data);
}
 
void Send_String(USART_TypeDef* usartx, char *str)
{
while(*str != '\0')           //判断字符串是否发送完毕
{
Send_Data(usartx, *str);        //发送单个字符
str++;                 //字符地址加1,指向先下一个字符
delay_ms(5);
}
}
View Code

 

    4. 系统功能测试
    在完成了前面几个部分的测试以后,对于后面系统功能测试,其实须要作的工做就少了不少。基本上只须要处理好整个系统工做时的时序便可。
    测试的过程当中,首先不是将全部的采集板全都挂载到基板上去测试,而是只挂载一个测试基板和采集板的协同工做是否正确。这部分的测试大概使用了4个小时的时间,期间调整了两个板子同时上电后的时序,这个时序是经过延时来控制的。基本的流程是上电以后采集板完成系统初始化以后,置位在线信号(置位这个信号以后基板就可以检测到采集板是否在线,若是采集板不在线,对应的端口呈现的状态应该是低电平输入),而后以个比较长的延时(我用了大概5S的时间),而基板则是完成初始化以后也是在一个比较长的延时(我选择2S)以后,再检测采集板的在线状况。使用这样的时序,就能够保证只要整个系统同时上电,可以安全采集到在线采集板的信息。这里虽然是一个比较简单的逻辑,可是设计之时因为忽略了两个板子上电以后完成初始化的过程所使用的时间相差比较大,在通过了不少的测试,并评估以后仍是决定采用长延时这种安全的方式去处理上电后检测采集板在线信息的任务。
    完成了在线检测以后,就可以肯定在线板的信息已经存在于前面设计的队列之中了。后面须要测试的就是可否根据采集板的在线信息发送了控制指令以后采集板是否可以采集到数据并传送上上位机上。经测试这部分的逻辑很容易实现,只要发送了控制信息,采集板就可以发送控制信息到上位机上,可是发送了信息以后对于基板而言,还须要作的工做是等待采集板给它发送闲信号。基板的设计使用了while等待的方式,发送完控制命令以后一直等待直到收到当前工做的采集板发送了闲信号给它以后才推出循环,再对下一块采集板发送控制指令。如此循环,便能实现一直轮询采集的任务。
    在完成了单个采集板的系统测试以后,就须要测试同时挂载多个采集板时系统的工做状况了。在测试的过程当中发现了一个问题,采集板的个数比较少的时候系统才能正常工做,可是当个数超过三个的时候指示灯显示系统是在正常采集数据,可是485就是没法接收到数据。怀疑为全部模块都为发送使能,有多是相互之间的干扰形成数据通信异常,建议软体方面改变使能端口状态,当空闲时关断使能,将总线释放,用示波器实测AB输出波形发现,当单个模块介入系统,不进行数据通信时A为“1”,B为“0”,当进行数据通信时,A变为“0”时,B将变为“1”,高电平值3.3v,当接入2个模块,不进行数据通信时A为“1”,B为“0”,当进行数据通信时,A变为“0”时,B将变为“1”,但A的低电平值变为1.56v,而B的高电平值也变为了1.56V。今后能够推断,非通信模块要将A上拉的3.3V,B要下拉的0V,而通信的模块想让A变为0V,B变为3.3V,并联的模块越多,电平值越小,直至AB差分判断失效,形成相互干扰。切记一点:但不使用总线时要释放总线,防止相互干扰。
    通过以上的测试,就可以肯定从功能的角度来说,系统是没有问题了。稳定性还有待测试。
    5. 系统稳定性测试
    系统稳定性的测试,无外乎就是测试系统长时间的工做是否可以依然正常。由于系统长时间工做会形成系统发热,而若是热量太高,则有可能致使整个系统阻抗以及容抗等都发生变化,形成系统不能正常工做。经测试系统工做20小时以上功能依然可以知足,电源部分会有一点热。通过再三考虑,最后仍是加了一个散热风扇(使用了普通PC机上的散热风扇)。再加了风扇以后发现电源部分的发热现象明显有了好转。最后通过48小时的烧机实验,肯定系统无误!!!
 

九. 总结框架

    以上就是整个此次《信号采集系统》的开发过程。就如在前文所说,这个系统是一个很简单的系统,没有任何技术难点可言。写这篇博文,只是想抛砖引玉,但愿你们之后能够多推出相似的关于开发流程管理等的文章,你们共同窗习进步。在开发的过程当中确定还有不少不完善的地方,很是期待有这方面爱好的朋友可以提出宝贵的意见,以便我改进。最后再上几张产品的图片吧。
相关文章
相关标签/搜索