用AD5933做的阻抗测量仪设计--带完整程序资料

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

基于AD5933的阻抗测量仪
摘要:设计采用阻抗测量芯片AD5933,以低功耗高性能处理器LUMINARY615作为控制器,利用比例测量,DFT数字解调,软件校准和补偿等技术实现了对阻抗的高精度测量。

通过外接模拟开关并通过软件设计实现了量程自动转换,并能在不同频率下进行测量,能通过良好的人机界面来实时控制与显示。

测试结果表明,在一定范围内测量阻抗的幅值相对误差小于1%,实现了较高精度的阻抗测量。

关键词: 阻抗测量; AD5933 ;自动量程转换;Luminay615
目录1. 系统设计
1.1 设计要求
1.2 方案比较与论证
1.2.1 系统方案比较与论证
1.2.2 系统方案
2. 系统硬件电路设计
2.1 处理器电路设计
2.2 阻抗测量电路设计
2.2.1 AD5933 简介
2.2.2 AD5933工作原理
2.2.4 测量电路
3.软件设计
3.1 开发环境简介
3.2 I2C通行协议简介
3.2 软件设计
4.系统测试
4.1 测试仪器
4.2 测试方法及结果
4.3 误差分析
5.总结
6.参考文献
附录
1.系统设计
1.1设计要求
要求设计一个较高精度的阻抗测量系统,并实现对阻抗的自动测量。

1.2方案论证与比较
1.2.1系统方案比较与论证
方案一:电桥法
电桥法是指在桥式电路的某部分施加一电压,通过调节电桥内部标准,一直到接于电桥电路中的平衡指示器获得平衡指示。

这时,位于电路未知端的器件和电桥电路的其它元件之间存在确定关系。

一般来说,电桥法是传统阻抗测量中准确度最高方法,特别适于中值阻抗的测量。

测量原理如图1.1所示。

图1.1 电桥电路原理图
图1.1中Z1,Z2,Z3,Z4为电桥的四臂的阻抗,E为电桥的信号源,G为电桥的平衡指示器。

当电桥桥路平衡时,Uab=0,桥路平衡指示器上无电流流过,根据基尔霍夫定律,
I1=I2,I3=I4,
Uca=Ucb,Uad=Ubd。

故I1Z1=I3Z3;I2Z2=I4Z4;以上两式相比得:Z1/Z2=Z3/Z4。

这就是四臂电桥平衡的条件,当桥路中有3个桥臂为已知时,则未知量才可求得。

因为阻抗包含电阻分量和电抗分量,在调节已知阻抗使电桥达到平衡时,至少需要调节两个。

在直流电桥中,因为各臂皆由纯电阻组成,故不需要考虑相位问题。

对于交流电桥,各臂阻抗都等效为电阻分量和电抗分量。

为了使电桥的平衡调节简单化,这两个调节阻抗元件的选择是非常重要的。

最理想的调节参数是能够分别平衡被测阻抗中的电阻分量和电抗分量。

因为阻抗电桥平衡的调节和相应的计算极为复杂,所以测量操作繁琐、费时,且测量范围受限,这给测量带来极大不便。

方案二:谐振法
谐振法是用电感和电容组成的串联或并联谐振电路,通过电压表或电流表来确定谐振点,而进行阻抗测量的一种方法。

这种方法常用于测量电抗成分与电阻成分之比很大,并组成串联或并联电路的阻抗。

图1.2为一谐振电路,当被测元件Cx 未连接时,电路谐振频率为:
( C 0 为谐振时可调电容值)
图1.2 谐振法测量阻抗
当Cx 接入后,保持f 值不变,调节电容C 的值使电路重新谐振,设此时C 的值为C2,则
Cx=C0-C2
谐振法通常是测定回路的参量,而不是单个元件的参量。

