找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 32693|回复: 28
打印 上一主题 下一主题
收起左侧

基于Android显示的便携式数字示波器 毕业设计(论文)

  [复制链接]
跳转到指定楼层
楼主

本设计是基于stm32单片机制作的,实物图片如下:

电路图下载: Android示波器电路原理图.zip (96.22 KB, 下载次数: 295)

源代码下载: Android、STM32源代码.zip (4.65 MB, 下载次数: 316)

完整版的论文下载word格式:
(毕业论文)基于Android显示的便携式数字示波器.zip (3.11 MB, 下载次数: 295)

以下是论文预览:

本科毕业设计论文)

基于Android显示的便携式数字示波器
        学    院      物理与光电工程学院      
        专    业        电子科学与技术         
        年级班别2009级(5)班         
        学    号
        学生姓名
        指导教师
摘要

数字示波器作为一种测量仪器,因其具有体积小、可长期贮存波形并具有波形分析处理能力等优点,使得它日益普及。由于目前国外在数字技术方面比国内发达很多,数字存储示波器的大部分市场被国外企业占有。而国内的数字存储示波器的研制处于起步阶段,因此迫切需要加快相关技术的发展。

本文主要介绍了基于单片机STM32控制的、并在Android上进行显示的便携式数字示波器。STM32单片机是一款性价比非常之高的处理器,最高时钟可达72M,完全能满足本设计的要求。Android系统作为一个开放的移动平台,在最近几年发展非常的迅速。在这个Android设备高度普及的时代,如何充分利用它的软硬件资源就显得尤为重要。

采用Android设备作为显示平台,是本设计最大的一个特点。本设计的基本思路是,由单片机对ADC采样到的数据进行处理,再通过蓝牙把波形数据发送到Android设备上进行显示。同时由于Android设备都采用触摸屏,因此示波器的参数可以很方便的通过触摸屏进行设置。本设计采用Android设备取代液晶屏,并使用蓝牙进行数据传输,充分利用了Android设备的硬件资源。其优点是降低了系统开发成本,并大大减小了系统硬件体积,完全实现了本设计小巧便携的设计宗旨。

关键词:数字示波器,STM32,安卓,蓝牙

1 绪论

1.1 示波器概述

1.2 数字示波器的特点及原理

1.3 数字示波器国内外研究状况

1.4 Android概述

1.5 题目研究背景及意义

2 数字示波器原理分析与技术指标

2.1 数字示波器的组成原理

2.2 数字示波器与模拟示波器相比较

2.3 数字示波器技术指标

2.3.1 最大采样速率

2.3.2 存储宽度

2.3.3 分辨率

2.3.4 记录长度

2.3.5 存储带宽

2.3.6 垂直灵敏度及误差

2.3.7 扫描速度及误差

2.4 采样原理分析

2.4.1 实时采样方式的原理

2.4.2 等效取样方式的原理

3 系统方案论证

3.1 系统总体方案设计

3.2 数据采集系统

3.2.1 波形整形电路方案选择

3.2.2 程控放大电路方案选择

3.3 数据处理系统

3.3.1 触发方案选择

3.3.2 峰值测量方案选择

3.3.3 测量频率方案选择

3.3.4 采样方案选择

4 系统硬件电路设计

4.1 微控制器电路

4.2 电源电路设计

4.3 信号采集电路设计

4.3.1 A/D转换及FIFO缓存器

4.3.2 程控放大电路

4.3.3 电平移位电路设计

4.3.4 频率测量电路

4.4 无线数据传输

5 系统软件设计

5.1 单片机软件开发环境

5.2 主程序设计及流程图

5.3 数据处理子程序

5.3.1 同步触发的软件实现

5.3.2 频率计算原理及流程图

5.3.3 测量信号峰峰值

6 Android显示平台

6.1 Android应用开发环境

6.1.1 Android简介

6.1.2 开发所需的软件包

6.1.3 搭建Android开发环境

6.1.4 测试所配的开发环境

6.2 Android蓝牙通信设计

6.2.1 Android设备中蓝牙模块的使用

6.2.2 蓝牙数据通信

6.3 Android上绘制波形

6.3.1 SurfaceView的使用

6.3.2 绘制波形子程序

结论

参考文献

致谢

附录 A  实物图

附录 B  系统主程序设计源码

附录 C  Android蓝牙服务程序设计源码




1 绪论1.1 示波器概述

示波器作为一种精密的测量仪器,广泛地应用在科研、教育、农业生产、军事等各个领域。示波器是一种用短暂扫描的方式记录并显示一个瞬间信号的测量仪器,可以直观地表示二维变量之间的瞬态或稳态函数关系、逻辑关系,以及实现对部分物理量的存储和变换[1]。

随着上个世纪七十年代雷达、电视和航空等领域的发展,研制对于电信号能够实现检测和跟踪的设备已成为急需,示波器在这个时期应运而生。带宽为100MHz的同步示波器研制成功,成为近代示波器的基础[2]。1972年美国尼科莱特公司利用模数转换器件,成功研制出世界上首台数字存储示波器,为信号数字化、数据的存储、信号处理和参数跟踪开辟了一条新的途径。

示波器从原理上可分为模拟和数字两种。传统的模拟示波器也就是电子管示波器,其原理是用被测信号去控制示波管的X、Y通道,达到控制阴极电子束的偏移的目的,从而实现在荧光屏上显示被测信号的波形。但很容易发现,传统的模拟示波器有很多缺点,比如操作复杂、不方便携带、笨重、耗电量大以及无法用于测量非周期、单次信号,这些缺点都给实际应用带来了许多不便。为了解决传统模拟示波器的缺点,并实现将各种信号无失真地显示并存储,数字示波器应运而生。数字存储示波器可直观的显示出被测信号的实时曲线,并可进行瞬态分析[3]。目前数字示波器已取代模拟示波器成为市场上的主流,并朝着智能化的方向发展。

近几年,随着计算机技术的发展,出现了虚拟示波器。传统示波器频带较宽,实时性较好,但功能比较单一,人机界面不够友好。采用虚拟示波器技术可以以低廉的成本解决这些问题。虚拟示波器是虚拟仪器技术的应用,它使用数据采集卡采集现场信号,通过接口电路传输数据到计算机,再借助强大的监控软件模拟示波器的操作面板,实现信号采集、分析、处理、存储、再显示、打印输出等功能[4]。

1.2 数字示波器的特点及原理

数字示波器中信号显示和数字信号处理功能是独立的,其性能取决于进行数字信号处理的微处理器、模-数转换器和RAM存储器。采用RAM存储器可以以很快的速度读写数据,也可以以很慢的速度读写数据,使得无论是观察高速变化的信号还是很缓慢变化的信号都很自如[5]。

与模拟示波器比较,数字示波器具有很多方面的有点,包括:

1、数字信号处理:数字示波器都使用了微处理器,所以它能对所采集到的数据进行幅度和时间等基本运算,高级的还能完成更复杂的数学运算,如平均值、极值、积分、微分、数字滤波、倒数等。

2、单次多通道信号捕获:数字示波器一般拥有多个通道,能够同时捕获多个单次瞬态信号(比如像电源开、关或故障发生等事件)。

3、多种触发:数字示波器有多种触发类型:边沿触发、峰值触发、脉宽触发、矮脉冲触发、逻辑触发等。

4、数据存储:数字示波器可把波形数据保存在存储器上,可在任意需要的时候调出波形数据进行显示。数字示波器也很容易实现与打印机和绘图仪进行连接,把波形以图片的格式输出。

数字示波器的重点是将连续的模拟信号转化成离散的数字信号,也就是从连续的模拟信号上以一定的时间间隔离散地采用。采样有实时采样和等效采样两种方式。数字示波器可按取样方式分为随机采样数字示波器、实时采样数字示波器、顺序采样数字示波器三种。这三种各自有各自的优点和缺点,等效采样可以做到用比较低速的ADC转换器对高频信号进行观察。

1.3 数字示波器国内外研究状况

国际数字存储示波器的领域,最主要的生产厂商是泰克公司、力科公司和安捷伦公司。泰克公司创始人在1946年发明了世界上第一台触发式示波器,始于这个突破性的技术创新,如今的泰克已经崛起成为全球最大的测试、测量和监测设备供应商之一。现在,泰克公司在全球19个国家都设有办事机构,2006年销售收入超过11亿美元。该公司早在2000年就推出了模拟带宽为4GHz带宽的示波器,以后陆续在2002年和2004年推出了模拟带宽分别为6GHz和8GHz的示波器。目前,泰克的最先进的数字示波器的模拟带宽已经高达80GHz[6]。

力科公司是一家专门从事高端数字示波器研发的公司。2008年1月2日,力科公司新推出的WaveMaster8系列数字示波器,此系列示波器提供了最高可达30GHz的带宽、80GS/s的采样率、512MHz采样点分析功能及大于15GHz的边沿触发功能。力科公司在同一个硬件平台基础上设计了8-Zi系列,支持全部8种型号,提供了4.30GHz的带宽。这就意味着工程师可以利用自己的投资,并紧跟新兴高速技术和串行数据标准,他们只需为当前设计购买所需的带宽,在需要变化时再升级到更高的带宽。这在经济衰退时期特别有吸引力,因为各个公司都在力图最大限度地降低资本投资,尤其力科示波器可以升级到30GHz的带宽。其中WaveMaste830Zi数字示波器的带宽为30GHz实时带宽,为世界上速度最快的实时示波器。在示波器技术研发部分与泰克相当[7]。

