测控技术课程设计
指导书
北京邮电大学自动化学院
2007年8月
测控技术课程设计指导书
[课程设计的目的]
测控系统的设计涉及许多技术,其应用领域众多,在现代国防、现代工业、科研教育、机械医疗等领域里有着广泛的应用。另一方面,它的理论性与实践性都很强,需要努力做到理论与实践相结合,为此我们安排此课程设计,加深同学们对测试技术理论的理解,加强同学们对实践操作能力的培养。重点是了解测控系统设计的一般流程,掌握设计测控系统的一般方法,树立计算机测控系统的整体概念。
[课程设计的任务]
在生产过程和科学研究中所接触到的被测量大多数是非电物理量,例如位移,力,转速,扭矩,温度,振动,流量,风速,等等。非电量种类繁多,特性千差万别,很多又是不便于直接测量的模拟信号。为了测量与处理方便,需要把非电量转换为电量,这一步通常是通过各式传感器来转换,常称为一次转换;为适应计算机的统计分析处理,又需要把模拟量转化为数字量,这一步是通过A/D转换来实现的,常称为二次转换。这两方面是测试系统的两个重要环节(在测控领域里,有时还需要把处理好的数字量再转换成模拟量反馈回来控制工作进程,常称为三次转换)。它们的关系如下:
本次课程设计是设计一套完整的微机实时测控系统,具体内容包括:
1、了解测控系统设计相关知识和具体指标要求。
2、多功能A/D采集板的编程使用和信号采集。
3、信号的显示与处理。
4、控制信号的输出。(选项)
5、测控系统软件设计与联调。
测控系统软件设计要经过老师的验收,测控系统要演示正确,功能完善,并且正确回答有关硬件和编程的问题后才能通过。
课程设计结束后同学们需交设计报告,其中包括:
1、计算机检测系统设计,主要和关键部分的程序如:A/D板采集数据的源程序,源程序中注释不少于30%,源程序设计的流程图。
2、正弦信号、矩形信号、三角波信号的采集数据和波形图、FFT频谱图的屏幕截图。
3、系统主要界面的屏幕截图。
4、系统设计时遇到的问题和心得体会。
5、填写北京邮电大学课程设计报告表格。
6、相关程序打包存入指定计算机的目录下。文件名称班号序号和姓名。
[先修课程]
《测试技术与测试信号处理》,《C 语言程序设计》,《微机原理与接口技术》
《模拟电子技术》,《数字电子技术》
[模/数与数/模转换 的原理]
常用D/A转换器有:
权电阻网络D/A转换器
T型电阻网络D/A转换器
开关树型D/A转换器
权电流型D/A转换器 等等,
常用A/D转换器有:
逐次逼近型A/D转换器
双积分型A/D转换器
瞬现型A/D转换器 等等。
本实验所用的A/D转换器为BB公司生产的ADS7818,是12位逐次逼近型。具体的工作原理请参看书《数字电子技术基础》的“数-模和模-数转换”这一章 ((第四版) 阎石主编。
[采样定理]
一、信号的采样在微机的测控系统中,一台微机往往对工业现场的多个测点进行测试,这些测试不是同时进行的,而是按照分时的方式逐个对多路测点进行测试。因此,需要把时间上连续的模拟信号,转变为时间上离散的信号。这一过程称之为信号的采样。
如图1-2a所示,连续的模拟输入信号e(t)按一定的时间间隔T逐点地采集瞬时值,并保持一个时间τ,从而变成时间上的离散,幅值等于采样时刻的输入信号瞬时值的方波序列信号,简称采样信号e*(t)。两次采样之间的时间间隔T称为采样周期,保持时间τ称为采样时间。从理论上讲不需要保持操作,但由于A/D变换需要时间,为了减少在变换过程中信号变化带来的影响,采样后的信号在τ中将保持幅值不变,直到完成变换。相应的电路就称为采样保持电路,一般的,可取理想化的情况,即认为τ<<T,可忽略不记τ值,将离散后的信号e*(t)看成是理想脉冲序列。
τ
图1-2 正弦信号的采样
a—ωs<2ωmax; b—ωs>>2ωmax
二、采样定理采样信号只给出了采样时刻的数值e(0),e(T),e(2T) …… 。对连续信号来说,它在任何时刻的数值都是已知的,但在采样后,除了能掌握e(T)在采样时刻的数值e(kT)以外,在各采样间隔内的信号就丢失了,如图1-2b所示 。采样周期T越大,信号变化越快,则信息丢失越严重。采样频率应如何选择才能保证无失真地恢复原信号呢?采样定理给出了选择采样频率的原则。
采样定理指出:一个带宽有限(例如从0到fm)的信号e(T),可用相隔时间为 T≤1/2 fm的若干个采样值来代表。反之,若想得到原来的信号e(T),只要将该信号的各采样值通过一个截止频率为fm的理想低通滤波器。即无失真频率应满足fs≥2 fm 。
采样定理虽然给出了选择采样周期的理论依据,但并未指出解决实际问题的条件与算公式。在实际中常以经验的方法确定采样周期。显然,采样周期T越小,越接近连续系统,控制精度越高,但这时将加重计算机的负担,从而使可控制的回路数目减少。另外,采样周期也不能小于执行程序所需要的时间。所以合理选择采样周期非常重要。
在检测系统中,正弦波、矩形波、三角波的采样周期根据它们的频率决定,例如可定为100微秒。
三、采样保持电路在微机测控系统中,由于微机是分时工作的,即在每一时刻只能有一个参数被采样,而且在采样完成后,微机还要花大量时间进行数据处理及控制计算,因此,在整个微机测试系统中,每个参数大部分时间都是在“脱机”的情况下工作的,特别是当被测参数比较多时更是如此。另一方面,由于A/D转换器的转换过程需要一定的时间,因而,在A/D转换器的转换过程中必须保持参数值不变,否则将影响转换精度。尤其是当参数的变化速度比较快时,更是如此。能够完成上述功能的电路叫采样保持(Sample/Hold)电路。最简单的采样保持电路是由电容及开关组成的。此电容一般选用泄露量比较低的电容(如聚乙烯或聚四氟乙烯电容)。为了提高采样保持器的精度,目前使用的采样保持电路一般均采用具有高输入阻抗的场效应管作为输入运算放大器 。典型的电路如图 1-3所示。
图中采样保持电路由输入输出缓冲运算放大器A1,A2及逻辑输入控制的开关电路组成。在采样期间,开关S 是闭合的。输入信号UI经高增益的放大器A1 输出,向电容C充电。在保持期间,开关S断开,由于A2运算放大器输入阻抗很高,所以,在理想情况下,电容C上的电压将保持充电时的最终值。
本次课程设计的测控系统所用的A/D转换器ADS7818中已内置采样保持器。
[典型的数据采集/控制系统]
图1-4 典型数据采集/控制系统
图中被测信号由传感器转化成相应的电信号(最终是电压),这是任何非电检测必不可少的环节。不同信号其传感器是不同的。例如,若第1路被测信号是温度,其传感器可以是热敏电阻、热电耦等。第2路是力,传感器可以是各种应变片,等等。
传感器输出的信号不能直接送到输出设备进行显示或记录,需要进一步处理。信号的处理由两部分完成,即模拟信号处理和数字信号处理。后者由计算机承担。计算机以前的全部信号处理都是模拟信号处理。其中A/D(模/数)转换是关键环节,它的作用是将模拟量转换为数字量以适应计算机工作。
模拟信号处理与调节的内容是相当丰富的。信号调节的主要作用是使传感器输出信号与A/D转换器相匹配,例如A/D转换的输入电平是0-5V,而传感器的输出电平仅几毫伏(mV),这时必须采取放大措施以减小量化误差,放大器输出电平愈接近A/D输入的满标,相对误差也就越小,这时的信号调节器就是放大器。当然,若传感器输出电平过大,则信号调节器应是衰减器。如果传感器输出信号过程中或在传输过程中,混入了虚假部分,就需要进行滤波、压缩频带,用以降低采样率。另外,阻抗变换、屏蔽接地、调制与解调、信号线性化等等,皆属处理范围。一般说来,对弱信号测试,放大与滤波是最重要的环节。并非每个系统都得包含上述全部内容,对不同的测试任务,系统应包含哪些环节是有所选择的。注意到被测信号有n个,相应的n个通道共享一个A/D转换器,这样做的目的是为了降低成本、减小体积。为了是各路信号互不混迭,系统中比须采用模拟多路切换开关。切换开关相当于一个单刀多掷开关(这里为n掷)开关,它的作用是把各路信号按预定时序分时地与保持电路接通。保持电路的引入是因为A/D转换需要一定时间,在转换期间模拟信号应保持不变。
带计算机的测控系统的性能是很高的。计算机在系统究竟起何作用,有何优点呢?
(1)使测控自动化
由于计算机有信号存贮、判断和处理能力,所以能控制开关通断、量程自动切换、系统自动校准、自动诊断故障、结果自动输出,等等。总之,计算机是测试系统的神经中枢,它使整个系统成为一个有机的整体,使测控实现了自动化,从而也大大地提高了测控速度。
(2)提高测控精度由于外界的干扰、内部的噪音、电源的波动、温度的变化、期间的非线性等,必然降低测控精度。引入微型计算机后,系统可以进行数字滤波,对器件的非线性进行校正;系统可以进行自动校准以消除系统误差,多次重复测量可以削弱随机误差。从而可将测控精度提高很多。
(3)通过数据变换实现多功能测频率后,通过倒数变换(T=1/f) 可得周期;测正弦波的峰值可求得有效值(v =vm/20.5 );时域数据通过快速傅立叶变换(FFT)可得到相应的频域数据可求得信号的最大值、最小值、平均值…… 。
(4)降低了测控系统成本由于软件有替代硬件的功能,各种运算器、比较器、滤波器、线性化器、定时器等都可由计算机承担,省去一大批硬件,从而减低了系统的成本。由于计算机的性能不断提高,价格逐年下降,这一优点今后将更加突出。
(5)提高了系统的可靠性
另外,由于计算机有分析、判断的能力,因此它作为过程控制的核心——决策机构是不容置疑的。
测量结果由计算机通过接口电路送给输出设备。输出设备可采用数字显示、打印机或绘图仪。如果要观察或记录被测信号的波形,可用D/A转换器把计算机输出的数字量恢复成模拟量,然后用示波器或X-Y记录仪显示或记录,也可将数字量直接送到显示终端绘制波形。D/A输出的模拟信号可作为控制信号。
[设备及器材]
微机、多功能A/D板及接口、示波器、信号发生器。
[设计步骤]
一、理论知识准备。
第一部分,采样定理、A/D的原理与D/A 的原理复习.
第二部分,VC、VB语言复习及图形编程.
第三部分,A/D板使用介绍.
第四部分,典型测控采集系统介绍、布置设计内容.
信号发生器信号与A/D板连接
AC6111AD板经DB25芯电缆经过AC146端子板连接信号发生器输出的模拟信号。
三、测控系统软件设计要求编写A/D板的初始化程序与采集程序,调试上述程序,绘制波形,可用信号发生器输出的信号调试。注意:图形曲线以及幅值刻度和时间刻度要与实际信号一直。调试程序可参考所给的参考程序。
调试成功后可编辑其他相关功能,(如设置采样长度、采样间隔、形成数据文件、FFT分析及波形、统计分析等)。自动检测系统在数据处理功能上除了可进行FFT分析外,还应给出检测信号的最大值、最小值、平均值。自动分析得出信号的频率和周期。
所编程序包括菜单的实现及相关功能,如举例所示,其中功能必须包括数据的采集及保存,波形显示,数据显示、FFT变换、信号周期和频率的自动检测。
通过D/A输出相关波形,由示波器进行观测的内容作为选项,完成基本内容的同学可以设计实习。
有关FFT变换的编程,可参看《测试技术与测试信号处理》(吴正毅编,清华大学出版社出版)203页至212页有关内容。
完成测控系统的界面及工作菜单设计。一个好的采集系统程序应有一个方便、实用、友好、快捷的工作界面。因此编制一个好的菜单亦很重要。
[调试注意事项]
1、连接好线路后,再打开电源。
2、使用FFT程序时,注意对数据点数的要求。
3、A/D板使用前要仔细了解说明及相关编程,注意接口引脚。调试程序要耐心。
[ AC6111 A/D板介绍 ]
AC6111是一款中速度通用A/D板,采用PCI总线支持即插即用。属于“JP FREE”系列,无需任何跳线、开关设置,方便应用。(北京双诺测控技术有限公司)
AC6111具有16路模拟输入、2路12位D/A输出、16路可编程开关量、一路16位计数器、采集转换支持多种触发形式。AC6111采用大规模可编程门阵列设计,提高可靠性。
1.1 AD部分介绍:
采用DB25接头。
16路输入,支持通道扫描及伪同时采样(同步采保)扫描模式。(注:伪同步模式:既模拟同步采样模式,采样被定时器或外部时钟启动后,6111以400KHz的最大速度对用户设置的一组通道采样,结束后等待下一次启动,如此循环采样),新卡支持16路单端/8路差分输入(连接与定义见后)。
12位400KHz A/D转换器。多通道采集速度可以达到最大采样速度。
模拟输入通道支持自动扫描模式,可以设置任意起始、截止通道。
输入量程程控,范围:5伏、10伏、(5伏、(10伏。
输入通道模式:SH/NORMAL,既:伪同步/等时间间距通道扫描模式。
AD启动模式:软件、外部硬件触发。触发可以选择上升、下降边沿有效。
AD定时器模式:板上16位定时器(基准时钟4MHz)、外部同步时钟(OCLK)。OCLK可以选择时钟上升或下降边沿有效。时钟触发在“SH”模式,每个触发转换N个通道;“NORMAL”模式,每个时钟触发转换一个通道。
AD接口采用4K字FIFO,支持大容量数据采集。
采集数据支持:起始通道标志、触发标志。用户可以检测采集数据的连续性及支持预触发功能。
1.2 AD性能:
A/D转换器ADS7818:400KHZ,12位A/D,A/D内置采样保持器。
16路单端输入/8路差分,输入阻抗大于100MΩ,最大输入电压:< +12V / -12V,瞬时输入耐压:-30V~+30V,差分输入共模抑制比大于80DB。DB25孔式输入连接器。
输入支持:SH、NORMAL二种通道模式(并行采样、扫描采样)。对应最小每通道采样时间:
SH:N*2.5 (uS) 其中:N为设置的采样通道数量。
NORMAL:2.5uS
程控模拟输入范围,双极性输入幅度: 5V、(10伏,单极性输入幅度:5V、10V输入,对应输入幅度及精度如下:
输入
精度
分辨率
0-5V
0.1%
1LSB
0-10V
0.1%
1LSB
-5V-+5V
0.1%
1LSB
-10V-+10V
0.1%
1LSB
A/D最大通过率:400KHZ,输入通道建立时间<2uS。
AD工作模式、参数:
采集启动模式:软件、硬件触发(外触发)启动。外部触发的极性可以选择为“上升边沿“或“下降边沿“有效。
触发输入:TTL电平(注1),内置10K上拉电阻,CMOS输入。输入带shmit触发器。
采样定时器模式:内部时钟、外部时钟。外部时钟支持上升、下降边沿选择。
板上时钟:16位定时器、基准时钟4MHz,设置范围:10~65535,对应采样速度:400KHz~16Hz。
外部时钟输入:TTL电平,输入特性同外部触发输入。时钟输入最小有效脉冲宽度:大于100nS。时钟频率必须小于对应采样模式的最大采样速度。
AD与计算机采用FIFO接口,容量:4K字,提供:FIFO空、半满、溢出标志。半满标志支持中断。
注1:TTL电平:高电平大于2.3V,低电平小于:0.6V
1.3 DA部分介绍
DB25插座。
二路D/A输出,分辨率12位。
模拟输出量程:10伏、(10伏,每路输出可以分别软件设置。
输出建立时间:小于50微秒(0.1%精度)
1.4 DA性能
D/A转换器DAC7612:二路12位D/A,输出电压10V或(10V(程控)。
精度:10V:0.1%,-10V ~ +10V:0.2%。
分辨率:12位。
输出驱动能力:电流大于5毫安、
电容驱动能力:100P。
1.5 开关量部分介绍:
20芯扁平电缆插座。
16位开关量的二个8位可以分别设置为输入、输出。
1.6 开关量性能:
16路开关量(2个8位定义为:PA、PB口),TTL电平。PA、PB可以分别程控为输入、输出。
20脚扁平电缆插座输出、输出。开关量复位后为输入状态。
输出高电压 > 3V,低电压 < 0.4V
输出下拉电流 > 20mA/路,上拉>6mA
输入电流:<0.1mA 输入高电压门限:〉2.5V,低电压:〈 0.8V,
最大输入耐压:-0.3V ~ +7V
1.7 计数器/定时器部分介绍:
一路16位计数器(DB25插座输入)。内置16位定时器(基准时钟:1MHz),可以精确测量频率、脉冲宽度。定时器测量范围:1微秒-65毫秒。
1.8 计数器/定时器性能:
16位计数器,计数范围1~65535,减法计数器。计数输入TTL电平,上升边沿有效,内部结构同触发输入。最大计数频率:大于5MHz。具有计数溢出标志(计数到0时溢出)。
内置16位定时器,可以测量从计数器设置数值到溢出有效这一个时间段的时间。定时器输入时钟为1MHz(1uS周期),精度:(66纳秒。
计数器与定时器结合可以完成:计数、测频、测量脉冲宽度的功能。
PCI总线,符合PCI V2.1标准
AC6111占用64个I/O选通空间(自动分配)。
1.9 连接
AC6111模拟输入可以配接AC146端子板。开关量可以配接AC142或AC145端子板
win98、2000、XP、NT驱动。
AC146:提供25端子到DB25插座的接线
P1:DB25芯D型插头,孔式,在输入的插头上标有对应的号码。定义如下:
AC6111采用PLX9052 PCI接口芯片及门阵列作为主控芯片。门阵列控制模拟输入、采样、模拟输出及开关量。如下图:
1.10 软件支持:
提供测试程序(含:波形显示):AC6111.EXE
win98、2000、XP、NT驱动。
[原理说明]
2.1 AD转换部分的原理
1) 转换模式、通道控制
ac6111具有二种采样模式,SH:采保模式、NORMAL:普通扫描模式。
SH模式:模拟同步采样模式,适合应用在对一组输入通道采样的时差要求尽量小,但组之间的时间间隔较大的应用场合。当由定时器脉冲或外部时钟有效边沿启动后,在板上逻辑的控制下以400KHz的速度,从第N通道开始顺序转换到第M通道结束,(N、M 分别为用户设置的起始与结束通道,N<=M)。同时转换数据顺序写入FIFO寄存器中,转换完后重新进入等待模式,等待下一个启动信号。
NORMAL模式:普通模式指,当由定时器脉冲或外部时钟有效边沿启动后,AD开始转换当前通道,并通道在转换时自动设置为下一个转换通道,等待下一个有效启动脉冲到来。通道转换顺序为:从第N通道开始顺序转换到第M通道结束,然后由重新从N到M通道,如此循环直到用户结束转换,(N、M定义同上)。转换数据顺序写入FIFO寄存器中。
因此,在不同模式下,启动时钟的最大频率不同。由于AD的转换速度是400KHz,各种模式下的最大转换速度如下:
SH模式:K个通道的最小转换时间 Tmin = 2.5*K (uS),K=(M-N+1)为一次转换的输入通道数量。等效每通道最大采样速度:1000/Tmin(KHz)。
NORMAL:每通道最小转换时间:Tmin=2.5uS/通道,等效每通道最大转换速度:400/(转换通道个数) (KHz)。
2)AD转换启动控制转换启动可以在触发选择中(TRSL)设置:由软件或外部硬件触发启动整个转换过程,除非用户终止转换,否测将一直转换下去。硬件触发可以在触发极性选择中(TRPOL)设置为“上升边沿”或“下降边沿”有效。
一旦启动转换,AD转换将在板上定时器或外部时钟驱动下按用户设置的起始(STCH)、终止通道(ENDCH)逐一通道顺序、循环转换。时钟选择(CLKSL)可以软件设置。应用外部时钟时,可以在模式设置字的CLKPOL控制位,控制时钟为“上升边沿”或“下降边沿”有效或启动转换。
用户应该区分二种模式:SH、NORMAL模式的通道转换模式及最小转换时间(或最大转换速度)的要求。
小结:采样模式转换触发启动:软件/硬件 (trsl=0/1)。
硬件触发极性:上升/下降边沿 (trpol=0/1)。
转换控制时钟:内部/外部 (clksl=0/1)。
外部时钟极性,上升/下降 (clkpol=0/1)。
模拟通道采样模式:SH/NORMAL (sammode=1/0)。
采样通道控制:起始通道/结束通道 (stch/endch)。
3)板上换定时器
AC6111的16位定时器为模拟转换提供精确的定时,误差小于(250纳秒。定时器输入基准时钟为4MHz,周期为250纳秒。定时器为减法计数器,当由用户设置数值tdata减到1时,发出启动脉冲并自动将定时器数据重新设置为tdata。
16位数据取值(tdata):1~65535,对应周期=0.25*N(uS),N:设置的16位定时器数据tdata。
在NORMAL模式下:最小转换周期为2.5uS(tdata=10),由此6111的转换周期为:2.5uS ~ 16385uS。
在SH模式下,最小转换周期为2.5*Nch(uS),Nch:为采样通道的个数。由此转换周期的间隔范围为:2.5*Nch(uS)~16385uS。
相应启动频率为,F=1000/(0.25*N) (KHz) N:16位定时器数据。
4)FIFO数据、状态
FIFO中的数据按从stch的采样数据到endch采样数据循环存放,如下:
Stch,stch+1,….,endch…….stch,..,endch,……结束
6111的FIFO(先进先出寄存器)容量为4096字,具有空(EF)、半满(HF)、溢出(FF)标志,标志为“0”时有效。采样数据不断的写入FIFO中,用户检测到半满标志后,立即读入2048个数据,以保持FIFO中的数据不超过4096个,否则FIFO溢出,数据队列顺序会打乱(新进入的数据将冲掉最先写入的数据)。如果出现FIFO溢出,只能靠提高计算机速度或降低采样速度或扩大存储器容量来弥补。
数据格式:16位读出数据定义如下:
D15
D14
D13
D12
D11
D10
D9
D8
AD11
AD10
AD9
AD8
AD7
AD6
AD5
AD4
D7
D6
D5
D4
D3
D2
D1
D0
AD3
AD2
AD1
AD0
IO1
IO0
trsign
chsign
D15-D0:16位数据的从高到低位。
AD11-AD0:12位采样数据,(MSB - LSB)。
IO1:开关量通道1状态。
IO0:开关量通道0状态。
Trsign:触发标志,=0:没有触发 / =1:触发有效
Chsign:通道标志,=0:数据为起始通道数据 / =1:其他通道的数据。
应用:
采样时可以记录开关量通道的0、1号,IO0、IO1状态(必须设置为输入状态)。由此可以将二个输入作为数字波形纪录器使用,速度为AD采样速度。
trsign:记录录外部触发状态,如果触发有效,trsign将从0变为1。检测这位可以在软件启动模式下检测外部触发的开始,用于实现预触发功能。
chsign:用于通道检测校正。如果FIFO中的数据乱了,可以通过检测chsign是否为“0”重新获得数据的起始位置。因为通道按stch-endch顺序循环采样,由此chsign每隔采样通道数量的个数为“0”、或对起始通道(stch)采样时起始时为“0”,其余时间为“1”。
5)模拟输入量程选择控制
6111的AD输入有4档量程,为:
单极性:0~5伏、0~10伏双极性:-5伏 ~ +5伏、-10伏 ~ +10伏由PS位设置。PS=0,1,2,3对应选择输入为:5、10、(5、(10伏。
注意:不要在AD转换过程中设置通道stch、endch与PS。
2.2 DA部分的原理:
AC6111提供二路12位D/A。输出可以分别由软件控制为:0-10伏或(10伏。控制寄存器为damode的低二位,如下:16位数据D15-D0的D1、D0控制模拟输出通道1、0号的输出范围,对应控制字定义为,
damode0、damode1,分别控制DA输出通道0、1号。
Damode0或damode1 =0,对应输出为0~10伏。
Damode0或damode1 =1,对应输出为(10伏。
2.3 开关量部分的原理
16路开关量DIO15-DIO0分为二个8位,可以由iomode寄存器的iomode0、iomode1位控制为输入或输出,0号控制低8位PA:DIO7-DIO0、1号控制高8位PB,DIO15-DIO8。Iomode0、iomode1对应16位控制字D15-D0的D0、D1位。定义:
IOMODEn=0:设置对应口为输入。
IOMODEn=1:设置对应口为输出。
注,n=0、1
2.4 计数器的原理
AC6111提供一个16位多功能计数器cnt,可以完成:计数、测频、脉冲宽度测量等功能。计数器为16位减法计数器,设置数据范围1~65535,输入上升边沿脉冲有效(进行减1操作)。计数器减法计数到0时,自动将溢出标志cntov由0设置为1,并保持到重新设置计数器数值。Cntov可以由状态查询位读入。Cnt的数据可以通过cntw、cntr指令设置或随时读出,cntw指令清除计数器、定时器数据并重新开始计数、定时。
AC6111内置16位定时器tcnt,功能为:测量由开始计数的第一个上升边沿到计数器溢出(最后一个脉冲的上升边沿)间的时间周期。Tcnt的输入时钟为1微秒,测量时间为1~65535微秒,如果超过65535。微秒,读入数值恒定为65535微秒。如果读入数据为FFFFH(65535),用户应该认为定时器已经溢出、测量结果无效。定时器性能:
16位定时器,定时范围:1-65535微秒,对应频率测量范围5000KHz-16Hz。
定时器为加法计数器,从0开始计数。
输入时钟:1微秒周期。时钟来自16兆时钟源4分频,并且分频器与定时器同时启动,保证(66纳秒的时钟精度。
应用:
计数器模式:用户初始化计数器数值,开始减法计数操作。可以随时读入计数器数值,计数的个数= 初始化数值-读入数值。
测量N个脉冲上升边沿间的时间:设置计数器数值为N,检测到计数器溢出标志后,读入tcnt数据,时间间隔为tcnt(uS)。注意:N的最小数值为2,即测量一个波形周期(二个上升边沿间)的时间。
波形示意:
注:
1.计数器初始化数据为N
2.定时器结束数值为M。
3.1 API函数接口列表序号
函数名
参数列表
功能描述
1
AC_OpenDriver
void
获得驱动句柄
2
AC_CloseDriver
HANDLE driver
关闭驱动
3
AC_6111_INIT
HANDLE port,
unsigned long *board_id
搜索AC6111卡的数量和识别ID
4
AC_6111_AD
HANDLE port,
Unsigned long board_id,
int ad_timer,
int start_ch,
int end_ch,
int ps,
int triger_sl,
int clk_sl,
int triger_pol,
int clk_pol,
int sam_mode,
int dif,
unsigned long *Data,
int Size
进行AD采样数据由*Data返回
5
AC_6111_DA
HANDLE port,
unsigned long board_id,
unsigned long chn,
unsigned long da_data
DA输出
6
AC_6111_DA_MODE
HANDLE port,
unsigned long board_id,
unsigned long da_mode0,
unsigned long da_mode1
设置DA电压输出电压范围
7
AC_6111_DI
HANDLE port,
unsigned long board_id,
unsigned long *di_data
开关量输入
8
AC_6111_DO
HANDLE port,
unsigned long board_id,
unsigned long do_data
开关量输出
9
AC_6111_IO_MODE
HANDLE port,
unsigned long board_id,
unsigned long io_mode0,
unsigned long io_mode1
开关量输入/输出口模式设定,可选择作为输入或输出
10
AC_6111_rCounter
HANDLE port,
unsigned long board_id,
unsigned long *counter_data
读计数器数值
11
AC_6111_wCounter
HANDLE port,
unsigned long board_id,
unsigned long counter_data
这是计数器数初值
12
AC_6111_rTimer
HANDLE port,
Unsigned long board_id,
Unsigned long *timer_data
读定时器数值
3.2程序开发指南程序开发基本步骤:
一、加载动态链接库二、获得驱动句柄三、检测AC6111是否存在,获得PCI板卡ID(所有的操作都是通过板卡ID来识别的)
四、选定板卡进行具体操作(可以进行多卡操作)
五、用户自己的应用程序六、退出前关闭驱动,卸载动态链接库
3.4简要例程
Visual C++程序简要说明
#include ".\include\io_nt.h"
#include ".\include\AC6111.h"
HINSTANCE hDLL; //DLL句柄
HANDLE NTportio=NULL; //NT IO驱动 句柄--->暂定为全局变量,自定义时,可以自己传递参数
int main(int argc,char* argv[])
{
char *dll_name="acpci.dll";//动态链接库名
hDLL=LoadLibrary(dll_name); //调入DLL,动态调用
#include ".\include\io_nt_func.h"
#include ".\include\ac6111_func.h"
//-----------------------------------------------------------------
//---------用户程序可以写在下面----------------
unsigned long idd[100];
unsigned long cardc;
NTportio=AC_OpenDriver(); //获取IO驱动句柄
cardc=AC_6111_INIT(NTportio,idd); //获得AC6111卡的数量和卡ID
printf("\n\ncard number=%x\n",cardc);
if(cardc==0){
printf("There is no card(AC6111) in this machine! exit.\n");
getch();
exit(0);
}
int do_data;
unsigned long di_data;
do_data=0xAAAA;
AC_6111_IO_MODE(NTportio,idd[0],0,1);//设置IO模式
printf("AC6111 Digital Out =%X ",do_data);
AC_6111_DO(NTportio,idd[0],do_data); //数字量输出
AC_6111_DI(NTportio,idd[0],&di_data);
printf("\nAC6111 Digital In =%X\n",di_data);//显示数字量输入的值
getch();
AC_CloseDriver(NTportio); //关闭驱动程序
FreeLibrary(hDLL); //关闭DLL
getch();
return 0;
}
Visual Basic程序简要说明
一、首先启动Visaul Basic开发环境;
二、新建一个标准EXE应用;
三、在工程菜单中添加模块,将acpci.bas模块加入(该模块在光盘中\pci\ac6111\vb目录中);
四、接下来可以按照函数说明编写:
1、在通用对象中加入定义
Dim cardid(100) As Long <----定义AC6111卡ID数组
2、在Form_Load中加入如下代码
NTportio = AC_OpenDriver()
注:获得驱动句柄,Ntportio已在模块文件中定义为Global变量
cardnumber = AC_6111_INIT(NTportio,cardid(0))
注:获得AC6111卡的数量和各自的识别ID,按插卡的顺序分别存放在cardid数组中,第一块卡的ID为cardid(0),第二块卡的ID为cardid(1)..依次类推..第N块卡的ID为cardid(n-1)。以后所有的操作都依靠ID来识别具体操作哪块卡。
3、在Form中建立一个CommonButton,名为Command1
在Command1_Click()过程中加入A/D,D/A转换函数,IO函数
Private Sub Command1_Click()
//用户具体程序语句
End Sub
4、在程序退出时,应该在Form_Unload()过程中加入释放驱动句柄的操作,具体程序如下:
AC_CloseDriver Ntportio
五、有关用户其他方面的应用请参考函数说明和例程。
例:
Private Sub Form_Load()
NTportio = AC_OpenDriver() ‘获得驱动句柄
cardnumber = AC_6111_INIT(NTportio,cardid(0))
Form1.Caption = Form1.Caption + " 检测到有 " + Str(cardnumber) + " 块AC6111卡在机器中"
End Sub
Private Sub Form_Unload(Cancel As Integer)
AC_CloseDriver Ntportio ‘关闭驱动
End Sub
4,AC6111 A/D板API使用说明
4.1 通用函数
AC_OpenDriver
HANDLE AC_OpenDriver( void )
功能:打开驱动,获得驱动句柄;
参数:无;
返回:获得的驱动句柄。数据类型为HANDLE。
举例:参考AC_CloseDriver()函数的例子
AC_CloseDriver
int AC_CloseDriver(HANDLE portio)
功能:关闭驱动,释放驱动句柄;
参数:要释放的驱动句柄;
返回:无。
举例:
Visual C++:
HANDLE Temp;
Temp=AC_OpenDriver();
If ( Temp != NULL ) //驱动加载成功
else //驱动加载失败
AC_CloseDriver(Temp); //驱动卸载
Visual Basic:
Global Temp
Temp=AC_OpenDriver() ‘驱动加载
AC_CloseDriver Temp ‘驱动卸载
4.2专用函数
AC_6111_INIT
int AC_6111_INIT(HANDLE port,unsigned long *board_id)
功能:初始化AC6111插卡,获得插卡的数量和识别ID
参数:
port:驱动句柄,类型为HANDLE。此举柄由AC_OpenDriver()获得。
*board_id :AC6111插卡识别ID通过此指针返回,数据类型为unsigned long指针返回:AC6111插卡的数量(比如计算机中有3块AC6111插卡,则返回 3)
举例:
Visual C++:
unsigned long idd[100];//存放板卡识别ID的变量
unsigned long cardc; //存放板卡数量的变量
cardc=AC_6111_INIT(NTportio,idd);//获得AC6111卡的数量和卡ID
printf("\n\ncard number=%x\n",cardc);//显示卡的数量
if(cardc==0){//没找到卡
printf("There is no card(AC6111) in this machine! exit.\n");
}
Visual Basic:
cardnumber = AC_6111_INIT(NTportio,cardid(0))
4.3 AD部分函数
AC_6111_AD
int AC_6111_AD (
HANDLE port,
unsigned long board_id,
int ad_timer,
int start_ch,
int end_ch,
int ps,
int triger_sl,
int clk_sl,
int triger_pol,
int clk_pol,
int sam_mode,
int dif,
unsigned long *Data,
int Size
)
功能:AC6111 A/D 采样
参数:
port :驱动句柄
board_id :要操作的AC6111插卡ID由AC_6111_INIT获得
int ad_timer,//10~65536,4M的时基,每个数表示0.25uS的时间长度
start_ch,//0~15,采样起始通道号
end_ch,//0~15,采样停止通道号
ps,//表示模拟输入的电压范围,用0~3分别表示0~5V、0~10V、±5V、±10V
triger_sl,//触发方式选择,用0/1分别表示软件/硬件触发,0─软件 1─硬件
clk_sl,//采样时钟的选择,0—使用内部时钟 1—使用外部时钟
triger_pol,//触发极性选择0—上升沿触发 1—下降沿触发
clk_pol,//时钟极性选择0—上升沿 1—下降沿
sam_mode,//采样方式选择 0--普通采样模式 1--采样/保持模式
dif,//模拟输入选择0--单端模式,1--差分模式(信号+、信号-、信号地),
此选项是为611x系列兼容考虑,对于AC6111是无意义的;
*Data,//回传的数据缓冲,数据类型是无符号长指针
Size //回传的数据的长度
返回:0—表示采样正确 11—表示参数有误。
下面详细描述数据各二进制位的具体含义:
模拟输入电压与采集数据的换算关系:
由于16位读入数据的高12位为12位采样数据。如下:
D15
D14
D13
D12
D11
D10
D9
D8
AD11
AD10
AD9
AD8
AD7
AD6
AD5
AD4
D7
D6
D5
D4
D3
D2
D1
D0
AD3
AD2
AD1
AD0
IO1
IO0
Trsign
chsign
D15~D0:16位数据的从高到低位。
AD11~AD0:12位采样数据,(MSB - LSB)。
IO1:开关量通道1状态。
IO0:开关量通道0状态。
Trsign:触发标志,=0:没有触发 / =1:触发有效
Chsign:通道标志,=0:数据为起始通道数据 / =1:其他通道的数据。
因此,用户必须将16位FIFO数据(fdata)转换为12位采集数据data,方法如下:
VB:
Data=(fdata and &hfff0)/16
Data=data and &hfff
Io1=fdata and &h8
Io0=fdata and &h4
Trsign=fdata and &h2
Chsign=fdata and &h1
VC:
Data=(fdata>>4) & 0xfff;
Io1=fdata & 0x8;
Io0=fdata & 0x4;
Trsign=fdata & 0x2;
Chsign=fdata & 0x1;
设:A/D读入数据为:data (data=0~4095),对应电压为:
0~5V输入,V=data*5000.0/4095.0 (mV)
0~10V输入,V=data*10000.0/4095.0 (mV)
-5V ~ +5V输入,V=(data-2048)*5000.0/2048.0 (mV)
-10V ~ +10V输入:V=(data-2048)*10000.0/2048.0 (mV)
举例:
Visual C++:
以下是三种电压输入方式、0~7通道、软件触发、采样/保持模式、采集2048点的例子:
//0~5V
printf("sample return=%x\n",AC_6111_AD(NTportio,idd[0],120,0,7,0,0,0,0,0,1,1,data,2048));
for(int ii=0;ii<8;ii++) printf( "%10.3f",((data[ii]>>4))/4095.0*5.0);
//0~10 V
printf("sample return=%x\n",AC_6111_AD(NTportio,idd[0],120,0,7,1,0,0,0,0,1,1,data,2048));
for( ii=0;ii<8;ii++) printf( "%10.3f",((data[ii]>>4))/4095.0*10.0);
//-5~+5 V
printf("sample return=%x\n",AC_6111_AD(NTportio,idd[0],120,0,7,2,0,0,0,0,1,1,data,2048));
for( ii=0;ii<8;ii++) printf( "%10.3f",((data[ii]>>4)-2048)/2048.0*5.0);
Visual Basic:
0~5V
Print Hex(AC_6111_AD(NTportio,cardid(0),120,0,7,0,0,0,0,0,1,0,data1(0),2048))
Print Hex(data1(0)),(data1(0) And &HFFF0&) / 16 / 4095# * 5#; "V"
0-10V
Print Hex(AC_6111_AD(NTportio,cardid(0),120,0,7,1,0,0,0,0,1,0,data1(0),2048))
Print Hex(data1(0)),(data1(0) And &HFFF0&) / 16 / 4096# * 10#; "V"
-5-+5V
Print Hex(AC_6111_AD(NTportio,cardid(0),120,0,7,2,0,0,0,0,1,0,data1(0),2048))
Print Hex(data1(0)),((data1(0) And &HFFF0&) / 16 - 2048) / 2048# * 5#; "V"
4.4 DA部分函数
AC_6111_DA_MODE
int AC_6111_DA_MODE(
HANDLE port,
unsigned long board_id,
unsigned long da_mode0,
unsigned long da_mode1)
功能:AC6111 D/A 输出电压模式的设定
参数:
port :驱动句柄
board_id :要操作的AC6111插卡ID
da_mode0 :DA0输出的电压范围选择(0、1);0:0~10V / 1:(10V
da_mode1 :DA1输出的电压范围选择(0、1);0:0~10V / 1:(10V
返回:0表示操作成功;10表示参数错误
例:
Visual C++:
设两通道都为0~10v输出,设置0通道电压输出为10V
AC_6111_DA_MODE( NTportio,idd[0],0,0 );
AC_6111_DA(NTportio,idd[0],0,4095);
Visual Basic:
AC_6111_DA_MODE NTportio,idd[0],0,0
AC_6111_DA NTportio,idd[0],0,4095
AC_6111_DA
int AC_6111_DA(
HANDLE port,
unsigned long board_id,
unsigned long chn,
unsigned long da_data)
功能:AC6111 D/A 输出参数:
port :驱动句柄
board_id :要操作的AC6111插卡ID
da_mode0 :DA0输出的电压范围选择(0、1);0:0~10V / 1:(10V
da_mode1 :DA1输出的电压范围选择(0、1);0:0~10V / 1:(10V
chn :选择的D/A输出通道(0,1),共两个通道
da_data :D/A输出的数据(0~4095)
返回:0表示操作成功;10表示参数错误。
举例:见AC_6111_DA_MODE函数的距举例。
D/A信号由P1-25脚D型插座输出,模拟输出量程软件设置。输出电压与写入数据关系:
设:D/A写入数据为:data (data=0~4095),对应电压为:
0~10V输出,V=data*10000.0/4095.0 (mV)
即,data=4095*V/10000.0(mV)
-10V ~ +10V输出:V=(data-2048)*10000.0/2048.0 (mV)
即,data=2048+2048*V/10000.0(mV)
注:用户如果输出数据超出了0~4095的范围后,程序自动进行如下处理:
1)data是否大于4095,如果大于,则data=4095。
2)data是否小于0,如果小于,则data=0。
5.1 Visual C++例程:
Visual C++例子程序仅给出的是个WIN32 CONSOLE应用程序,以便与用户参考和使用。用户应该结合自己的实际需要使用。要注意的是在定义一些重要的变量时,应该考虑其有效的作用域,对于在整个程序运行中都需要使用的重要变量,应该定义成全局变量,否则在使用时会导致错误或程序崩溃,计算机死机等意想不到的后果。(比如,dll句柄,IO句柄,PCI卡ID变量等等)
// AC6111.cpp,Defines the entry point for the console application.
#include "stdafx.h"
#include <conio.h>
#include "windows.h" // 应加入的头文件
#include "winioctl.h" // 应加入的头文件
#include <stdio.h>
#include <stdlib.h>
#include <winbase.h>
#include ".\include\io_nt.h"
#include ".\include\AC6111.h"
HINSTANCE hDLL; //DLL句柄
HANDLE NTportio=NULL; //NT IO驱动 句柄--->暂定为全局变量,自定义时,可以自己传递参数
unsigned short ad_data[1000000];
int main(int argc,char* argv[])
{
char *dll_name="acpci.dll";//动态链接库名
hDLL=LoadLibrary(dll_name); //调入DLL,动态调用
if(hDLL!=NULL){
if((int)hDLL<31){
printf("%s未找到!",dll_name);
}else{
printf("%s已调入。",dll_name);
#include ".\include\io_nt_func.h"
#include ".\include\ac6111_func.h"
//-----------------------------------------------------------------
if(AC_OpenDriver==NULL){
printf("\nAC_OpenDriver函数不存在!");
}else{
printf("\nAC_OpenDriver函数存在。");
NTportio=AC_OpenDriver(); //获取IO驱动句柄
if(NTportio==NULL)
{
printf("Drivers is not exist!!!\n");//未成功加载驱动
getch();
FreeLibrary(hDLL);//清DLL句柄
exit(0);//退出
}
if(AC_Version==NULL){
printf("\nAC_Version函数不存在!");
}else{
printf("\nAC_Version函数存在。");
char Version[100];
AC_Version(NTportio,Version);//ok
printf("%s\n",Version);
}
//判断AC6111系列API是否正确加载
if(AC_6111_DI==NULL || AC_6111_DO==NULL ||
AC_6111_DA==NULL ||AC_6111_INIT==NULL ||
AC_6111_AD==NULL || AC_6111_AD_INI ==NULL
|| AC_6111_rTimer == NULL || AC_6111_rCounter== NULL || AC_6111_wCounter== NULL
){ printf("ac6111 函数不存在!\n");
}else{ printf("ac6111 函数 is ok!\n");
//---------用户程序可以写在下面----------------
unsigned long idd[100];
unsigned long cardc;
cardc=AC_6111_INIT(NTportio,idd);//获得AC6111卡的数量和卡ID
printf("\n\ncard number=%x\n",cardc);
if(cardc==0){
printf("There is no card(AC6111) in this machine! exit.\n");
getch();
exit(0);
}
printf("-----------Test IO part!--------------\n");
int do_data;
unsigned long di_data;
do_data=0xAAAA;
AC_6111_IO_MODE(NTportio,idd[0],0,1);//设置IO模式
printf("AC6111 Digital Out =%X ",do_data);
AC_6111_DO(NTportio,idd[0],do_data); //数字量输出
AC_6111_DI(NTportio,idd[0],&di_data);
printf("\nAC6111 Digital In =%X\n",di_data);//显示数字量输入的值
getch();
int temp=0;
printf("-----------Test AD part!--------------\n");
unsigned long data[100000];
/*//AC_6111_AD函数参数说明
HANDLE port,
unsigned long board_id,
int ad_timer,//10-65536
int start_ch,//0-15 起始通道
int end_ch,//0-15 停止通道
int ps,//0-3--0-5V 0-10V ±5V ±10V
int triger_sl,//0-软件方式触发 1--硬件方式触发
int clk_sl,//0--内部采样时钟 1--外部采样时钟
int triger_pol,//0—上升沿触发 1—下降沿触发
int clk_pol,//0—上升沿同步 1—下降沿同步
int sam_mode,//0--普通采样模式 1--采样/保持模式
int dif,//0--单端模式,1--差分模式 为611x系列兼容考虑
unsigned long *Data,//回传的数据缓冲
int Size//回传的数据的长度
*/
for(;;){
//0-5V
printf("sample return=%x\n",AC_6111_AD(NTportio,idd[0],120,0,7,0,0,0,0,0,1,1,data,2048));
for(int ii=0;ii<8;ii++)
//AD采样数据的高12位为有效的电压数据,详细的说明请参阅说明书中的具体说明
printf( "%10.3f",((data[ii]>>4))/4095.0*5.0);
if(kbhit() && getch()==27)break;
//0-10 V
printf("sample return=%x\n",AC_6111_AD(NTportio,idd[0],120,0,7,1,0,0,0,0,1,1,data,2048));
for( ii=0;ii<8;ii++)
//AD采样数据的高12位为有效的电压数据,详细的说明请参阅说明书中的具体说明
printf( "%10.3f",((data[ii]>>4))/4095.0*10.0);
if(kbhit() && getch()==27)break;
//-5--+5 V
printf("sample return=%x\n",AC_6111_AD(NTportio,idd[0],120,0,7,2,0,0,0,0,1,1,data,2048));
for( ii=0;ii<8;ii++)
//AD采样数据的高12位为有效的电压数据,详细的说明请参阅说明书中的具体说明
printf( "%10.3f",((data[ii]>>4)-2048)/2048.0*5.0);
if(kbhit() && getch()==27)break;
}
getch();
printf("-----------Test DA part!--------------\n");
//选择DA的模式和要输出的通道(共2个通道),输出模拟电压
//使用方法请参考说明书中的函数说明
getch();
for(int i=0;i<2;i++){
printf(" DA%d !\n",i);
getch();
printf("0xffff\n");
AC_6111_DA_MODE(NTportio,idd[0],0,0);
AC_6111_DA(NTportio,idd[0],0,4095);
getch();
printf("0x7fff\n");
AC_6111_DA_MODE(NTportio,idd[0],0,0);
AC_6111_DA(NTportio,idd[0],0,2047);
getch();
printf("0x0\n");
AC_6111_DA_MODE(NTportio,idd[0],0,0);
AC_6111_DA(NTportio,idd[0],0,0);
getch();
}
printf("-----------Counter part!--------------\n");
AC_6111_wCounter( NTportio,idd[0],500);//设置计数器初值500
//下面是个测试时使用的模拟方波发生
//用户可以使用IO口发出高低电压,模拟方波脉冲,以便于调试计数器和,定时器
//模拟100次脉冲发生
for(int jj=0; jj<100;jj++){
AC_6111_IO_MODE(NTportio,idd[0],0,1);
AC_6111_IO_MODE(NTportio,idd[0],1,1);
}
unsigned long data1;
printf("rcount return = %d\n",AC_6111_rCounter(NTportio,idd[0],&data1));
printf("500 Counter -100 = %d\n",data1);//读计数器数值
getch();
printf("-----------Timer part!--------------\n");
AC_6111_wCounter( NTportio,idd[0],2);//设置计数器初值2,测量2个脉冲间隔的时间
//模拟10次脉冲发生,实际应用中用户应该自己产生脉冲
for(jj=0; jj<10;jj++){
AC_6111_IO_MODE(NTportio,idd[0],0,1);
AC_6111_IO_MODE(NTportio,idd[0],1,1);
}
//读取定时器的数值,时基为1uS,每个计数相当于1uS
printf("rtimer return = %d\n",AC_6111_rTimer(NTportio,idd[0],&data1));
printf(" %d uS\n",data1);
getch();
}
}
//关闭驱动程序
if(AC_CloseDriver==NULL){
printf("AC_CloseDriver函数不存在!");
}else{
printf("\nAC_CloseDriver函数存在。");
AC_CloseDriver(NTportio);
}
FreeLibrary(hDLL);//清DLL
}
getch();
//return 0;
}
return 0;
}
5.2 Visual Basic例程:
acpci.bas:模块文件
'NT IO DRIVER -------------------------------------------------- W & W lab
Public Declare Function AC_OpenDriver Lib "acpci.dll" () As Long
Public Declare Function AC_CloseDriver Lib "acpci.dll" (ByVal HANDLE As Long) As Long
Public Declare Function AC_Version Lib "acpci.dll" (ByVal HANDLE As Long,Version As Byte) As Long
Public Declare Function AC_inp Lib "acpci.dll" (ByVal HANDLE As Long,ByVal Address As Long) As Long
Public Declare Function AC_inpw Lib "acpci.dll" (ByVal HANDLE As Long,ByVal Address As Long) As Long
Public Declare Function AC_outp Lib "acpci.dll" (ByVal HANDLE As Long,ByVal Address As Long,ByVal data As Long) As Long
Public Declare Function AC_outpw Lib "acpci.dll" (ByVal HANDLE As Long,ByVal Address As Long,ByVal data As Long) As Long
Public Declare Function AC_inps Lib "acpci.dll" (ByVal HANDLE As Long,ByVal Address As Long,data As Byte,ByVal Count As Long) As Long
Public Declare Function AC_inpws Lib "acpci.dll" (ByVal HANDLE As Long,ByVal Address As Long,data As Integer,ByVal Count As Long) As Long
Public Declare Function AC_outps Lib "acpci.dll" (ByVal HANDLE As Long,ByVal Address As Long,output_data As Byte,ByVal Count As Long) As Long
Public Declare Function AC_outpws Lib "acpci.dll" (ByVal HANDLE As Long,ByVal Address As Long,output_data As Integer,ByVal Count As Long) As Long
'-----------PCI CARD ----------------
Public Declare Function AC_6111_INIT Lib "acpci.dll" ( _
ByVal NTportio As Long,_
cardid As Long _
) As Long
Public Declare Function AC_6111_IO_MODE Lib "acpci.dll" ( _
ByVal NTportio As Long,_
ByVal cardid As Long,_
ByVal iomode0 As Long,_
ByVal iomode1 As Long _
) As Long
Public Declare Function AC_6111_DI Lib "acpci.dll" ( _
ByVal NTportio As Long,_
ByVal cardid As Long,_
di_data As Long _
) As Long
Public Declare Function AC_6111_DO Lib "acpci.dll" ( _
ByVal NTportio As Long,_
ByVal cardid As Long,_
ByVal DoData As Long _
) As Long
Public Declare Function AC_6111_DA Lib "acpci.dll" ( _
ByVal NTportio As Long,_
ByVal cardid As Long,_
ByVal chn As Long,_
ByVal DA_DATA As Long _
) As Long
Public Declare Function AC_6111_DA_MODE Lib "acpci.dll" ( _
ByVal NTportio As Long,_
ByVal cardid As Long,_
ByVal da_mode0 As Long,_
ByVal da_mode1 As Long _
) As Long
Public Declare Function AC_6111_rCounter Lib "acpci.dll" ( _
ByVal NTportio As Long,_
ByVal cardid As Long,_
count_data As Long _
) As Long
Public Declare Function AC_6111_wCounter Lib "acpci.dll" ( _
ByVal NTportio As Long,_
ByVal cardid As Long,_
ByVal count_data As Long _
) As Long
Public Declare Function AC_6111_rTimer Lib "acpci.dll" ( _
ByVal NTportio As Long,_
ByVal cardid As Long,_
timer_data As Long _
) As Long
Public Declare Function AC_6111_AD Lib "acpci.dll" ( _
ByVal NTportio As Long,_
ByVal cardid As Long,_
ByVal timer_data As Long,_
ByVal start_ch As Long,_
ByVal end_ch As Long,_
ByVal ps As Long,_
ByVal triger_sl As Long,_
ByVal clk_sl As Long,_
ByVal triger_pol As Long,_
ByVal clk_pol As Long,_
ByVal sam_mode As Long,_
ByVal dif As Long,_
data As Long,_
ByVal size As Long _
) As Long
Global NTportio As Long
ac6111.frm:窗体文件
Dim cardid(20) As Long '卡id数组
Dim TIMERDATA(3) As Long '定时器数据数组
Dim COUNTERDATA(3) As Long '计数器数据数组
Dim data1(100000) As Long 'AD采样数据数组
Dim di_data(2) As Long
Private Sub AC6111_AD_Click()
'函数参数说明
'AC_6111_AD(
' HANDLE port,
' board_id,
' ad_timer,//10-65536
' start_ch,//0-15
' end_ch,//0-15
' ps,//0-3--0-5 0-10 +-5 +-10
' triger_sl,//0-软件 1--硬件
' clk_sl,//0--内部 1--外部
' triger_pol,//0--rise 1--down
' clk_pol,//0--rise 1--down
' sam_mode,//0--普通采样模式 1--采样/保持模式
' dif,//0--单端模式,1--差分模式 为611x系列兼容考虑
' *Data,//回传的数据缓冲
' Size//回传的数据的长度
' )
Print Hex(AC_6111_AD(NTportio,cardid(0),10,0,0,0,0,0,0,0,0,0,data1(0),2048))
Print Hex(data1(0)),(data1(0) And &HFFF0&) / 16 / 4095# * 5#; "V"
Print Hex(AC_6111_AD(NTportio,cardid(0),10,0,0,1,0,0,0,0,0,0,data1(0),2048))
Print Hex(data1(0)),(data1(0) And &HFFF0&) / 16 / 4096# * 10#; "V"
Print Hex(AC_6111_AD(NTportio,cardid(0),10,0,0,2,0,0,0,0,0,0,data1(0),2048))
Print Hex(data1(0)),((data1(0) And &HFFF0&) / 16 - 2048) / 2048# * 5#; "V"
End Sub
Private Sub AC6111_COUNTER_Click()
'计数器计数实例
AC_6111_wCounter NTportio,cardid(0),500 '设置计数器初值为500,并启动计数
'读如计数器数值,如果返回11则表示计数器溢出,数据存储在COUNTERDATA(0)中
AC_6111_rCounter NTportio,cardid(0),COUNTERDATA(0)
Print "count_org="; COUNTERDATA(0) '显示计数器值初值
'-------------发生100个脉冲-----------------------
For i = 0 To 99
AC_6111_IO_MODE NTportio,cardid(0),0,1
AC_6111_IO_MODE NTportio,cardid(0),1,1
Next i
'-------------------------------------------------
AC_6111_rCounter NTportio,cardid(0),COUNTERDATA(0)
Print "count_end="; COUNTERDATA(0) '显示计数器值最终的数值为400
'测频率
AC_6111_wCounter NTportio,cardid(0),2 '设置计数器初值为2,并启动计数
'读如计数器数值,如果返回11则表示计数器溢出,数据存储在COUNTERDATA(0)中
AC_6111_rCounter NTportio,cardid(0),COUNTERDATA(0)
Print "count_org="; COUNTERDATA(0) '显示计数器值初值
'-------------发生5个脉冲--------------------------
For i = 0 To 4 '发生5个脉冲
AC_6111_IO_MODE NTportio,cardid(0),0,1
AC_6111_IO_MODE NTportio,cardid(0),1,1
Next i
'---------------------------------------------------
Print AC_6111_rTimer(NTportio,cardid(0),TIMERDATA(0)) '返回为11则表示定时器溢出
Print "Timer Data="; TIMERDATA(0) '显示定时器的数值,时基是1微秒,按1个数表示1微秒可以计算出时间
End Sub
Private Sub AC6111_DA_Click()
Dim DA_DATA As Long
DA_DATA = &H0 'DA数值0-4095,
AC_6111_DA_MODE NTportio,cardid(0),1,1
'输出一通道,使用+-10v输出
AC_6111_DA NTportio,cardid(0),0,DA_DATA
'输出二通道,使用+-10v输出
AC_6111_DA NTportio,cardid(0),1,DA_DATA
End Sub
Private Sub AC6111_DIO_Click()
AC_6111_IO_MODE NTportio,cardid(0),0,1 '设置0-15通道IO为输入状态,设置8-15通道IO为输出状态
AC_6111_DO NTportio,cardid(0),&HA500 '输出8-15通道&H55
temp = AC_6111_DI(NTportio,cardid(0),di_data(0)) '输入0-15通道
Print "IO 0- 7:"; Hex(temp And &HFF) '显示0-15通道输入的IO值
Print "IO 8-15:"; Hex((di_data(0) And &HFF00) / 256) '显示8-15通道输入的IO值,由于AC6111是可编程IO,因此读输出口数据时,其数值为上次输出的所存的数据
End Sub
Private Sub Form_Click()
Cls
End Sub
Private Sub Form_Load()
NTportio = AC_OpenDriver()
cardnumber = AC_6111_INIT(NTportio,cardid(0))
Form1.Caption = Form1.Caption + " 检测到有 " + Str(cardnumber) + " 块AC6111卡在机器中"
If cardnumber = 0 Then
AC6111_DA.Enabled = False
AC6111_AD.Enabled = False
AC6111_DIO.Enabled = False
AC6111_COUNTER.Enabled = False
End If
End Sub
Private Sub Form_Unload(Cancel As Integer)
AC_CloseDriver NTportio
End Sub
6.1有关编程的几点说明
1、所编程序包括菜单的实现及相关功能,如举例所示,其中功能必须包括数据的采集及保存,波形显示,数据显示、FFT变换、信号周期和频率的自动检测。
2、有关FFT变换的编程,可参看《测试技术与测试信号处理》(吴正毅编,清华大学出版社出版)203页至212页有关内容。
这是同学利用VB设计的一个检测系统界面
北京邮电大学课程设计报告课程设计名称
学 院
指导教师
学生姓名
班 级
学 号
课程设计内容
简要介绍课程设计的主要内容,包括课程设计教学目的、基本内容、实验方法和团队分工等
学生课程设计报告
(附页)
课程设计成绩评定
遵照实践教学大纲并根据以下四方面综合评定成绩:
1、课程设计目的任务明确,选题符合教学要求,份量及难易程度
2、团队分工是否恰当与合理
3、综合运用所学知识,提高分析问题、解决问题及实践动手能力的效果
4、是否认真、独立完成属于自己的课程设计内容,课程设计报告是否思路清晰、文字通顺、书写规范评语,
成绩:
指导教师签名,
年 月 日