如果要用谐振法测定单个元件参量,只有在其它回路元件为已知或者它们对于回路的作用可以不予考虑的情况下才能实现,所以,谐振法不能用作高准确度阻抗测量,但谐振法具有宽频带 (1kHz 至1000MHz),操作简单,适合于高Q 元器件测量。

方案三:矢量电压电流法
矢量电压电流法是将测试信号电压加到被测件,测量信号电流流过被测件,然后由电压和电流之比计算测试端的阻抗。

这种方法可用多端测量结构,在电路中消除残余阻抗的影响同时测量电路比较简单、量程宽。

电桥电路不需要使用通常的平衡控制,所以便于高速测量且操作容易。

其工作原理如图1.3所示:
R
Z X
V 1
V 2
I
图1.3 矢量电压电流法
由精确的电阻R 值便可实现阻抗的测量,容易得到下式:
R V V I V Z X 2
1
1==
以上三种方案各有优缺,通过比较,结合设计要求,采用基于矢量电压电流法的阻抗测量芯片AD5933来实现阻抗测量,能达到高精度,高稳定度的要求,且容易实现。

1.3 系统方案
系统通过Luminary615作为控制器,对AD5933内部寄存器读写从而控制阻抗测量,外接模拟开关以实现不同量程范围内阻抗的测量。

AD5933芯片内部集成了内置温度传感器,数模转换器和模数转换器,频率发生器.扫描激励信号通过被测物后,再经过放大、滤波、模数转换,使其变为数字信号后经过DFT 变换得到阻抗实部值与虚部值,通过与Luminary615进行I2C 通信便可实现数据处理最终实现阻抗测量。

系统设计框图如图1.4所示。

图1.4 系统框图
2. 硬件电路设计
2.1 处理器电路设计
Luminary Micro Stellaris®系列微控制器是首款基于ARM® CortexTM -M3 的控制器,它将高性能的32 位计算引入到对价格敏感的嵌入式微控制器应用中。

这些堪称先锋的器件,价格与8 位和16 位器件相同,却能为用户提供32 位器件的性能,并且所有器件都是以小型封装的形式提供。

Stellaris 系列的LM3S615微控制器拥有ARM 微控制器所具有的众多优点,如拥有广泛使用的开发工具,片上系统(SoC )的底层结构IP 的应用,以及众多的用户群体。

此外,控制器还采用了ARM 可兼容Thumb®的Thumb-2 指令集来降低内存的需求量,进而降低成本。

Luminary615最小系统电路图见附录图1.1。

2.2 阻抗测量电路设计
2.2.1 AD5933 芯片简介
AD5933是一种高精度阻抗数字直接变换系统,主要由一个12位、1MSPS的片上频率发生器和一个片上模拟数字转换器(ADC)组成。

频率发生器可以产生特定频率的信号激励外部复阻抗。

复阻抗的响应信号由片上模数转换器ADC采样后,再通过片上上数字信号处理器进行离散傅立叶变换(DFT)。

在每个输出频率,DFT运算处理后都会返回一个实值(R)和虚值(I)。

校正后,扫频轨迹上的每个频点的阻抗幅值和阻抗相对相位很容易计算。

图2.1给出了AD5933的封装图,表2.1给出了AD5933的引脚定义。

图2.2为AD5933内部框图。

建议在使用时把所有的电源脚9、10、11都连到一起,统一连接到电源上,同样所有的地引脚12、13、14也都连接到一起,统一连接到系统地上。

图2.1 AD5933引脚排列
表2.1 AD5933引脚定义
图2.2 AD5933内部框图
2.2.2 AD5933工作原理
用AD5933来实现阻抗测量,这种测量方法实质上是一种软测量方法,即在待测变量难于直接测量的情况下,进行与之相关的易测变量的测量,并依据易测变量与待测变量之间的数学关系,建立数学模型,运用各种数学计算和估计方法,实现待测变量的测量[10]。

AD5933有一个电压输出引脚Vout (图2.2)。

它能发出一定频率的正弦扫描信号对外部阻抗 Z(ω) 进行激励。