在与国外测试测量巨头的博弈中,示波器领域上中国企业已取得非常大的突破。RIGOL公司作为中国仪器界崛起的生力军,继DS5000系列数字示波器创下销售佳绩,获得专业人士好评之后,于2006年初又投下一颗重磅炸弹,推出一款性能卓著的紧凑型数字存储示波器――DS1000系列。DS1000系列在性能上不仅全面超过国外同类产品,打破了在这个领域国外产品一统天下的局面,同时又在原DS5000系列产品上大胆创新,使DS1000系列成为为数不多体积小巧、功能强大、性能卓越的低端数字示波器,弥补了国内空白。RIGOL近几年中之所以能够快速增长,其中的一个重要原因就是利用强大的本土优势,能很好地应对来自客户和整个行业的一系列新标准,结果就是用户能够更快更好地完成他们的工作[8]。

1.4 Android概述

Android(安卓)一词的本义指“机器人”,同时Android也是Google于07年11月5日宣布的基于Linux平台开源手机操作系统名称,该平台由操作系统、中间件、用户界面和应用软件组成,号称是首个为移动终端打造的真正开放和完整的移动软件。

安卓作为一个基于Linux内核的半开源操作系统,目前已广泛的应用于各种移动设备,并正呈现高速发展的趋势。原名“Android”的公司最早开发了安卓系统,谷歌在2005年收购“Android.lnc”后,便投入大量资本和人力继续进行对安卓系统开发运营。安卓采用了软件堆层(software stack,又名软件叠层)的架构,主要分为三部分。基本功能由底层Linux内核提供,其他所有的应用软件由各个公司开发并发布,大部分程序都是用Java进行编写的。在2011年初,安卓系统仅上市两年便超越了称霸十年之久的塞班系统,一举成为全世界最受欢迎的开放移动手机平台。如今不仅仅在智能手机上使用安卓系统,其在平板电脑、机顶盒等电子产品上的应用也是日益广泛。随着Android手机的普及,Android应用的需求势必会越来越大,这将会是一个潜力巨大的市场,会吸引无数软件开发厂商和开发者投身其中[9]。

1.5 题目研究背景及意义

近年来,在数字示波器技术研究领域国内品牌也得到了许多相当不错的成果。但是总体上我国示波器领域的水平还是比较落后的,国内品牌的数字示波器在集成化、智能化、数字化等方面和国外相比还是有相当的差距。在国内,数字示波器领域的技术研究尚处于初级阶段,品牌数字示波器几乎被国外厂家全部占领。但是由于国内消费水平相对较低,昂贵的数字示波器的消费能力非常有限,难于普及,仍然还有大量的模拟示波器在使用,这些都严重的妨碍我国在数字示波器领域的发展。所以,对于目前国内的现状,本课题选择数字示波器的研究是相当有意义的。

传统的模拟示波器存在诸多弊端:第一,模拟示波器升级困难;第二,模拟示波器的造价高;第三,模拟示波器的精度低;第四,模拟示波器操作复杂;第五,模拟示波器处理的是模拟信号,模拟信号处理起来很困难。基于以上的考虑,数字示波器的开发是非常必要的。


2 数字示波器原理分析与技术指标

本章主要分析数字示波器的外部特性,阐述数字示波器的功能和输入输出量;阐述数字示波器的基本框图、基本原理;确定数字示波器中各个部分所使用的关键器件、关键模块。

2.1 数字示波器的组成原理

数字示波器是上世纪70年代初发展起来的新型示波器。该类型的示波器能够实现长期存储模拟信号,并能能够运用相应的编程语言编写相应的算法对存储的数据进行处理,如对被测信号的波形、频率、相位、功率谱和幅度等参数进行精确的测量。数字示波器的出现,是示波器技术发展的一个里程碑,其成功的实现了传统模拟示波器所无法完成的功能,为现代测量技术的发展提供了强大的动力[10]。

数字示波器典型原理框图如图2.1所示。

图2.1              数字示波器典型原理框图

2.2 数字示波器与模拟示波器相比较

1、数字示波器的一大特点是能够无闪烁地观察出很低频率的被测信号,这是模拟示波器无法胜任的。对于很高频率的被测信号,模拟示波器首先要有很高的带宽,同时还要有阴极射线示波管,这些将大大提高模拟示波器的造价,而且模拟示波器的稳定性与显示精度也将大打折扣。而在数字示波器上,由于可以用一个固定的刷新显示速度对存储数据进行显示,而且波形数据可以在液晶屏幕上显示,这样将大幅降低示波器的造价和读出显示所要求的带宽。并且在观察低频信号时,不至于因为过快的显示而丢失波形的细节信息[11]。

2、数字示波器能做到很深的存储深度,即允许存储很长时间内捕捉到的信号。在对单次瞬变信号的分析和处理方面,数字示波器的这一大优点将大有作为。在实际应用中常常会碰到很多瞬变的信号,比如放电现象、单次冲击波等都是在短暂的一瞬间产生的。用模拟示波器观察这些瞬变信号时,波形将在屏幕上一闪而过,根本来不及观察,很多的波形细节都会被忽略[12]。在数字示波器出现之前的年代,当时的工程师设计了“屏幕照相”,来解决模拟示波器在观察瞬变信号时的缺陷。

3、具有多样的触发功能。数字示波器不仅能检测并显示触发后的信号,而且还能检测并显示触发前的信号,并且显示波形的超前或滞后时间可以任意选择。在材料强度、地震研究、生物机能等方面的实验研究上,数字示波器是一个非常有利的工具。通过不同的器件或算法,数字示波器可以实现不同的触发方式,使得在对电信号进行跟踪和分析时变得更加的方便和准确。

4、测量精度高。模拟示波器的水平精度受到水平轴扫描锯齿波线性度的限制,其精度很难提高,一般限制在3%~5%之间。而数字示波器由于采用了高稳定度的晶振,可以达到很高的测量精度。此外,还可以通过采用更高位的A/D转换器来进一步提高垂直精度。同时由于数字示波器克服了示波管对测量精度的影响,使得测量精度可以很容易的达到1%以上。尤其是数字示波器能够自动的设置各种参数,这将使信号的实时检测更加的高效。

5、数字示波器都嵌入了高速微处理器,使它具有很强的信号处理能力与灵活的程序控制性,从而可以方便的实现对多种波形数据的测量、分析与显示。例如可以分析出波形的周期、频率、相位、峰峰值以及方波的占空比等参数。此外,数字示波器还能与计算机进行数据通信,将测量的数据传输给计算机,利用计算机中的软件对数据进行分析处理与显示。

虽然数字示波器有很多优势,但它也存在一定的缺陷。例如,由于受到A/D转换器最大转换速率的限制,数字示波器的性能无法发挥到极致[13]。目前,在观察超高频率信号方面,数字示波器还是难于完全胜任。不过伴随着A/D转换器等技术的发展,数字示波器的功能将越来越完善。

2.3 数字示波器技术指标2.3.1 最大采样速率

定义:单位时间内所完成的对模拟输入信号的采样次数就叫做最大A/D采样速率,单位为Sa/S(次/秒)。最大采样速率主要取决于A/D转换器的最高转换速率,同时也受处理器处理速度的限制。最大采样速率代表数字示波器在时间轴上对信号的捕获能力,其采样率越大,在时间轴上对高速单次信号的捕获能力就越强。

数字示波器实际所使用的采样速率与所设定的示波器水平扫描时间之间具有一定的关系,即示波器需要显示的点数和水平扫描时间因子将一起决定示波器实际所使用的采样速率,其计算公式可表示为

                                                                                               (2.1)

式(2.1)中,N表示显示屏每格显示的点数;t/div表示示波器水平扫描时间因子,也就是示波器扫描显示一格所需的时间[14]。比如选示波器的水平扫描时间为10ms/div,每格包含100个采样点,那么可以计算得知此时示波器的采样率为10KHz。因为示波器水平显示的点数是固定的,那么示波器的水平扫描速度将和采样速率具有一一对应的关系,也就是说示波器最快的扫描速度是由其最大采样速率决定的。如果某示波器的最大采样速率为100MHz,那么其最快的扫描速度为1uS/div。

2.3.2 存储宽度

示波器的存储宽度和采样速率也存在密切的关系。根据奈奎斯特抽样定理,如果采样速率大于或等于信号最高频率的2倍,那么就可以完整的恢复原始信号的波形。但是在数字示波器设计过程中,往往会为了更真实的显示信号波形,而需要在一个信号周期内采集更多的点。一个信号周期内采集到的点数越多,还原出来的波形的失真就越小。

2.3.3 分辨率

分辨率是指能够分辨出的被测信号波形的最小幅值,其指示的是信号波形细节的综合指标,包括水平分辨率和垂直分辨率。

垂直分辨率又称电压分辨率,它取决于A/D数模转换器的分辨率,通常用数模转换器数据的位数来表示,单位是比特[15]。比如,如果某数字示波器所使用的A/D数模转换器的精度是8位的,那么称该数字示波器的垂直分辨率是8bit。垂直分辨率也可用显示屏每格的A/D转换级数表示,单位是级/div。假设某数字示波器使用的是8bit的A/D转换器,显示屏垂直方向上有8个格,那么称该数字示波器的垂直分辨率为32级/div。