信号通过被测样品后,再经放大、滤波后被模数转换器取样,并进行离散傅立叶变换,最终计算出待测阻抗值。

AD5933是通过芯片内部的DDS(直接数字合成器)来产生正弦扫描信号,该信号具有小于1Hz的分辨率。

为DDS提供时钟频率的,既可以是外部时钟,也可以是内置的振荡器,可通过软件进行设置。

DDS合成的信号经过数模转换和放大后,即可变为测试需要的扫描激励信号。

该正弦激励信号有四个幅值可供选择,其值分别为2v,1v,400mv,200mv。

而这些信号的起始频率,频率的增加量,和增加的次数,必须预先确定,它们都可通过软件进行设定。

扫描激励信号通过被测物后,再经过放大、滤波、模数(AD)转换,使其变为数字信号。

在这个过程中,反馈电阻RFB的选取至关重要,必须保证输入到AD转换器的电压,即Vout×(Rf / Z)×PGA(放大倍数),既不能超过模数转换器的最大电压,也不能太小(见图1)。

这是因为电压太大AD转换器则会饱和,从而使信号失真。

太小信号所含信息又不能够被充分利用。

这两种情况都会使AD转换器不能工作在线性区域。

我们必需通过选取合适的反馈电阻Rf,使Vout×(Rf / Z)×PGA的数值处在一个适当的范围内以避免上述情况发生。

AD转换器输出的数字信号,直接进入数字信号处理器进行离散傅立叶变换(DFT),傅立叶变换在每
个扫描频率点上进行,其公式如下:
()()()()()()∑=-
=
10230
sin cos n n j n n x f X
其中f 是扫描点的频率,x(n)是AD 转换器输出值,而cos(n)和sin(n)是在频率f 下由DDS 计算产生。

计算的结果
()
X f 一般是一个复数。

它的实部用R ,虚部用I 来表示。

这些就是
我们建立被测阻抗数学模型所需的易测变量值。

以下是详细计算过程。

(1) 幅值计算
阻抗测量的第一步是在每个扫频点,计算傅里叶变换的幅值,计算公式如下: 幅值=
22I R +
上式中R 为存储在地址为0x94和0x95寄存器中的实数;I 为存储在地址为0x96和0x97寄存器中的虚数(注)。

例如:实数寄存器中的十进制数值为907,虚数寄存器中的十进制数值为516,则幅值= 2
2516907+ =1043.506。

(2) 增益系数计算
增益系数的计算是在VOUT 引脚和VIN 引脚之间连接一个未知阻抗,进行系统校准计算完成的。

该系数被确定后便可以测量计算任何阻抗值。

下面是一个计算增益系数的例子:假设输出激励电压为2V (峰峰值),校正阻抗值为200K ,PGA 放大倍数是1倍,电流电压转换放大器增益电阻为200K ,校正频率为30KHz 。

该频点经DFT 转换后实数和虚数寄存器中的内容为:
实数寄存器=0xF064=-3996; 虚数寄存器=0x227E=8830 ;
幅值= =9692.106
增益系数=
= (1/200K)/9692.106=515.819×10-12
下面再给出一个已知增益系数、被测电阻的实部和虚部值计算被测电阻阻值的例子。

假设被测电阻为510k Ω,激励频率为30kHz ,测量得到的实部和虚部值分别为-1473和3507,则计算得到的模值为3802.863。

阻抗值=
=1/(515.819E-12×3802.863) =509.791k Ω。

对于不同的测量频率点增益系数是不同的,所以在不同的频率点上要分别计算增益系
22)8830()3996(+-幅值
校正阻抗值1⨯增益系数幅值1⨯
数。

在测量过程中可以通过限制电阻的测量范围来优化测量性能。

(3)相角计算及校准
在阻抗测量过程中不仅仅要关注电阻的模值,还要知道相角的大小,相角值=arctanI/R。

和模值一样相角也要进行校准。

首先对标定电阻进行测量,得到标定电阻的相角,测量电阻的实际相角等于测量计算得到的值减去标定电阻的相角值。

值得注意的是测量时通过arctanI/R得到的相角是在-90º到+90º之间的,所以要根据R和I所决定的象限来把相角变换到所在象限内。

如果R<0,I>0则说明在第二象限,所以计算时要把相角加上180º;如果R<0,I<0则是在第三象限,计算时要把相角减去180 º。

2.2.4 测量电路
电路由3.3V稳压器Lm1117提供电源,为实现不同量程范围内阻抗的测量,外接模拟开关CD4051来实现量程转换。

电路原理图见附录图1,图2所示。

由于外接模拟开关的导通电阻在300Ω左右,通过测试,当采用运放来实现小阻抗测量时,效果并不明显,故该电路中没有采用运放来实现小阻抗测量。

3. 软件设计
3.1编程环境介绍
基于ARM公司最新内核Cotex-M3 的Luminary615处理器,可以采用IAR编程环境,IAR编程环境风格简易方便,功能齐全,支持JTAG仿真。

IAR EWARM Embedded Workbench for ARM 是IAR Systems 公司为ARM 微处理器开发的一个集成开发环境(下面简称IAR EWARM)。

比较其他的ARM 开发环境,IAR EWARM 具有入门容易、使用方便和代码紧凑等特点。

EWARM 中包含一个全软件的模拟程序(simulator)。

用户不需要任何硬件支持就可以模拟各种ARM 内核、外部设备甚至中断的软件运行环境,从中可以了解和评估IAR EWARM 的功能和使用方法。

3.2 I2C通行协议简介
控制AD5933是通过支持串行接口协议的I2C总线完成的,AD5933作为一个由主控设备控制的从设备连接到总线上。

AD5933有一个7位串行总线从地址。

当设备通电后,默认的串行总线地址为0001101(0x0D)。

图3.1给出了I2C接口一般读写操作的时序图。

主设备先进行传输数据初始化,包括:建立一个起始条件,定义串行数据线为自高位到低位传输,串行时钟线保持为高电平时,数据
流传送。

从设备响应起始条件,传送一个8位数据,其中包括7位从地址和一个决定数据传输方向的读写控制位,即数据是由从设备读取或写入(0:写入,1:读取)。

图3.1 I2C控制时序图
在第九个时钟脉冲的前一个低电平时刻,从设备将数据线的电位拉低(称为应答信号)并在该时钟脉冲的高电平阶段保持为低。

所选设备等待数据进行读取或写入,而总线上的其他所有设备保持空闲状态。

如果读/写位为0,那么主机内容写入从器件。

如果读/写位为1,主机由从器件读取数据。

串行总线上的数据传送在九个时钟脉冲后传送一个序列,包括八位数据位,一个应答信号位。

这数据可以是主设备发出的,也可以使从设备发出的。

数据线上的数据传送是在时钟信号为低并保持稳定的时刻进行的,因为当时钟信号为高电平时,若一个上升沿出现,则该信号为停止信号。

如果该操作是一个写操作,从地址的第一数据字节,是一个指令字节。

该字节会通知从器件接下来的工作是什么。

它可能是一个指令,告诉从器件进行块写操作;也可以是一个寄存器地址,告诉从器件随后的数据将写入什么地方。

因为数据流被定义为一个单方向的读/写位,从设备在读操作事是不可能向其发送指令的。

在执行读操作之前,有时需要先进行写操作告诉从存储器读操作的类型,或数据读取的地址。

当所有字节数据读或写完毕后,会建立停止条件。

写模式下,在第十个时钟脉冲声明停止条件期间,主设备将数据线电位拉高。

读模式下,在第九个时钟脉冲之前的低电平段,主设备释放数据线的占用,但从设备并不会把它拉低,这就是所谓的非应答。

在第十个时钟脉冲之前的低电平段,主设备把数据线电位拉低,然后在第十个时钟脉冲到来时又将其拉高,以形成停止条件。

3.3 软件设计
AD5933是I2C接口的器件,满足I2C控制条件,LM3S615通过I/O口模拟I2C协议实现对AD5933的读写操作,通过参数修正便可以得到正确的结果,通过对CD4051的控制,实现了量程自动转换。

系统主程序设计流程图如图3.2所示,图3.3中给出单个阻抗测量软件流程图。

测量后得到的实部和虚部结果都是十六进制表示。

通过I2C通信将数据传至Luminary615进行处理并由
Luminary615控制,辅以良好的人机界面,可方便操作。

具体程序详见附录3.
图3.2 系统设计流程图
图3.3 单个阻抗测量过程软件流程图
4. 系统测试
4.1测试仪器
数字万用表:UT39A.
4.2测试方法与结果
在特定频率下,将电阻、电容等串并联接到测试端,从液晶读出阻抗幅值与相位并记录下来,再通过数字外用表测量其值并计算出阻抗实际值。

比较测量值与实际值的大小,计算出误差并进行分析。

通过测试,部分结果如表4.1、表4.2及表4.3所示,此处测试激励源频率为2KHZ,激励
信号幅值设定为2V。

误差计算公式为:
%
100
*|
实际值
实际值
测量值
|
表1 电阻测量结果
备注,测量电阻时无相位误差。

4.3 误差分析
测量结果表明,对电阻的测量是比较精确的,大电阻范围内精度在1%以内,由于测量小电阻时模拟开关的导通电阻较大,故测量结果误差较大。

另外,元器件的阻值本身便有一定误差,在测量电容时尤其能体现出。

电阻与电容的串并联测量结果表明,阻抗幅值误差在10%以内,相位误差也从2%~10%不等。

一方面电容的器件误差本身比电阻大,不同大小电容间误差大小也不同,另一方面频率对电容的影响大,对结果也有影响。

在电感测量中,由于实验室电感值较小,阻抗值处在小范围内,测量误差较大。

5. 结论
该设计采用阻抗测量芯片AD5933实现阻抗测量,外围电路简单,测试结果表明,通过Luminary615微控制器控制AD5933测量精度高,稳定性好。

设计中,标定阻抗的选取对精度有很大影响,且软件算法对测量值的校准也非常重要。

该设计实现了阻抗量程的自动转换,总体测试良好。

6.参考文献
[1]/static/imported-files/data_sheets/AD5933.pdf
[2]崔传金,郭志强,赵楠,左月明.用AD5933实现电导率测量的研究,机电工技术,2008.37(4)
[3] 高吉祥.全国大学生电子设计竞赛培训系列教程[M].北京:电子工业出版社,2007.12
附录一元器件清单
附表1
元件型号标号数量
电容104
C1, C3, C5,
C31
4
电解电容100U C2 1 电解电容10U C4 1 磁珠L1, L3 2 发光二极管LED L2 1
插针
P1, P4 ,P2, P3,
P5
5
电阻300 R1 1
电阻10K R2, R3 2
电阻510 R4 1
电阻200 R5 1
电阻1K R6 1
电阻10K R7 1
电阻100K R8 1
电阻220K R9 1
电阻1M R12 1
芯片Lm1117 U1 1
芯片CD4051 U2 1
芯片AD5933 U6 1 附录二原理图以及PCB图
附图1 AD5933 pack板原理图
附图2 AD5933阻抗测量原理图
附图3 阻抗测量底座PCB底层附图4 阻抗测量底座PCB丝印层
附图5 AD5933pack 板 PCB 顶层
8
76543218
7
6
5
4
3
2
1
附图6 AD5933pack 板 PCB 丝印层
附图7 Luminary615 最小系统PCB顶层图
附图8 Luminary615 最小系统PCB底层图
附图9 Luminary615 最小系统图
附录三程序清单
/****************************************************************************** ************************
**文件名:xiangwei.c
**功能:通过LM3S615实现对AD5933的控制,实现阻抗测量
**说明:AD5933是I2C接口的,LM3S通过模拟I2C接口实现对AD5933的控制。

******************************************************************************* *************************/
#include "VI2C_LM3S101.H"
#include "hw_ints.h"
#include "hw_memmap.h"
#include "hw_types.h"
#include "gpio.h"
#include "interrupt.h"
#include "sysctl.h"
#include "12864.h"
#include "ZLG7290.h"
#include "math.h"
#include "7290moni.h"
#ifndef uchar
#define uchar unsigned char
#endif
// I2C引脚的定义。

#define SDA GPIO_PIN_3 // 模拟I2C数据传送位
#define SCL GPIO_PIN_2 // 模拟I2C时钟控制位
#define SDAA GPIO_PIN_5 //模拟I2C数据传送位
#define SCLL GPIO_PIN_4 //模拟I2C时钟控制位
#define AD5933_addr 0x1A //从机地址
#define SET_POINT 0xB0 //0xB0命令表示写入地址
unsigned char j=0;
//---------------------------------------------------------------------------------------------------------------------
// 函数原形:void delays(unsigned int n)
// 功能描述:延时数量为n个指令周期。

// 参数说明:unsigned int n,将要延时的时间数。

// 返回值:无
//---------------------------------------------------------------------------------------------------------------------
void delays(unsigned int n) // 软件延迟函数
{
volatile int i;
for(;n>0;n--)
{
for(i=0;i<10;i++);
}
}
//---------------------------------------------------------------------------------------------------------------------
// 函数原形:InitAD5933(void)
// 功能描述:AD5933初始化函数。

// 参数说明:无。

// 返回值:无
//---------------------------------------------------------------------------------------------------------------------
void InitAD5933(void)
{
ISend(AD5933_addr,0x82,0x00); //start frequency起始频率
delays(5);
ISend(AD5933_addr,0x83,0xFA); //1kHz
delays(5);
ISend(AD5933_addr,0x84,0x05);
delays(5);
ISend(AD5933_addr,0x85,0x00); //increment frequency频率增量
delays(5);
ISend(AD5933_addr,0x86,0x31); //500Hz
delays(5);
ISend(AD5933_addr,0x87,0x81);
delays(5);
ISend(AD5933_addr,0x88,0x01); //测量点数
delays(5);
ISend(AD5933_addr,0x89,0xFF);
delays(5);
ISend(AD5933_addr,0x80,0xB1); //标准模式
delays(5);
ISend(AD5933_addr,0x81,0x00); //选着内部时钟
delays(5);
ISend(AD5933_addr,0x81,0x10); //复位AD5933
delays(5);
ISend(AD5933_addr,0x81,0x00);
delays(5);
ISend(AD5933_addr,0x80,0x11); //初始化频率
delays(5);
ISend(AD5933_addr,0x8A,0x03); //等待建立周期数
delays(5);
ISend(AD5933_addr,0x8B,0xFF);
delays(5);
ISend(AD5933_addr,0x80,0x21); //启动频率扫描
delays(5);
}
//---------------------------------------------------------------------------------------------------------------------
// 函数原形:void display(unsigned int re,unsigned int im)
// 功能描述:显示函数。

// 参数说明:unsigned int re,unsigned int im ,实部和虚部
// 返回值:无
//---------------------------------------------------------------------------------------------------------------------
void display(signed int re,signed int im)
{
unsigned char a[11],y=0,x=0,i=0;
signed int revalu=0,imvalu=0;
float valu=0;
double xishu=0,regist;
long int ll;
revalu=re;
imvalu=im;
if(revalu&0x8000) //把带符号的换算成无符号整数
{
revalu=(revalu-0x10000)*(-1);
x=1;
}
if(imvalu&0x8000) //把带符号的换算成无符号整数
{
imvalu=(imvalu-0x10000)*(-1);
y=1;
}
valu=sqrt(imvalu*imvalu+revalu*revalu); //计算幅值
switch(j)
{
case 0:
if((valu<13000)&&(valu>8000))
{
xishu=(1/(96.86810)); //计算系数
xishu=(1/(xishu*valu))*100000+0.5; //计算阻值
ll=xishu-250;
i=1;
}
break;
case 1:
if((valu<13000)&&(valu>1350))
{
xishu=(1/(13.33726)); //计算系数
xishu=(1/(xishu*valu))*1000000+0.5; //计算阻值
ll=xishu-100;
i=1;
}
break;
case 3:
if((valu<12000)&&(valu>1050))
{
xishu=(1/(10.398994)); //计算系数
xishu=(1/(xishu*valu))*10000000+0.5; //计算阻值
ll=xishu;
i=1;
}
break;
case 4:
if((valu<12000)&&(valu>1000))
{
xishu=(1/(96.736596)); //计算系数
xishu=(1/(xishu*valu))*10000000+0.5; //计算阻值
ll=xishu;
i=1;
}
break;
case 5:
if((valu<2130)&&(valu>1060))
{
xishu=(1/(21.006)); //计算系数
xishu=(1/(xishu*valu))*100000000+0.5; //计算阻值
ll=xishu;
i=1;
}
break;
case 6:
if((valu<4800)&&(valu>800))
{
xishu=(1/(96.527914)); //计算系数
xishu=(1/(xishu*valu))*100000000+0.5; //计算阻值
ll=xishu;
i=1;
}
break;
default:
break;
}
if(i==1) //满足条件则显示阻值,相位
{
a[0]=ll/10000000+48;
a[1]=ll%10000000/1000000+48;
a[2]=ll%1000000/100000+48;
a[3]=ll%100000/10000+48;
a[4]=ll%10000/1000+48;
a[5]='.';
a[6]=ll%1000/100+48;
a[7]=ll%100/10+48;
a[8]=ll%100%10+48;
a[9]='K';
a[10]=0;
LCD_WriteStr(4,2,a);
regist=ll;
if((y==0)&&(x==0))
{
//计算并显示atan2(float y, float x); 求y/x(弧度表示)的反正切值xishu=atan2(imvalu,revalu)*180/3.14+0.5;
}
if((y==1)&&(x==0))
{
//计算并显示atan2(float y, float x); 求y/x(弧度表示)的反正切值xishu=atan2((imvalu*(-1)),revalu)*180/3.14-0.5;
xishu=xishu+180;
}
if((y==1)&&(x==1))
{
//计算并显示atan2(float y, float x); 求y/x(弧度表示)的反正切值
xishu=atan2(imvalu,revalu)*180/3.14+0.5;
xishu=xishu+180;
}
if((y==0)&&(x==1))
{
xishu=atan2(imvalu,(revalu*(-1)))*180/3.14-0.5; //计算并显示atan2(float y, float x); 求y/x(弧度表示)的反正切值
xishu=xishu+360;
}
if((ll<1000)&&(ll>400)) //相位误差修正
ll=xishu-89.5;
if((ll<10000)&&(ll>=1000))
ll=xishu-(-0.0012237*regist+91.46)+0.5;
if((ll<100000)&&(ll>=10000))
ll=xishu-(-0.0001515*regist+91.016)+0.5;
if((ll<1000000)&&(ll>=100000))
ll=xishu-(-0.0000179*regist+91.806)+0.5;
if((ll<=2000000)&&(ll>=1000000))
ll=xishu-(-0.000009675*regist+93.789)+0.5;
if((ll<12000000)&&(ll>2000000))
ll=xishu-(-0.00000256*regist+95.444)+0.5;
if(ll<0) //判断正负
{
ll=ll*(-1);
a[0]='-';
a[1]=ll/100+48;
a[2]=ll%100/10+48;
a[3]=ll%100%10+48;
a[4]=0;
LCD_WriteStr(4,3,a);
}
else
{
a[0]=' ';
a[1]=ll/100+48;
a[2]=ll%100/10+48;
a[3]=ll%100%10+48;
a[4]=0;
LCD_WriteStr(4,3,a);
}
}
//---------------------------------------------------------------------------------------------------------------------
// 函数原形:ReadData(unsigned char addr)
// 功能描述:读数据函数。

// 参数说明:unsigned char addr 子地址
// 返回值:数据
//---------------------------------------------------------------------------------------------------------------------
unsigned int ReadData(unsigned char addr) //读数据
{
unsigned int data_a;
ISend(AD5933_addr,SET_POINT,addr);
delays(5);
data_a=IRcv(AD5933_addr);
delays(5);
return data_a;
}
//---------------------------------------------------------------------------------------------------------------------
// 函数原形:void wendu(void)
// 功能描述:温度测量函数。

// 参数说明:无。

// 返回值:无
//---------------------------------------------------------------------------------------------------------------------
void wendu(void)
{
unsigned char Status,a[3];
unsigned int Tm;
//复位AD5933
ISend(AD5933_addr,0x81,0x10);
delays(5);
ISend(AD5933_addr,0x81,0x00);
delays(5);
//启动温度测量
ISend(AD5933_addr,0x80,0x91);
delays(5);
//等待转换完成
{
Status=ReadData(0x8F);
}while(!(Status & 0x01));
Tm=ReadData(0x92);
Tm<<=8;
Tm+=ReadData(0x93);
Tm=Tm&0x3FFF;
Tm=Tm/32; //温度换算并且显示
a[0]=Tm%100/10+48;
a[1]=Tm%100%10+48;
a[2]=0;
LCD_WriteStr(4,1,a);
}
//---------------------------------------------------------------------------------------------------------------------
// 函数原形:void sweepfre(void)
// 功能描述:测量函数
// 参数说明:无。

// 返回值:无
//---------------------------------------------------------------------------------------------------------------------
void sweepfre(void)
{
unsigned char Status=0,count;
signed int Re=0,Im=0;
InitAD5933(); //初始化AD5933
do
{
Status=ReadData(0x8F);
}while(!(Status & 0x02));
//读回阻抗的实部
Re=ReadData(0x94);
delays(5);
Re=Re<<8;
Re+=ReadData(0x95);
delays(5);
//读回阻抗的虚部
Im=ReadData(0x96);
delays(5);
Im=Im<<8;
Im+=ReadData(0x97);
delays(5);
display(Re,Im);
}
//--------------------------------------------------------------------------------------------------------------- // 函数原形:int main(void)
// 功能描述:主函数。

// 参数说明:无。

// 返回值:无
//--------------------------------------------------------------------------------------------------------------- int main(void)
{
unsigned char data;
// 设置晶振为系统时钟
SysCtlClockSet(SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
SYSCTL_XTAL_6MHZ);
// 使能本例所使用的外设。

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
// 配置相关引脚,以进行I2C操作,初始化LED指示灯。

GPIODirModeSet(GPIO_PORTB_BASE, SDA | SCL | SDAA| SCLL,GPIO_DIR_MODE_OUT);
GPIODirModeSet(GPIO_PORTD_BASE, SDAye | SCLye | CSye|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7, GPIO_DIR_MODE_OUT);
lcdInit(); //液晶初始化
LCD_WriteStr(1,1," 温度:");
LCD_WriteStr(1,2,"幅值:");
LCD_WriteStr(1,3,"相位:");
LCD_WriteStr(6,3,"度");
LCD_WriteStr(5,1,"度");
while(1)
{
wendu(); //测量温度
for(j=0;j<7;j++)
{
if(j==2)
continue;
GPIOPinWrite(GPIO_PORTD_BASE,0xe0, j<<5); //选着通道
sweepfre(); //扫描并计算阻抗
}
}。

相关文档
最新文档