水平分辨率又称时间间隔分辨率,通常以数字示波器在进行波形采样时所能分辨的最小时间间隔值来表示。如果没有加入内插,当数字示波器的采样速率为

时,则定义数字示波器的水平分辨率为 ;如果加入内插算法,并且内插器的增益为N,则定义数字示波器的水平分辨率为 。如果某数字示波器的记录长度为1KB,显示屏横向坐标为十格,则该示波器水平分辨率约为100点/div。

分辨率与测量准确度紧密相关,但分辨率并非就是测量准确度,而是理想情况下测量准确度的上线。

2.3.4 记录长度

记录长度又称存储深度,用记录一帧波形数据所利用的存储容量来表示,单位为KB或MB等。记录长度表示的是数字示波器能够连续存入采样点的最大字节数。记录长度和水平分辨率之间存在正比的关系,即记录长度越长,水平分辨率就越高;反之,记录长度越短,水平分辨率就越低。一般来说,记录长度越长,就允许用户捕捉更长时间内的事件,就能更好的描述更为复杂的波形。但是由于高速存储器制造技术的限制,目前数字示波器的记录长度是有限的,通常采用的是1KB,4KB,8KB或者是更大的记录长度。需要指出的是,对于一个数字示波器,其记录长度是一个定值,但实际使用中存储容量是可以变化的。

2.3.5 存储带宽

存储带宽定义为示波器输入不同频率的等幅正弦波信号时,显示屏上显示的信号幅度下降3dB时所对应的输入信号的上、下限频率之差,也称为示波器的频带宽度,单位为MHz或GHz[16]。

数字示波器有模拟带宽和存储带宽两种表达方式。模拟带宽指的是采样点路以前模拟信号通道电路的频带宽度,主要由信号调理电路的幅频特性决定。如果没有特殊说明,数字示波器的频带宽度一般指的是其模拟带宽。存储宽度按其采样方式的不同又分为实时带宽与等效带宽两种。实时带宽指的是采用实时采样方式时所具有的存储宽度,主要取决于A/D转换器的采样速率和波形处理所采用的内插技术。根据取样定理,如果采样速率大于或等于信号最高频率分量的两倍,便可重现原始信号波形。在数字示波器设计中,通常要求比信号频率高更多倍数的采样速率,以保证显示分辨率。采用点显示方式时,每周期采样点数k一般取20~25,也即要求采样频率是信号频率的20~25倍。采用插值技术可以降低示波器对采样速率的要求,采用矢量内插方式时,一般取k=10;当采用正弦内插方式时,一般取k=2.5。等效带宽指的是示波器工作在等效采样方式下,测量周期信号时所表现出来的频带宽度。在等效采样方式下,要求信号必须是周期重复的,否则无法准确的重现波形。使用等效采样时,数字示波器一般要经过多个采样周期,并对采集的样点进行重新组合,才能重显被测波形。等效带宽可以做的很宽,有的数字示波器的等效带宽可达到几十GHz以上。

2.3.6 垂直灵敏度及误差

垂直灵敏度是指数字示波器显示在垂直方向(Y轴)每格所代表的电压幅度值,常以V/div、mV/div表示。根据模拟示波器的习惯,数字示波器也按1-2-5步进方式分挡,每挡也可以细调。垂直灵敏度表明了示波器测量最大和最小信号幅度的能力。垂直灵敏度误差是指数字示波器测量信号幅度的准确度,一般用规定频率的标准幅度脉冲信号作校验信号,其计算公式如下

                                                            (2.2)

式(2.2)中,e为垂直灵敏度误差,V1为测量读数值(V),V2为校准信号每格电压值(V),D为校准信号格数(div)。

2.3.7 扫描速度及误差

扫描速度(又称扫描时间因数,简称为扫速)定义为示波器光点在屏幕水平方向上移动一格所占用的时间,以s/div、ms/div、μs/div、ns/div、ps/div等表示。扫描速度表明了示波器能测量信号频率的范围。沿用模拟示波器的习惯,也按1-2-5步进方式分挡,每挡也能细调。扫描速度取决于A/D转换器的转换速率及记录长度(存储容量),其值为相邻两个取样点的时间间隔与每格取样点数N的乘积,即

                                                                             (2.3)

扫描速度误差是指示波器测量时间间隔的准确度。一般用具有标准周期时间的脉冲信号作为校验信号,其计算公式如下式

                                                  (2.4)

式(2.4)中,e为扫描误差;Δt为校准信号周期时间测量读数值;T0为校准信号周期时间值。

2.4 采样原理分析2.4.1 实时采样方式的原理

实时取样指的是利用等时间间隔取样脉冲对被测信号进行取样,按照取样时钟的先后顺序将A/D采样的数据存在存储器中的过程。取样就是对连续的信号波形进行量化的过程,如图2.2所示。其方法可用图2.3说明。

图2.2   取样示意图

图片请下载附件中有完整版

图2.3   取样方框图

把模拟信号的波形送到采样保持电路,并通过采样脉冲来控制采样电路对模拟信号进行采样,取样方框图如图2.3所示。令n代表第n个时刻的抽样,在取样脉冲到来的瞬间,在A/D转换器的输入端就得到相应的模拟量An(n=1,2,3,…),这个模拟量An就是所需要的用于进行离散化的模拟量。若把An中的每一个离散模拟量进行A/D转换,就可以得到相应的数字量,这也就是量化的过程。我们把A/D采样得到的数据按照采样顺序进行存储,也就实现了将模拟信号转化为一序列的数字信号进行存储。A/D转换器是将模拟信号进行数字化的核心器件,它与数字示波器的存储带宽、最大取样速率以及垂直分辨率等多项指标有关,所以A/D转换器的选取是数字示波器设计过程中非常重要的一个环节。

2.4.2 等效取样方式的原理

实时取样方式对观测单次瞬变信号特别有效,是数字示波器采样方式中不可或缺的一种。但受到最大采样速率的约束,实时采样方式很难实现大的带宽。因此,想要提高带宽,就必须寻找一种更有效的取样方式,而等效取样正是一种有效的能提高带宽的方式。等效取样方式也称非事实取样,可分为顺序取样和随机取样两种方式。等效取样方式的原理是先利用“等效取样技术”,将高频周期性信号转换为波形性质与其相似的低频周期性信号,然后对采集到的低频信号进行处理与转化,就可以轻松的获得很宽的频带,从而实现对高频周期性信号的检测[17]。但是等效取样方式有两个制约条件:1、必须是周期性的信号;2、信号波形能够形成稳定的触发。常用的等效取样方式的采集系统框图如图2.4所示。

图2.4              等效取样方式采集系统框图


3 系统方案论证
3.1 系统总体方案设计

数字示波器很大的一个特点,就是能对采集到的波形数据进行处理,通过特定的算法即可测量出信号的频率、幅值和相位等电气参数。并且示波器能将运算处理后的数据直接显示在LCD液晶屏上,通过调整合适的扫描速度就能方便的观察到信号的细节。由于示波器需要处理的数据量比较大,且对于高频信号需要很高的采样率和刷新速度,因此一般的微处理器难于满足[19]。目前高性能的数字示波器都采用FPGA来控制数据的采集和处理数据。由于FPGA的灵活性极高,采用FPGA的系统能高效的处理数据及显示波形。但是由于FPGA的成本较高,并不适用于低端便携式产品上。

本文的设计理念是便携式、低成本,因此需要寻找一款性能高、价格低的微处理器。考虑到成本和实际应用,本文选择了意法半导体公司的STM32微处理器作为主控制器。STM32系列是基于专为要求高性能、低成本、低功耗的嵌入式应用专门设计的ARM Cortex-M3内核,能完全满足本设计对成本和性能的要求。

本文的另外一个亮点就是使用了Android作为波形显示平台。在这个基本上是人手一部Android手机的时代,怎样充分挖掘Android软硬件的使用价值就显得尤为重要。本设计用到Android的屏幕来显示波形,而且还使用了触摸屏来对示波器进行控制,这样将大大缩小硬件的体积和降低系统成本。同时示波器硬件电路和Android之间通过蓝牙实现无线数据传输,这使得系统的应用将是非常的方便。

数字示波器的结构框图如图3.1所示。

本论文设计的数字示波器的工作方式是,被测信号经STM32控制的采样电路进行采样并对数据进行处理,然后通过蓝牙把处理过后的波形数据发送到Android端,最后通过Android端的应用程序把波形显示出来。在Android端的应用程序上可以操作示波器的所有功能,比如调节垂直灵敏度、水平扫描速度、触发电平、垂直基线等。同时本设计非常小巧,且使用锂电池进行供电,非常方便携带。本设计的理念是,只要你拥有一台Android手机或者平板电脑,你就可以拥有一个低成本的、便于携带的数字示波器。

图片请下载附件有完整版

图3.1  结构框图

模拟信号处理是示波器的重要组成部分,也是信号采集系统中的一个核心部分。图3.1清晰的介绍了数字示波器的结构框图,从图中可以看出,模拟通道的输入信号被分成两路,一路送至程控放大器,用来实现垂直灵敏度的调节;另一路送至触发电路,用于测量被测信号的频率。其中程控放大器是示波器模拟部分设计的关键,也是示波器带宽最重要的限制因素。

3.2 数据采集系统3.2.1 波形整形电路方案选择

波形整形电路的选择主要是选择合适的比较器芯片,为了防止波形在过零点出现抖动,比较电路最好是接成滞回比较结构,以免影响比较器的输出波形。

方案一:采用Maxim公司的高速比较芯片Max912构成滞回比较器。Max912的最高转换速度可达ns级别,对频率很高的信号都能进行有效的整形。但缺点是Max912的成本太高。

方案二:采用比较器LM311构成滞回比较器。在对5M以下的信号进行整形时,能收到比较好的效果。最主要的还是其价格相对比较低,能满足本设计对成本的控制。但当信号频率高于5M时,由于收到LM311转换速度的限制,其整形效果比较差。

基于本设计对测试范围的要求以及成本的控制,本设计选择方案二。

3.2.2 程控放大电路方案选择

由于A/D转换器的输入范围一般都比较小(低于2Vpp),不可能直接测量几十伏甚至是几百伏的信号。而且由于A/D转换器的分辨率有限,对于幅值很低的信号测量误差将会很大甚至是无法测量。所以在输入级必须要设计一个程控放大电路,以现实对信号进行不失真的处理,而后再送至A/D数模转换器,以达到A/D数模转换器的输入要求。通常情况下所说的“示波器的模拟带宽”就是输入级的模拟信号放大电路的带宽。而数字示波器的带宽主要是用采样率来定义,主要受数模转换器的最高采样率以及控制器的处理速度的限制。

方案一:利用高速运放LM6172构成放大电路,并设置多种不同放大倍数的反馈电阻网络,然后通过控制继电器选择不同的反馈电阻,从而实现不同放大倍数的切换。其优点是电路和控制都比较简单,放大倍数稳定。但缺点是继电器的工作电流大,且需要多个继电器配合才能实现多种不同的放大倍数,很明显不符合本设计便携小巧的宗旨。同时继电器在开和关的瞬间都会产生很大的电磁干扰,有可能会影响到系统的正常运行。

方案二:使用模拟开关HCF4051BE代替继电器,来实现不同放大倍数的切换。优点是克服了继电器工作电流大、体积大等缺点,且电路结构简单,成本低廉。但缺点是模拟开关无法实现零阻抗,且其带宽有限,通过高频信号将会产生失真。

方案三:使用专用PGA芯片AD603,可以通过MCU来控制AD603的基准,进而实现不同放大倍数的调节。该电路优点是控制比较简单,且增益调节范围大,外围电路简单。缺点是成本稍微偏高。

基于本设计便携小巧的宗旨,和电路复杂度的考虑,本设计选择方案三。

3.3 数据处理系统3.3.1 触发方案选择

为了波形能在示波器显示屏上稳定显示,必须要到用触发系统,以保证被测信号与扫描信号始终保持同步。也即是每次扫描的起始点,都是信号波形一个周期内固定的一个点。

方案一:采用高速比较器构成触发电路。这种方法对于比较器的转换速率要求很高,在带宽很高的示波器上,一般的比较器难于满足要求。并且采用高速比较器,将会增加系统的制作成本。此外,硬件触发电路如果设计的不好,比较器的输出容易产生抖动毛刺,容易使系统误将抖动毛刺当作触发信号,从而使整个硬件系统变的不可靠。

方案二:采用软件触发方式。软件触发的原理很简单,就是在MCU内通过一定的算法,将A/D转换器采集到的数据和软件设置的触发电平进行比较,从而实现可靠的波形触发。其优点是可以根据实际情况方便的选择不同的触发方式和触发电平,具有极高的灵活性。此外该方案在一定程度上消除了硬件触发电路产生的干扰毛刺,提高系统的稳定性。

基于以上对系统稳定性和成本控制的考虑,本设计选择方案二。

3.3.2 峰值测量方案选择

对示波器来说,测量并显示信号峰值是其必不可少的一部分。信号峰值测量包括正峰值和负峰值,而信号峰峰值就是正负峰值的绝对值。

方案一:峰值检波法。峰值检波法是利用硬件电路对电容进行充放电,从而在电容两端保持信号峰值。然后通过A/D转换器采集电容两端的电压值,并把峰值显示出来。峰值检波法能有效的测量出信号的峰值,且由于是采用硬件电路来实现峰值的检测,不会对MCU增加任何的负担。但该方案的缺点是需要采用高速运算放大器,不但增加了系统的设计成本,同时也增加了硬件系统的复杂度。

方案二:数字方法。所谓数字方法,就是通过分析A/D转换器所采集到的波形数据,采用最大值和最小值算法,计算出信号的正峰值和负峰值。该方案的缺点是增加了软件算法的复杂度,从而降低了波形数据采集、处理和显示的速度。另外,由于受到A/D转换器最高采样率的限制,该方法不适用于高频信号的测量。

考虑到本设计测量的频率范围不是很大,且在软件系统中增加峰值测量算法,对信号数据处理及显示速度的影响不大。同时为了不增加系统的设计成本,本设计的峰值测量方案采用方案二。

3.3.3 测量频率方案选择

因为被测信号频率的大小决定了示波器的采样方式,且直接决定采样时钟的选择,因而测量频率在示波器中显得尤为重要。测量频率的方案通常有测周法和测频法两种。

方案一:测周法。这是一种比较简单易用的方案,其原理是被测信号通过触发电路,连接到单片机定时器的计数IO口上,实现对被测信号周期数的测量。然后取一个固定的计数门限,通过计算在该固定时间内计数器的计数值,就可以计算出被测信号的频率。也可以是通过计算一定周期数的脉冲,然后再算出计数所使用的时间,就能知道被测信号的频率了。 在被测信号频率较高的场合,该方案可以做到很高的精度。在被测信号频率较低时,如果想保持高精度的话,则需要加长计数门限时间,但这会使得示波器的响应变慢。换言之,该方案的缺点是测量精度受被测信号频率的影响。

方案二:等精度测频法。其原理是在一个固定的门限时间内,使用一个固定频率的基准脉冲,使得被测信号与基准脉冲同时计数,再通过两个计数值之间的关系便可以计算出被测信号频率。门限时间的开启由被测脉冲的边沿来触发。该方案的优点是测量精度与被测信号频率无关,且只要基准脉冲频率足够大,系统就能够实现很高的测量精度。

考虑到本设计的测量频率范围比较大,且要求在整个频段内都能保持一定的测量精度,因此采用方案二。

3.3.4 采样方案选择

在现代数字示波器一般都会同时采用实时采样和等效采样这两种采样方式。

方案一:实时采样。实时采样是在信号的一个完整周期内对其采样,故显示的都是信号的实时波形。按照奈奎斯特抽样定理,采样速率必须高于信号最高频率分量的2倍,否则无法恢复原始信号。对于周期正弦信号,一个周期内的采样点要多于2个。考虑实际因素的影响,为了不失真地恢复被测信号的波形,通常按照恢复失真度选取相应的采样点数。这里用采样点直接恢复方式,因此一个信号周期内至少需要20个采样点数。该方案的缺点是在信号频率很高时,由于受到采样器件的限制,很难实现实时采样。

方案二:等效采样。等效采样又称为非实时采样,可分为顺序采样和随机采样两种方式。顺序采样是对每一个信号周期仅采样一点,经过若干个周期的采样之后,就能完整的恢复原始信号的波形。随机采样是在每个采样周期内采集多个采样点,并且每个采样周期第一个采样点的时刻是随机的,经过多个采样周期的叠加即可还原原始波形。但等效采样法的前提是,被测信号必须是周期信号且能有效的触发,也就是说等效采样方式对单次信号的测量是无能为力的。

等效采样虽然可以对很高频率的信号进行采样,但是步进延迟的采样技术较难实现,而且总采样时间过长,从而导致示波器反应速度慢。而实时采样方式的优点是采样所需的时间很短,示波器响应快。同时考虑到本设计所要求的采样率不是特别高,因此本设计选用实时采样的方式。


4 系统硬件电路设计
4.1 微控制器电路

主控制器采用STM32F103系列单片机作为控制核心。STM32系列基于专为要求高性能、低成本、低功耗的嵌入式应用专门设计的ARM Cortex-M3内核。其具有最高72MHz的工作频率,能够满足系统对速度的要求。微控制器电路如图4.1所示。

图4.1              微控制器电路

4.2 电源电路设计

本设计的定位是便携式,因此采用锂电池供电。锂电池选用目前市场上性价比最高的18650电池,容量为2000mAh,并可充电。因为锂电池的电压为3.7V,因此需要设计一个升压电路把电压升压到5V,才能给系统供电。升压电路如图4.2所示。

           

图4.2              升压电路

此外,还需要设计一个负电压转换电路,以产生-5V来给运放供电。负电压转换电路采用芯片ICL7660来完成,该芯片具有成本低、电路结构简单等优点。负电压转换电路如图4.3所示。

         

图4.3              负电压转换电路

4.3 信号采集电路设计

信号采集部分是数字示波器和模拟示波器在本质上的区别,其组成包括模拟信号的调理和数字信号的处理。数字示波器的性能也主要是受到信号采集系统的限制。因此对数字示波器来说,一个好的信号采集系统是至关重要的。

4.3.1 A/D转换及FIFO缓存器

A/D转换器是模拟信号转换为数字信号的核心部分,其作用是将模拟信号转换为便于存储和处理的数字信号。在本设计中选用的AD转换芯片为TI公司的8位高速AD转换器ADS830E,它的采样频率为10kSa/s~60MSa/s,通过实验发现转换速率在lK以下也能正常工作,本设计的最低采样频率为600Sa/s。由于高速AD转换器一般都有高低端转换速率的限制,选择AD转换芯片时,不仅要注意最高转换速率还要关注最低转换速率,否则可能导致电路无法正常工作。

A/D采样出来的数据,是随采样时钟和被测信号的变化而变化的,所以要能够再现被测信号,必须要把每次采集的数据存人缓存器。F1F0就是一个典型的缓存器,它是一个先进先出的存储器,可同时对存储空间进行读写,没有地址线,第一个读出来的数据是第一个写进去的数据。在本设计中选择了专门的FIFO芯片IDT7203,如图4.4所示。

图4.4  A/D转换及FIFO缓存电路

4.3.2 程控放大电路

程控放大电路主要是对被测信号在幅度上进行线性处理,使信号在垂直方向上处于A/D转换器的输入范围内。待测模拟信号输入到数字示波器时首先要经过相关的处理才能够送给ADC,因为ADC对输入电压的幅度有一定的要求,比如2V~3V,或者1.5V~3.5V等。对于输入的模拟信号,要根据不同的垂直灵敏度做出调整,具体说就是把小电压信号放大,将大电压信号衰减使之符合ADC的输入电压范围。因此,需要对电压大小不同的信号进行增益调整,也就是需要一个程控放大电路。本设计采用的程控放大电路如图4.5所示。

图4.5              程控放大电路

本设计采用可变增益放大器AD603来构成程控放大电路。AD603是AD公司推出的一种低噪声且由电压控制的增益放大器。它提供精确的、可由管脚选择的增益,它的增益是线性变化的,且在温度和电源电压变化时有很高的稳定性,增益变化的范围40dB,增益控制转换比例25mV/dB, 响应速度为40dB,变化范围所需时间小于1us。AD603内部包含一个七级R-2R梯形网络组成的0dB到-42.14dB的可变衰减器和一个固定增益的放大器,此固定增益放大器的增益可通过外接不同反馈网络的方式改变,以选择AD603不同的增益变化范围。

4.3.3 电平移位电路设计

因为ADS830E的模拟输入电压范围是1.5V~3.5V,输入中点电压为2.5V,所以基线电压应为2.5V。因此需要设计一个电平移位电路,把前级经过调理后的信号叠加2.5V,以满足AD转换器的电压输入范围。电平移位电路如图4.6所示。

图4.6              电平移位电路

电路图中,IN为前级调理后的输入信号,ADC端接到AD转换器的输入端,Level为单片机的PWM输出端。单片机输出的PWM经过RC低通滤波器之后,将会变成一个和占空比相对应的电压值,从而实现了通过改变PWM的占空比来改变信号波形的基线。

4.3.4 频率测量电路

频率的测量采用单片机外部中断/INT,对频率测量电路产生的脉冲进行计数,再通过对测量数据的校正来完成。为抑制干扰引起的误翻转,本设计应用滞回比较电路,将信号由反向端输入。电路的正向阈值电压满足公式4.1,对应于输出信号的下降沿;其负向阈值电平为0V,对应于输出信号的上升沿。滞回比较器如图4.7所示。

                                                (4.1)

在数字测量和控制系统中,由传感器送来的波形边沿较差,此外,脉冲信号经过远距离的传输后,往往会发生各种各样的畸变,利用滞回比较电路可以对这些信号进行整形。整形效果如图4.8所示。

图4.7  波形整形电路

图4.8  整形效果图

4.4 无线数据传输

本设计的一大特点是,把采集到的波形数据发送到Android设备平台进行显示,并使用蓝牙技术进行无线数据传输。本设计选用博陆科公司的BLK-MD-BC04-B型蓝牙模块,其采用英国CSR公司Blue Core4-Ext芯片,遵循V2.1+EDR蓝牙规范。其支持UART、USB、SPI、PCM、SPDIF等接口,并支持SPP蓝牙串口协议,具有成本低、体积小、功耗低、收发灵敏性高等优点,只需配备少许的外围元件就能实现其强大功能。

该模块主要用于短距离的数据无线传输领域。可以方便的和 PC机的蓝牙设备相连,也可以两个模块之间的数据互通。避免繁琐的线缆连接,能直接替代串口线。该模块广泛应用于工业遥控、遥测;POS系统,无线键盘、鼠标;楼宇系统化、安防、机房设备无线监控、门禁系统;汽车检测设备等领域。

蓝牙模块功能框图如图4.9所示,应用电路如图4.10所示。

图4.9              蓝牙模块功能框图

图4.10              蓝牙模块应用电路


5 系统软件设计
5.1 单片机软件开发环境

本设计采用STM32F103系列单片机作为控制核心,软件开发环境选用keil uVision。

keil uVision是美国Keil Software公司出品的51系列兼容单片机C语言软件开发统,与汇编相比,C语言在功能上、结构性、可读性、可维护性上有明显的优势,因而易学易用。keil uVision软件提供丰富的库函数和功能强大的集成开发调试工具,全Windows界面。另外重要的一点,只要看一下编译后生成的汇编代码,就能体会到Keil C51生成的目标代码效率非常之高,多数语句生成的汇编代码很紧凑,容易理解。在开发大型软件时更能体现高级语言的优势。

C51工具包的整体结构,其中uVision是C51 for Windows的集成开发环境(IDE),可以完成编辑、编译、连接、调试、仿真等整个开发流程。开发人员可用IDE本身或其它编辑器编辑C或汇编源文件。然后分别由C51及A5l编译器编译生成目标文件(.OBJ)。目标文件可由LIB51创建生成库文件,也可以与库文件一起经L51连接定位生成绝对目标文件(.ABS)。ABS由OH51转换成标准的Hex文件,以供调试器dScope51或tScope51使用进行源代码级调试,也可由仿真器使用直接对目标板进行调试,也可以直接写入程序存储器如EPROM中。

5.2 主程序设计及流程图

本设计是一个以硬件为基础的、软硬件紧密结合的系统。对于智能仪器仪表来说,软件就是灵魂。示波器软件采用C语言来编写,完成对人机界面、系统控制、系统硬件、波形参数分析等的控制。主程序流程图如图5.1所示。

5.3 数据处理子程序

5.3.1 同步触发的软件实现

为了降低电路的复杂性,本设计采用软件来实现同步触发。软件触发的好处是触发

条件更易调整,只需调整比较语句中的参数即可。保证可以用软件触发的条件是要有足够大的存储空间,显示一屏的数据为240个,但每次读进单片机的数据为500个,多余260个数据就是作为不满足触发条件的舍弃余量,为了以防万一,当从500个数据中以经读出超过260个数据但还没有符合触发条件的数据时,将跳出触发比较循环,重新从FIFO存储器中读出500个数据,因为FIFO存储器为4K容量,最多可以这样重复读取8次数据,所以软触发可以非常稳定的工作。

同步触发子程序:

read:

for(i=0;i<500;i++)   // 从FIFO存储器中读500 个数据

{

FIFO_R=0;

add[ i]=FIFO_bus;

FIFO_R=1;

}

while(!(add[q]<=m&&add[q+1]>=m))  //满足幅度为m 且为上升沿则触发

{

              q+=1;

if(q>=260)  //若存储数据不足则重新读数据

goto read;

}

程序的意思是只有当此时采样信号的数值是m且为上升沿时才可以触发,改变触发沿只需改变运算符,改变触发电压只需改变m的值即可,m的取值范围是0~255。

5.3.2 频率计算原理及流程图

本设计的频率计算采用外部中断和两个定时器来完成,其中一个定时器用来对脉冲个数进行计算,另一个定时器用于定时。其原理是,当整形后的脉冲的下降沿带来时,触发外部中断。在外部中断响应程序里,开启TIM1并设置其时钟来源为外部输入;开启TIM2,设置为定时模式。等待TIM1计数溢出中断,然后停止计时并读出定时器的值。假设计数的脉冲个数为N,所用的时间为T,那么频率可有式(5.1)计算得出。

                                              (5.1)

频率计算流程图如图5.2所示。



图5.2  频率计算流程图
5.3.3 测量信号峰峰值

本示波器就能够测量输入信号电压的峰峰值,并显示在屏幕上。这个功能由峰峰值测量子程序完成,见下面的程序段。

在程序开始时给a中赋值128,即基线电压值。因为一屏幕的显示数据为240个,所以用for循环将if…else…判断语句执行240次,在a中存放最大值,在b中存放最小值。对每个数据进行比较,如果该数据比a大则将这个数据存入a;如果小于a,则将这个数据与b进行比较,比b大则抛弃,比b小则存入b。故当240个循环执行完后a中存放的是这一屏幕数据中的最大值,b中存放的是这一屏幕显示数据中的最小值。在比较完后用a减去b,得到差值存入c中,则c中保存的值就是电压的峰峰值,调用电压计算显示子程序根据当前的垂直灵敏度给c乘以不同的倍数,得到实际的峰峰值。

峰峰值测量子程序:

a=128;

for(i=0;i<240;i+ +)      //取数据中的最大值与最小值

  {

     if(add[ i]>a)

       {

          a=add[ i];

        }

        else if(add[ i]<b)[ size][="" font][="" color][="" p][p="24," null,="" left]显示平台6.1 Android应用开发环境6.1.1 Android简介

  Android是Google于2007年11月5日宣布的基于Linux平台的开源手机操作系统的名称,该平台由操作系统、中间件、用户界面和应用软件组成,号称是首个为移动终端打造的真正开放和完整的移动软件。可以把它简单理解成Linux上套了一个JAVA的壳。

6.1.2 开发所需的软件包

  1、java JDK 6.0最好下载新版。它可从Sun公司的官网下载。

  2、Android SDK 这是Android开发必需的。

  3、Eclipse 3.5最好使用这个版。它可从Eclipse官网下载。

  4、Eclipse所需的插件ADT-0.9.7它可从google网站上下载。

6.1.3 搭建Android开发环境

准备好开以上软件包之后,我们便可以搭建Android的开发环境了。

第一步:安装java JDK 6.0。

第二步:把下载好的Eclipse 3.5解压。

第三步:Android SDK 安装。

Android SDK可以通过SDK下载器自动下载和配置,适合网络好,下载速度快的情况下;也可以借助工具下载SDK文件,手工配置,适合网络不是很好,下载速度慢的情况下。

第四步、Eclipse集成开发环境(IDE)搭建

1、打开Eclipse,选择菜单:Help->Install New Software...

2、弹出“Available Software”对话框,点击“Add...”按钮

3、弹出“Add Repository”对话框。中Name中输入ADT,然后点击Archive把路径设置到下载的ADT-0.9.7文件的位置,然后安装。

4、安装成功后,安装提示重启Eclipse,即完成整个安装过程。

第五步:Android SDK 配置,即配制Android 虚拟设备,亦即嵌入式开发中常用的模拟器。

6.1.4 测试所配的开发环境
  • 新建项目:打开Eclipse,选择File > New > Project > Android Project,便会打开新建项目界面,如图6.1所示。

在Project name中输入工程的名字,build target中选择所用的平台,Application name为应用程序的名称,create activity为活动类的名称。

图6.1              新建项目

2、配制运行方式:点击Run Configurations会出现配制运行方式界面,如图6.2所示。然后点击Android application新建一个动行方式,在右边project中输入要运行的工程名称。至此运行方式配制完成。

图6.2  配制运行方式

3、运击会行,便会出下如下界面,如图6.3:

图6.3              运行界面

至此,Android的开发环境已搭建成功。

6.2 Android蓝牙通信设计

蓝牙是一种支持设备短距离通信(一般10m内)的无线电技术。能在包括移动电话、PDA、无线耳机、笔记本电脑、相关外设等众多设备之间进行无线信息交换。利用“蓝牙”技术,能够有效地简化移动通信终端设备之间的通信,从而数据传输变得更加迅速高效,为无线通信拓宽道路。

本设计分为信号采集模块和Android显示终端,两部分采用蓝牙技术进行无线通信。Android显示终端实现波形的显示和示波器参数的设置。

6.2.1 Android设备中蓝牙模块的使用
  • 使用蓝牙的响应权限

[html]view plaincopyprint



  • 配置本机蓝牙模块

BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();

//直接打开系统的蓝牙设置面板

Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);

startActivityForResult(intent, 0x1);

//直接打开蓝牙

adapter.enable();

//打开本机的蓝牙发现功能(默认打开120秒,可以将时间最多延长至300秒)

Intent discoveryIntent = new                                                        

Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);

discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);//设置持续时间(最多300秒)

  • 搜索蓝牙设备

使用BluetoothAdapter的startDiscovery()方法来搜索蓝牙设备。

startDiscovery()方法是一个异步方法,调用后会立即返回。该方法会进行对其他蓝牙设备的搜索,该过程会持续12秒。该方法调用后,搜索过程实际上是在一个System Service中进行的,所以可以调用cancelDiscovery()方法来停止搜索(该方法可以在未执行discovery请求时调用)。请求Discovery后,系统开始搜索蓝牙设备,在这个过程中,系统会发送以下三个广播:

ACTION_DISCOVERY_START:开始搜索

ACTION_DISCOVERY_FINISHED:搜索结束

ACTION_FOUND:找到设备

这个Intent中包含两个extra fields:EXTRA_DEVICE和EXTRA_CLASS,分别包含BluetooDevice和BluetoothClass。我们可以自己注册相应的BroadcastReceiver来接收响应的广播,以便实现某些功能。

功能代码如下:

// 创建一个接收ACTION_FOUND广播的BroadcastReceiver

private final BroadcastReceivermReceiver = new BroadcastReceiver() {

public void onReceive(Context context, Intent intent) {

String action = intent.getAction();

// 发现设备

if (BluetoothDevice.ACTION_FOUND.equals(action)) {

// 从Intent中获取设备对象

BluetoothDevice device =               intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

// 将设备名称和地址放入array adapter,以便在ListView中显示

mArrayAdapter.add(device.getName() + "" + device.getAddress());

}

}

};

// 注册BroadcastReceiver

IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);

registerReceiver(mReceiver, filter); // 不要忘了之后解除绑定

6.2.2 蓝牙数据通信

如果打算建议两个蓝牙设备之间的连接,则必须实现服务器端与客户端的机制。当两个设备在同一个RFCOMM channel下分别拥有一个连接的BluetoothSocket,这两个设备才可以说是建立了连接。服务器设备与客户端设备获取BluetoothSocket的途径是不同的。服务器设备是通过accepted一个incoming connection来获取的,而客户端设备则是通过打开一个到服务器的RFCOMM channel来获取的。

  • 服务器端的实现

通过调用BluetoothAdapter的listenUsingRfcommWithServiceRecord(String, UUID)方法来获取BluetoothServerSocket,并调用BluetoothServerSocket的accept()方法监听连接请求,如果收到请求,则返回一个BluetoothSocket实例(此方法为block方法,应置于新线程中)。如果不想在accept其他的连接,则调用BluetoothServerSocket的close()方法释放资源。

  • 客户端的实现

通过搜索可以得到服务器端的BluetoothService,并通过调用BluetoothService的listen

UsingRfcommWithServiceRecord(String, UUID)方法获取BluetoothSocket(该UUID应该同于服务器端的UUID)。调用BluetoothSocket的connect()方法,如果UUID同服务器端的UUID匹配,并且连接被服务器端accept,则connect()方法返回。

3、数据通信

可以分别通过BluetoothSocket的getInputStream()和getOutputStream()两种方法获取InputStream和OutputStream,并使用read(bytes[])和write(bytes[])方法分别进行读写操作。其中,read(bytes[])方法会一直block,直到从数据流中读取到信息;而write(bytes[])方法并不是经常的block,比如在另一设备没有及时read或者中间缓冲区已满的情况下,write方法会block。

6.3 Android上绘制波形

利用SurfaceView类来实现波形的绘制。SurfaceView是视图(View)的继承类,这个视图里内嵌了一个专门用于绘制的Surface控件。可以通过SurfaceHolder接口访问这个surface,getHolder()方法可以得到这个接口。surfaceview的核心在于提供了两个线程:UI线程和渲染线程。SurfaceView的性质决定了其比较适合一些场景:需要界面迅速更新、对帧率要求较高的情况。

6.3.1 SurfaceView的使用

只要继承SurfaceView类并实现SurfaceHolder.Callback接口就可以实现一个自定义的SurfaceView。SurfaceHolder.Callback在底层的Surface状态发生变化的时候通知View,SurfaceHolder.Callback具有如下的接口:

1、surfaceCreated(SurfaceHolder holder):当Surface第一次创建后会立即调用该函数。程序可以在该函数中做些和绘制界面相关的初始化工作,一般情况下都是在另外的线程来绘制界面,所以不要在这个函数中绘制Surface。

2、surfaceChanged(SurfaceHolder holder,int format,int width,int height):当Surface的状态(大小和格式)发生变化的时候会调用该函数,在surfaceCreated调用后该函数至少会被调用一次。

3、surfaceDestroyed(SurfaceHolder holder):当Surface被摧毁前会调用该函数,该函数被调用后不能继续使用Surface,一般在该函数中清理使用的资源。通过SurfaceView的getHolder()函数可以获取SurfaceHolder对象,Surface就在SurfaceHolder对象内。虽然Surface保存了当前窗口的像素数据,但是在使用过程中是不直接和Surface打交道的,由SurfaceHolder的CanvaslockCanvas( )或Canvas的lockCanvas(Rect dirty)函数来获取Canvas对象,通过在Canvas上绘制内容来修改Surface中的数据。当在Canvas中绘制完成后,调用函数unlockCanvasAndPost(Canvas canvas)来通知系统Surface已经绘制完成,这样系统会把绘制完的内容显示出来。为了充分利用不同平台的资源,发挥平台的最优效果,可以通过SurfaceHolder的setType函数来设置绘制的类型,可接收如下的参数:

SURFACE_TYPE_NORMAL:用RAM缓存原生数据的普通Surface。

SURFACE_TYPE_HARDWARE:适用于DMA(Direct memory access )引擎和硬件加速的Surface。

SURFACE_TYPE_GPU:适用于GPU加速的Surface。

SURFACE_TYPE_PUSH_BUFFERS:表明该Surface不包含原生数据,Surface用到的数据由其他对象提供,在Camera图像预览中就使用该类型的Surface,有Camera负责提供给预览Surface数据,这样图像预览会比较流畅。如果设置这种类型则就不能调用lockCanvas来获取Canvas对象了。

6.3.2 绘制波形子程序

该子程序的功能是,先绘制8*8的显示网格,然后把接收到的波形数据在SurfaceView中显示出来。功能程序如下:

   void DrawWave(int length) {

   Canvas canvas = sfh.lockCanvas(new Rect(0, 0, 480,480));//获取画布

   Canvas.drawColor(Color.BLACK);              //清除画布

   Paint mPaint = new Paint();                            //获取画笔

   mPaint.setColor(Color.GRAY);              //设置画笔为黄色

   mPaint.setStrokeWidth(1);                            //设置画笔粗细

   oldY=0;

   //绘制8*8的网格

   for (int i = 0; i <= 8; i++) {// 绘画横线

                 canvas.drawLine(0, oldY, 479, oldY, mPaint);

                 oldY = oldY+60;}

   oldX=0;

   for (int i = 0; i <= 8; i++) {// 绘画纵线

                 canvas.drawLine(oldX, 0, oldX, 479, mPaint);

                 oldX = oldX+60;}

//绘制波形

                   mPaint.setColor(Color.YELLOW);// 画笔设置为绿色

                              for (int x = 0; x < length; x++) {

                 y = data_osc[ i];//读取y轴数值,波形数据保存在数组ata_osc[]中

                 canvas.drawPoint(x, y, mPaint);//描点

   }

   sfh.unlockCanvasAndPost(canvas);//解锁画布,提交画好的图像

}


结  论

经过三个月的努力,终于完成了本毕业设计。总结这三个月来的工作,主要有以下几个方面:

1、综述了现阶段数字存储示波器技术及产品的国内外发展状况,对数字存储示波器的原理、工作方式、显示方式等的基本概念及技术发展进行了介绍。

2、针对设计的任务和要求,确定了存储示波器波形采样和数据处理及波形重组的硬件和软件方案。

3、对整机各部分关键电路进行相关理论分析、计算和设计。

4、本系统由单片机主控,高速A/D转换器ADS830进行模数转换,用FIFO缓存芯片IDT7203来实现波形的存储。通过软件对转换后的数字信号进行处理,并通过蓝牙把波形数据发送到Android设备上进行显示。

5、完成了作品的制作与调试;论述了仪器的测试方法,完成数据测试及测试结果分析。

采用Android设备作为显示平台,是本设计最大的一个特点。本设计的基本思路是,由单片机对ADC采样到的数据进行处理,再通过蓝牙把波形数据发送到Android设备上进行显示。同时由于Android设备都采用触摸屏,因此示波器的参数可以很方便的通过触摸屏进行设置。本设计采用Android设备取代液晶屏,并使用蓝牙进行数据传输,充分利用了Android设备的硬件资源。其优点是降低了系统开发成本,并大大减小了系统硬件体积,完全实现了本设计小巧便携的设计宗旨。

本系统的数据采集系统、数据处理系统和波形显示系统等模块都经过了软硬件的调试。虽然整个系统的实现方案基本完成,但是还有一些不够理想的地方,仍然有不少的工作需要继续。比如需要进一步改善测量精度、模拟带宽以及系统噪声等性能;添加等效采样、波形回调以及数据导出等功能。


参  考  文  献

[1]  张永瑞. 电子测量技术基础[M] . 西安:西安电子科技大学出版社,2006:131-133.

[2]  朱明强. 基于单片机及CPLD的数字存储示波器的研究与设计[D] . 北京:北京交通大学,2008.

[3]  王彦斌. 数字存储示波器中模拟通道设计[D] . 成都:电子科技大学,2008.

[4]  冯静亚,于强,吕朝晖,罗福山. 虚拟示波器的软件设计与应用[J] . 计算机工程与设计,2007,28(1):211-273.

[5]  张虹. 泰克公司推出可分析带宽达20GHz信号的Signal Vu软件[J] . 中国无线电,2008,9(7):23-25.

[6]  赵茂泰. 简易数字存储示波器评述[J] . 电子世界,2002,5(11):40-42.

[7]  徐俊毅. 力科推出带宽可达30GHz的WaveMaster8Zi系列示波器[J] . 电子与电脑,2009,5(13):53-56.

[8]  蒙玉宝. 40Gsps随机取样数字示波器关键技术预先研究[D] . 成都:电子科技大学,2003.

[9]  杨丰盛. Android应用开发揭秘[M] . 北京:机械工业出版社,2009:15-16.

[10]  陈景波,杨放,姚定江. 基于CompuScope 82G型高速数据采集卡的虚拟示波器设计[J] . 国外电子元器件,2006,11(2):60-62.

[11]  H.Troy Nagle,D.Carroll,J.David Irwin . DIGITAL LOGIC CIRCUIT ANALYSIS & DESIGN[M] . 北京:清华大学出版,2009:57-71.

[12] V.V.Panasyuk. Electronic oscillograph unit for recording failure diagrams in the impact testing of metals[J] . Soviet Materials Science,2001,9(5):10-12.

[13] 刘杨斌,刘其峰,华慧. 基于AT89S52单片机的简易数字示波器设计[J] . 现代电子技术,2011,14(14):17-18.

[14] 贾春霞,张洪艳. 数字存储示波器现状初探[J] . 仪器仪表用户,2004,8(15):25-26.

[15] 张根柱,陈勇钢. 数字存储示波器[J] . 现代技术开发,1999,5(12):49-50.

[16]  J. Molenaar,R. Voorhorst. Study on Remote Control Techniques to the Digital Storage Oscilloscope[J] . Energy Procedia,2012,16(9):34-35.

[17] 刘岩. 数字示波器的设计[J] . 电脑知识与技术,2008,12(20):21-22.

[18] R. P. Patterson. Design and Implementation of Multifunctional Virtual Oscilloscope Using USB Data-Acquisition Card[J] . Procedia Engineering,2012,10(25):40-42.

[19] W. A. Grind. Patent Application Titled "Oscilloscope with Internally Generated Mixed Signal Oscilloscope Demo Mode Stimulus, and Integrated Demonstration" Under Review[J] . Journal of Engineering,2012,9(17):7-8.


致  谢

在这里要衷心感谢我的指导老师苏成悦教授的悉心指导和多方关怀。苏老师思维敏锐,视野开阔,创新性强。他渊博的学识,严谨的治学作风,执着的敬业精神都深深地影响着我。我深深感受到他对研究的精益求精,对学生的鼓励和爱护。他对工作和生活的态度将是我一生学习的榜样。

此外,还需要感谢我身边的同学们。在设计过程中碰到的问题,我都会找同学一起来讨论解决。同学们都很热情、很积极的参与到讨论中,而且大部分问题在讨论之后都得到了解决。除了学习之外,在生活上同学们对我的帮助也是非常大的。在此,我衷心感谢各位亲爱的同学们。


附录 A  实物图

图A1  信号采集模块

图A2  系统测试图


附录 B  系统主程序设计源码

#include "STM32Lib\stm32f10x.h"

#include "hal.h"

extern void SetLevel(u8 pulse);

extern void Adc1_Init(u8 ADC_CH_x,u8 ADC_CH_SMP);

extern u16 Get_Adc(u8 ADC_CH_x);

u16 data_test_16;

u8 data_test_8;

u8 Data_osc[320];              //波形数据

u8 Data_osc_full=0;

u8 Data_set[10];

//延迟函数

void Delay(u16 speed)

{

              u16 i;

              while(speed!=0)

              {

                            speed--;

                            for(i=0;i<400;i++);

              }

}

//设置水平扫描速度

void shuiping(u8 sp)

{

              if(sp >= 12)

                            sp=12;

              if(sp <= 1)

                            sp=1;

              //设置不同采样速率

              switch(sp)

              {

                            case 1:TIM1->PSC=0; break;

                            case 2:TIM1->PSC=1; break;

                            case 3:TIM1->PSC=3; break;

                            case 4:TIM1->PSC=9; break;

                            case 5:TIM1->PSC=19; break;

                            case 6:TIM1->PSC=39; break;

                            case 7:TIM1->PSC=99; break;

                            case 8:TIM1->PSC=199; break;

                            case 9:TIM1->PSC=399; break;

                            case 10:TIM1->PSC=999; break;

                            case 11:TIM1->PSC=1999; break;

                            case 12:TIM1->PSC=3999; break;            

                            default :break;                           

              }

}

//设置水平灵敏度

void SetAGC(u16 pulse)

{

              if(pulse >= 3)

                            pulse=3;

              if(pulse <= 1)

                            pulse=1;

              //设置不同的增益

              switch(pulse)

              {

                case 1: TIM4->CCR1=255;break;

                case 2: TIM4->CCR1=195;break;

                case 3: TIM4->CCR1=153;break;

              }

}

int main(void)

{

              u16 i_osc=0;

              u16 i_start=0;

              ChipHalInit();                            //片内硬件初始化

              ChipOutHalInit();              //片外硬件初始化                                                                                                                  

              SetLevel(128);                //初始化垂直基线

              SetAGC(2);                                          //初始化垂直灵敏度

              shuiping(6);                  //初始化水平灵敏度            

              while(1)

              {

                            if(Data_osc_full==1)

                            {

                                          Data_osc_full=0;

                                          while(!(Data_osc[i_start]<=160&& Data_osc[i_start+1]>=160))

                                          {

                                                        i_start++;

                                                        if(i_start>=150)

                                                                      break;            

                                          }

            if(i_start < 150)

                                          {

                                                        for( i_osc=0; i_osc<160; i_osc++)

                                                        {

                                                                      USART2_Putc(Data_osc[i_osc + i_start]);

                                                        }

                                          }

                                          Delay(500);              //延时,等待Android系统处理完毕数据

                                TIM1->CR1 |= 0x0001;              //开启定时器TIM1            

                            }

              }

}


附录 C  Android蓝牙服务程序设计源码

package com.test.BTClient;

import android.app.Activity;

import android.bluetooth.BluetoothAdapter;

import android.bluetooth.BluetoothDevice;

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.content.IntentFilter;

import android.os.Bundle;

import android.util.Log;

import android.view.View;

import android.view.Window;

import android.view.View.OnClickListener;

import android.widget.AdapterView;

import android.widget.ArrayAdapter;

import android.widget.Button;

import android.widget.ListView;

import android.widget.TextView;

import android.widget.AdapterView.OnItemClickListener;

public class DeviceListActivity extends Activity {

    // 调试用

    private static final String TAG = "DeviceListActivity";

    private static final boolean D = true;

    // 返回时数据标签

    public static String EXTRA_DEVICE_ADDRESS = "设备地址";

    // 成员域

    private BluetoothAdapter mBtAdapter;

    private ArrayAdapter mPairedDevicesArrayAdapter;

    private ArrayAdapter mNewDevicesArrayAdapter;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        // 创建并显示窗口,并设置窗口显示模式为窗口方式

        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);

        setContentView(R.layout.device_list);

        // 设定默认返回值为取消

        setResult(Activity.RESULT_CANCELED);

        // 设定扫描按键响应

        Button scanButton = (Button) findViewById(R.id.button_scan);

        scanButton.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {

                doDiscovery();

                v.setVisibility(View.GONE);

            }

        });

        // 初使化设备存储数组

        mPairedDevicesArrayAdapter = new ArrayAdapter(this,

R.layout.device_name);

        mNewDevicesArrayAdapter = new ArrayAdapter(this,

R.layout.device_name);

        // 设置已配队设备列表

        ListView pairedListView = (ListView) findViewById(R.id.paired_devices);

        pairedListView.setAdapter(mPairedDevicesArrayAdapter);

        pairedListView.setOnItemClickListener(mDeviceClickListener);

        // 设置新查找设备列表

        ListView newDevicesListView = (ListView) findViewById(R.id.new_devices);

        newDevicesListView.setAdapter(mNewDevicesArrayAdapter);

        newDevicesListView.setOnItemClickListener(mDeviceClickListener);

        // 注册接收查找到设备action接收器

        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);

        this.registerReceiver(mReceiver, filter);

        // 注册查找结束action接收器

        filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);

        this.registerReceiver(mReceiver, filter);

        // 得到本地蓝牙句柄

        mBtAdapter = BluetoothAdapter.getDefaultAdapter();

    }

    @Override

    protected void onDestroy() {

        super.onDestroy();

        // 关闭服务查找

        if (mBtAdapter != null) {

            mBtAdapter.cancelDiscovery();

        }

        // 注销action接收器

        this.unregisterReceiver(mReceiver);

    }

    public void OnCancel(View v){

                  finish();

    }

    //开始服务和设备查找

    private void doDiscovery() {

        if (D) Log.d(TAG, "doDiscovery()");

        // 在窗口显示查找中信息

        setProgressBarIndeterminateVisibility(true);

        setTitle("查找设备中...");

        // 显示其它设备(未配对设备)列表

        findViewById(R.id.title_new_devices).setVisibility(View.VISIBLE);

        // 关闭再进行的服务查找

        if (mBtAdapter.isDiscovering()) {

            mBtAdapter.cancelDiscovery();

        }

        //并重新开始

        mBtAdapter.startDiscovery();

    }

    // 选择设备响应函数

    private OnItemClickListener mDeviceClickListener = new OnItemClickListener() {

        public void onItemClick(AdapterView av, View v, int arg2, long arg3) {

            // 准备连接设备,关闭服务查找

            mBtAdapter.cancelDiscovery();

            // 得到mac地址

            String info = ((TextView) v).getText().toString();

            String address = info.substring(info.length() - 17);

            // 设置返回数据

            Intent intent = new Intent();

            intent.putExtra(EXTRA_DEVICE_ADDRESS, address);

            // 设置返回值并结束程序

            setResult(Activity.RESULT_OK, intent);

            finish();

        }

    };

    // 查找到设备和搜索完成action监听器

    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {

        @Override

        public void onReceive(Context context, Intent intent) {

            String action = intent.getAction();

            // 查找到设备action

            if (BluetoothDevice.ACTION_FOUND.equals(action)) {

                // 得到蓝牙设备

                BluetoothDevice device =

  intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                // 如果是已配对的则略过,其余的在添加到列表中进行显示

                if (device.getBondState() != BluetoothDevice.BOND_BONDED) {

                    mNewDevicesArrayAdapter.add(device.getName() + "" +

device.getAddress());

                }else{  //添加到已配对设备列表

                mPairedDevicesArrayAdapter.add(device.getName() + "" +

device.getAddress());

                }

            // 搜索完成action

            } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {

                setProgressBarIndeterminateVisibility(false);

                setTitle("选择要连接的设备");

                if (mNewDevicesArrayAdapter.getCount() == 0) {

                    String noDevices = "没有找到新设备";

                    mNewDevicesArrayAdapter.add(noDevices);

                }

            }

        }

    };


}

评分

参与人数 4黑币 +11 收起 理由
lxj199610 + 6 很给力!
ljldx + 3 分析得很到位,受教了,硬件部分可参考魏源.
541199109 + 1 赞一个!
打卡机的 + 1 很给力!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏29 分享淘帖 顶3 踩
回复

使用道具 举报

沙发
ID:113875 发表于 2016-4-13 09:10 | 只看该作者
学习了~~~~~~~~~~
回复

使用道具 举报

板凳
ID:114085 发表于 2016-4-14 23:05 | 只看该作者
非常感谢!我先下载学习下!
回复

使用道具 举报

地板
ID:123117 发表于 2016-5-25 15:08 | 只看该作者
好东西啊,很值得学习!
回复

使用道具 举报

5#
ID:123154 发表于 2016-5-25 16:43 | 只看该作者
受教了 很不错 就是没钱下载
回复

使用道具 举报

6#
ID:117823 发表于 2016-6-4 01:54 来自手机 | 只看该作者
这个很有用
回复

使用道具 举报

7#
ID:129333 发表于 2016-11-11 21:23 | 只看该作者
很不错,楼主,谢谢了
回复

使用道具 举报

8#
ID:171328 发表于 2017-3-16 20:11 | 只看该作者
学习了,刚好可以借用,51黑有你更精彩
回复

使用道具 举报

9#
ID:204243 发表于 2017-5-24 12:18 来自手机 | 只看该作者
感谢楼主
回复

使用道具 举报

10#
ID:135643 发表于 2017-5-25 19:06 | 只看该作者
这个确实比较实用
回复

使用道具 举报

11#
ID:75267 发表于 2017-6-27 11:59 | 只看该作者
感谢分享 这个厉害了
回复

使用道具 举报

12#
ID:233712 发表于 2017-9-17 20:36 | 只看该作者

这个确实比较实用
回复

使用道具 举报

13#
ID:237354 发表于 2018-2-27 23:41 | 只看该作者
很好的资料
回复

使用道具 举报

14#
ID:142638 发表于 2018-4-12 15:03 | 只看该作者
感谢楼主
回复

使用道具 举报

15#
ID:341542 发表于 2018-5-30 17:16 | 只看该作者
不错 ,学习~
回复

使用道具 举报

16#
ID:368366 发表于 2018-7-11 11:43 | 只看该作者
白高兴一场,哎,android不是源码,根本没法实现功能,是不是楼主传错了求源码,求源码
回复

使用道具 举报

17#
ID:125889 发表于 2018-8-28 21:14 | 只看该作者
谢谢作者开源分享,我下载下来学习一下
回复

使用道具 举报

18#
ID:125889 发表于 2018-8-29 07:32 | 只看该作者
楼主这个的线路板是怎么弄的?用洞洞板可以吗?
回复

使用道具 举报

19#
ID:74977 发表于 2018-12-13 15:50 | 只看该作者
哇,楼主厉害了,我也来学习学习
回复

使用道具 举报

20#
ID:521014 发表于 2019-6-3 18:29 | 只看该作者
楼主厉害了,学习学习学习
回复

使用道具 举报

21#
ID:405966 发表于 2019-6-23 23:13 来自手机 | 只看该作者
几个主要的元件有点小贵
回复

使用道具 举报

22#
ID:405966 发表于 2019-6-27 06:28 来自手机 | 只看该作者
不错的东西,可惜木有币
回复

使用道具 举报

23#
ID:576975 发表于 2019-7-3 13:07 | 只看该作者
不错的东西
回复

使用道具 举报

24#
ID:452731 发表于 2019-7-11 12:07 | 只看该作者
只来学习,支持楼主
回复

使用道具 举报

25#
ID:696797 发表于 2020-2-23 09:17 | 只看该作者
很棒  很有用
回复

使用道具 举报

26#
ID:253767 发表于 2020-4-22 06:51 | 只看该作者
谢谢分享!!!
回复

使用道具 举报

27#
ID:1043982 发表于 2022-9-14 08:11 | 只看该作者
楼主做的真好,学习了,对我帮助很大
回复

使用道具 举报

28#
ID:909377 发表于 2022-10-8 20:33 | 只看该作者
可进行瞬态分析?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表