C题:锁定放大器的设计
摘 要:本设计对于检测微弱信号的锁存放大器进行论述,锁定放大器主要包括交流放大器、带通滤波器、相敏检波器、低通滤波器、直流放大器及液晶显示等几个部分。其中,交流放大器以INA128为主要构成部件,实现交流信号的放大从而作为带通滤波器的输入;带通滤波器用UAF42构成,实现对900Hz到1100Hz频带范围的滤波过程,其误差小于20%;相敏检波器的主要部件采用乘法器MPY634,得到的信号在输入低通滤波器经直流放大器放大后输入显示电路,显示出被测信号的幅度及有效值。另外,在相敏检波器部分的方波驱动信号由参考信道的参考信号经触发整形、移相、比较而来。同时,为了更好的检测出锁定放大器的性能,在信号的输入端增加加法器电路,实现被测信号与干扰信号的1:1叠加,当干扰信号的频率为1050Hz—2100Hz时,输出端的测量误差小于10%。锁定放大器在实际应用中用途广泛,尤其对于微弱信号检测方向站着主导地位,随着科技的发展已渐渐的融入人类的生活之中,拥有很好的发展前景。
关键词:带通滤波器;相敏检波器;显示;方波驱动
1 总体方案设计
1.1 方案比较与选择
1.1.1 微弱信号检测模块方案比较
方案一:采用滤波电路检测微弱信号,通过滤波电路将微弱信号从强噪声中检测出来,但滤波电路中心频率是固定的,而信号的频率是可变的,无法达到要求,由此可见该方案不满足要求。
方案二:采用取样积分电路检测小信号,采用取样技术,在重复信号出现的期间取样,并重复N次,则测量结果的信噪比可改善√N倍,但这种方法取样效率低,不利于重复频率的信号恢复。
方案三:采用锁相放大器检测小信号,锁相放大器由信号通道、参考通道和相敏检波器等组成,其中相敏检波器(PSD)是锁相放大器的核心,PSD把从信号通道输出的被测交流信号进行相敏检波转换成直流,只有当同频同相时,输出电流最大,具有良好的检波特性。由于该被测信号的频率是指定的且噪声强、信号弱,正好适用于锁相放大器的工作情况,故选择方案三。
1.1.2 移相网络模块方案比较
方案一:数字法:采用数字相移的方法势必增加电路的难度,所以此法不可取。
方案二:模拟法:由于电路用的是锁相放大,所以要保持输入信号相位的一致,故需要对参考信号做移相处理,移相采用简单的RC电路搭成,可以很容易得到所需效果。所以采用方案二。
1.1.3 电阻分压模块方案比较
电阻分压网络有串联分压和π型网络,π型网络的性能较好,适合在高频的条件下工作,而本设计要求的电压范围较小,故采用简单电路串联来作为分压网络就可以达到要求。
1.1.4 显示模块方案
方案一:采用数码管显示。数码管只能显示简单的数字,其电路复杂,占用资源较多,显示信息少,不宜显示大量信息。
方案二:采用液晶显示。液晶显示增加了显示信息的可读性,看起来更方便。而QC12864B字符点阵液晶模块有明显的优点:微功耗、尺寸小、显示信息量大、显示清晰、易控制,抗干扰能力强。
1
选择方案二,用液晶显示所需的数据,显示的信息量大而且方便。
1.2 总体方案论述
对于幅度较小的直流信号或满编信号,为了防止1/f噪声和直流放大的直流漂移(例如运算放大器输入失调电压的温度漂移)的不利影响,一般都使用调制器或斩波器将其变换成交流信号后,在进行放大和处理,用带通滤波器抑制宽带噪声,提高信噪比,之后再进行解调和低通滤波,以得到放大了的被测信号。对于微弱的直流和慢变信号,调制后的正弦信号也必然微弱。要达到足够的信噪比,用于提高信噪比的带通滤波器的带宽必须非常窄,Q值必须非常高,这在实际上往往很难实现。而且Q值太高的带通滤波器往往不稳定,温度、电源电压的波动均会是滤波器的中心频率发生变化,从而导致其通频带不能覆盖信号频率,使得测量系统无法稳定可靠地进行测量。在这种情况下,利用锁定放大器可以很好地解决上述问题。
本设计为制作一个用来检测微弱信号的锁定放大器。首先,交流放大器部分采用INA128作为主要部件,将信号放大后输入带通滤波器,带通滤波器由UAF42构成,可以实现950Hz到1050Hz频带范围的滤波过程,其误差小于10%;然后,带通滤波后的信号和同频同相的方波参考信号送入乘法器,乘法器采用MPY634;再者,乘法器输出的信号送入低通滤波器,再经直流放大器放大后,由显示电路显示出被测信号的幅度有效值。另外,在相敏检波器部分的方波驱动信号由参考信道的参考信号经触发整形、移相、比较而来。同时,为了更好的检测出锁定放大器的性能,在信号的输入端增加加法器电路,实现被测信号与干扰信号的1:1叠加,当干扰信号的频率为1050Hz—2100Hz时,输出端的测量误差小于10%。
1.3 锁定放大器的流程框图
锁定放大器的流程框图如图1.1所示,主要由交流放大器、带通滤波器、相敏检波器、低通滤波器、直流放大器、触发整形、移相器及方波驱动等模块构成。
参考 R(t) S(t) 信号 信号通道 交流放大器 带通滤x(t) 波器 相敏检波器 r(t) 方波驱动 输出 低通滤波器 直流放大器 显示 参考通道 触发整形 移相器 图1.1锁定放大器的流程框图
2
1.4 总体电路图
总体电路图如图1.2所示。
3
2 各部分指标的分析与计算
2.1 交流放大器
交流放大器部分采用INA128三级同相放大电路放大。根据公式GB=1+50K/R,第一级放大16倍,第二级放大为26倍,第三级放大为26倍,三级相乘最终的放大倍数可达10816倍,满足设计要求;由此每一级的电阻选择分别为3.3K、2K、2K。INA128的外围电路简单,输入阻抗高,同时能有效的抑制共模干扰,其电路图如图2.1所示。
图2.1交流放大器电路
2.2 带通滤波器
带通滤波器部分的核心部件为UAF42芯片。UAF42是一款通用有源滤波器,可配置为低通、高通、带通滤波器。它使用了一种经典的状态可调的模拟结构,通过一个反向放大器和两个积分器。积分器包含上1nF电容。这种结构解决了有源滤波器设计的一个重要的难题——获得紧密对准公差、低损耗电容。它是一种单片集成电路,其中包含了运算放大器、匹配电阻和状态可调双极滤波极对所需的精密电容,以及四个独立的精密运放。对于带通滤波器的设计,采用Filter42软件计算出外围电阻RF1=RF2=158K,达到中心频率为1000Hz,频带范围为950Hz—1050Hz的滤波要求。其电路如图2.2所示。
4
图2.2带通滤波器电路
2.3相敏检波器
相敏检波器主要部件为MPY634,其电路如图2.3所示。
图2.3相敏检波器电路
2.4低通滤波器
低通滤波器同样采用UAF42构成,其外围电阻分别为44K、470K。电路图如图2.4所示。
5
图2.4低通滤波器电路
2.5直流放大器
直流放大器电路如下图2.5所示。
图2.5直流放大器电路
2.6显示部分
单片机最小系统设计。本设计电流源通过键盘模块输入给定的电流值传送给单片机,单片机在接收到信号后进行处理运算,并显示其给定的电流值,然后经过D/A转换以输出电压,驱动恒流源电路实现电流输出,并将采样电阻上的电压
6
经过A/D转换输入单片机系统,通过补偿算法进行数值补偿处理,调整电流输出并驱动显示器当前的电流值。
最小系统核心为MSP430,将单片机的引脚用接口引出,电路图如图2.6中单片机最小系统模块所示。
C1410uFGNDC15100nFJ3C1R30RY1QUAR25C2R40R12345678910CON10C3100nFP1.0P1.1P1.2P1.3P1.4P1.5P2.0P2.1P2.212345678910R147KU1VCCVSSP1.0XIN/P2.6P1.1XOUT/P2.7P1.2TESTP1.3RSTP1.4P1.7P1.5P1.6P2.0P2.5P2.1P2.4P2.2P2.3MSP430C41nF20191817161514131211XINXOUTJ212345678910CON10VCCR247K
12pFXIN12pFP1.7P1.6P2.5P2.4P2.3XOUTGNDGNDGND图2.6单片机最小系统
A/D转换器选用具有16位分辨率高精度模数转换器ADS1115。ADS1115具有一个板上基准和振荡器,数据通过一个I2C兼容型串行接口进行传输,可以选择4个I2C从地址。如图2.7所示电路中,ADS1115的SDA与单片机P1.2口相接,SCL与单片机P1.3口相接。上接上拉电阻通过编程模拟ADS1115的通信时序实现对ADS1115的操作。
GND12345+3.3vC5ADDRALERT/RDYGNDAIN0AIN1ADS1115SCLSDAADDAIN3AIN2109876R2510kR2610k+3.3vC190.1uFP1.3P1.221GNDJ10CON2 图2.7 A/D转换器
7
液晶显示电路设计如图2.8所示。
J41234567891011121314151617181920CON201234567891011121314151617181920D1VSSVDDVoRsR/WEDB0DB1DB2DB3DB4DB5DB6DB7PSBNCRSTVoutAKQC12864BGND+5vP2.0P2.1P2.2图2.8 液晶显示电路
2.7参考通道部分
参考通道部分采用LM324及外围电阻搭建而成,整个通道分为触发整形、移相、方波驱动三个部分。其电路图如图2.9所示。
图2.9 参考通道部分整体电路
8
2.8自制电源设计
本设计共用到电源有2种:即±15V 、 +5V 。电源原理:稳压电源由电源变压器、整流电路、滤波电路组成,整流作用是将交流电压变换成脉动电压。滤波电路一般由电容组成,其作用是脉动电压中的大部分纹波加以滤除,以得到较平滑的直流电压输出。
图2.10所示的电源电路图由L7815和L7915组成,输出±15V电压给压控恒流电路中的OP07等器件供电。图2.11所示为+5V电源电路。
1D144007C11L7815VIGND C21VO3 T2J5D104007D1240070.1uF D114007D134007C234700uF/50vC25470uF/50vC280.1uF+15vGND1232CON3TRANS4C220.1uFC244700uF/50vC26470uF/50vC270.1uF1GND2VIVO3C12L7915D15
4007图2.10 ±15V电源电路
T11D84007C8L7805VIGNDVO3
C62D34007D64007TRANS10.1uFD54007D74007C72200uF/50vC9C102200uF/50v0.1uFJ6+5v1GND2CON2图2.11 +5V电源电路
9
3 软件设计
3.1 软件流程设计
软件流程图如图3.1所示
图3.1 软件流程图
4测试结果与数据分析
4.1测试仪器
为了确定系统与题目要求的符合程度,对系统中的关键部分进行了实际测试。使用仪器设备见表4—1。
10
表4—1 测试使用的仪器设备
序号 1 2 3
名称、型号、规格 数字万用表 UT71B 数字示波器DS5102M 可调直流稳压电源KHM-1 1 30V/3A 1 带宽100M 1 精度4位半 数量 备注 4.2各部分电路测试结果
1)锁定放大器的设定要求与测试结果如下:
(1)外接信号源提供频率为1kHz的正弦波信号,幅度自定,输入至参考信号R(t)端。R(t)通过自制电阻分压网络降压接至被测信号S(t)端,S(t)端幅度有效值为 10μV~1mV。
结果:外接信号源的频率为1kHz的正弦波信号,幅度0.25v,通过分压网络470倍,S(t)端幅度有效值为 0.5mV,满足设计要求。
(2)参考通道的输出r(t)为方波信号,r(t)的相位相对参考信号R(t)可连续或步进移相180度,步进间距小于10度。
结果:参考通道输出r(t)为方波信号,r(t)的相位相对参考信号R(t)可实现连续或步进移相180度,步进间距小于10度,满足设计要求。
(3)信号通道的3dB频带范围为900Hz~1100Hz。误差小于20%。 结果:带通滤波器的中心频率为1000 Hz,信号通道的3dB频带范围为900Hz~1100Hz,满足设计要求。
(4)在锁定放大器输出端,设计一个能测量并显示被测信号S(t)幅度有效值的电路。所测量的显示值与S(t)有效值的误差小于10%。
结果:所设计的锁定放大器的输出端能测量被测信号S(t)幅度的有效值,所测量的显示值与S(t)有效值的误差为9%,满足设计要求。
(5)在锁定放大器信号S(t)输入端增加一个运放构成的加法器电路,实现S(t)与干扰信号n(t)的1:1叠加。
结果:锁定放大器信号S(t)输入端的加法器电路可以实现S(t)与干扰信号n(t)的1:1叠加,满足设计要求。
(6)用另一信号源产生一个频率为1050~2100Hz的正弦波信号作为n(t),
11
将其叠加在锁定放大器的输入端,信号幅度等于S(t)。n(t)亦可由与获得S(t)同样结构的电阻分压网络得到。锁定放大器应尽量降低n(t)对S(t)信号有效值测量的影响,测量误差小于10%。
结果:测量误差在15%。未能达到设计要求。
(7)增加n(t)幅度,使之等于10S(t),锁定放大器对S(t)信号有效值的测量误差小于10%。
结果:测量误差在22%。未能达到设计要求。 2)测试结果分析
未能完全满足设计要求(6)和(7)。主要原因之一是,参考方波信号和带通滤波器输出信号的相位存在一定误差;主要原因之二是,由于整体电路没有采用屏蔽线,再加上所使用的仪器精度不够不可避免地引入噪声。
5 总结
本设计对于检测微弱信号的锁存放大器进行论述,锁定放大器主要包括交流放大器、带通滤波器、相敏检波器、低通滤波器、直流放大器及液晶显示等几个部分。锁定放大器在实际应用中用途广泛,尤其对于微弱信号检测方向站着主导地位,随着科技的发展已渐渐的融入人类的生活之中,拥有很好的发展前景。
在本次设计的过程中,遇到了许多困难,开始设计进度比较慢,但通过仔细的分析和进行多方面的调整后解决了问题,从中我们对电子专业知识与技能得到了更多的理解与提高。比赛中三个人分工明确,积极配合,最终完成了设计,这使我们深刻地体会到了共同协作和团队精神的重要性。总之,这次比赛对我们每个人都影响非常深刻。
参考文献:
[1] 高晋占主编.《微弱信号检测》.清华大学出版社,2004
[2] 王兆安主编.《电力电子技术》.第五版.北京:机械工业出版社,2009 [3] 邱关源编著《电路(第五版)》,高等教育出版社,2006 [4] 康光华编著《电子技术基础》,高等教育出版社,2006
[5] 阎石主编.《数字电子技术基础》.第五版.北京:高等教育出版社,2006. [6] 梅丽凤等编著《单片机原理及接口技术》清华大学出版社2009.
12
附录:
附录1:主要元器件清单
1、单片机MSP430 G2553 2、16位A/D转换器ADS1115 3、液晶QC12864B 4、高精度运算放大器OP07 5、DNC头、DNC座 6、加法器NE5534 7、乘法器MPY634 8、滤波芯片UAF42 9、移向、比较芯片LM324
10、稳压芯片LM317、7805、7905、7815、7915
13
附2:程序清单
#include typedef unsigned char uchar; typedef unsigned int uint; #define Channal_A 1 //通道A #define Channal_B 2 //通道B #define Channal_AB 3 //通道A&B //**************************TLV5618引脚接线******************** #define DIN_L P1OUT&=~BIT0 //数据输入端 #define DIN_H P1OUT|= BIT0 #define SCLK_L P1OUT&=~BIT4 #define SCLK_H P1OUT|= BIT4 #define CS_L P1OUT&=~BIT5 #define CS_H P1OUT|= BIT5 //ADS1115引脚定义 #define SCL_H P1OUT |= BIT0 #define SCL_L P1OUT &= ~BIT0 #define SDA_H P1OUT |= BIT1 #define SDA_L P1OUT &= ~BIT1 #define SDA_in P1DIR &= ~BIT1 //SDA改成输入模式 #define SDA_out P1DIR |= BIT1 //SDA变回输出模式 #define SDA_val P1IN&BIT1 //SDA的位值 #define TRUE 1 #define FALSE 0 #define CPU_F ((double)8000000) #define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0)) //延时uS #define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0)) //延时mS #define uchar unsigned char #define uint unsigned int #define address 0x90 #define config 0x01 #define conversion 0x00 #define Lsiwei 0xE3 14 #define channel_0 0 //表示选择通道0 #define channel_1 1 //表示选择通道1 #define channel_2 2 //表示选择通道2 #define channel_3 3 //表示选择通道2 uchar jieguo[5]; uchar dianya[3]; ///////////////////////////////// //12864 1接地 2接vcc 3和18接电位器 (3---18 ) 19接vcc 20接地 #define CS BIT0 //P2.0 片选端 //P2.1 数据口 //P2.2 时钟口 #define SID BIT1 #define SCLK BIT2 uchar f[10]; int c; //#define PSB BIT3 //P2.3 PSB=0,串行;PSB=1,并行 int ad,i=1010,j=0,date,p=0,a=0,n=0,w=0; double a1,a2=0,a3=0; // 函数名称 :void DAC_TLV5618(unsigned int Dignum) // 函数功能 :进行DA转换 //============================================================= // 入口参数 :Dignum:根据说明设置转化数据,头四位为特殊位用于选择转化方式, // 以及用于通道选择.请自行设置.后12位为需要转换的值 // 出口参数 :无 void DAC_TLV5618( unsigned int Dignum ) { unsigned int Dig=0; unsigned char i=0; SCLK_H; CS_L; // Chip Enable for(i=0;i<16;i++) // Write 16_Bits Datas { Dig=Dignum&0x8000; 15 //============================================================= } SCLK_H; CS_H; // Chip Disenable } // 函数名称 :void Write_A_B( float Analog_A , float Analog_B , // unsigned char Channal,unsigned char Mode ) // 函数功能 :模式、通道选择并进行DA转换 // 入口参数 :Analog_A:A通道转换的电压值 // Analog_B:B通道转换的电压值 // Channal:通道选择,其值为Channal_A,Channal_B,或Channal_AB // Model:速度控制位 0:slow mode 1:fast mode // 出口参数 :无 //说明: 范围为:0—0x0fff // 本程序如果只需要一个通道时,另外一个通道的值可任意,但是不能缺省 void Write_A_B( float Analog_A , float Analog_B , unsigned char Channal,unsigned char Mode ) { unsigned int Data_A = 0, Data_B = 0; unsigned int tmp = 0; //Analog_A=2*Vref*(Data_A/0x1000) 822 16 if(Dig) } else { } SCLK_L; _NOP(); DIN_L; { DIN_H; Dignum<<=1; SCLK_H; _NOP(); //============================================================= //============================================================= { } void Delay_Nms(uint n) { uint i; for(i = n;i > 0;i--) Delay_1ms(); } void Write_Cmd(uchar cmd) { uchar flag; P2DIR|=CS+SCLK+SID; P2OUT&=~(CS+SCLK+SID);//P2OUT=0; uchar i; uchar i_data; 17 Data_A = (unsigned int)( Analog_A * 1000 ) ; Data_B = (unsigned int)( Analog_B * 1000 ) ; if( Mode ) tmp=0x4000; else tmp=0x0000; switch( Channal ) { case Channal_A: DAC_TLV5618( tmp | 0x8000 | ( 0x0fff & case Channal_B: DAC_TLV5618( tmp | 0x0000 | ( 0x0fff & case Channal_AB:DAC_TLV5618( tmp | 0x1000 | ( 0x0fff & DAC_TLV5618( tmp | 0x8000 | ( 0x0fff & default:break; } } Data_A ) );break; Data_B ) );break; Data_B ) ); Data_A ) );break; void Delay_1ms(void) uchar i; for(i = 150;i > 0;i--) _NOP(); i_data=0xf8; P2OUT|=CS; //CS=1;= for(i=0;i<8;i++) { flag=SID&((i_data&0x80)>>6); if(flag!=0)P2OUT|=SID; else P2OUT&=~SID; P2OUT&=~SCLK; //SCLK=0; P2OUT|=SCLK; //SCLK=1; i_data=i_data<<1; } i_data=cmd; i_data&=0xf0; for(i=0;i<8;i++) { flag=SID&((i_data&0x80)>>6); if(flag)P2OUT|=SID; else P2OUT&=~SID; P2OUT&=~SCLK; //SCLK=0; P2OUT|=SCLK; //SCLK=1; i_data=i_data<<1; } i_data=cmd; i_data=i_data<<4; for(i=0;i<8;i++) { flag=SID&((i_data&0x80)>>6); if(flag)P2OUT|=SID; else P2OUT&=~SID; P2OUT&=~SCLK; //SCLK=0; P2OUT|=SCLK; //SCLK=1; i_data=i_data<<1; } P2OUT&=~CS; //CS=0; Delay_Nms(10); 18 } void Write_Data(uchar dat) { uchar flag; P2DIR|=CS+SCLK+SID; P2OUT&=~(CS+SCLK+SID);//P2OUT=0; //P2OUT&=~PSB; //PSB=0; uchar i; uchar i_data; i_data=0xfa; P2OUT|=CS; //CS=1; for(i=0;i<8;i++) { flag=SID&((i_data&0x80)>>6); if(flag)P2OUT|=SID; else P2OUT&=~SID; P2OUT&=~SCLK; //SCLK=0; P2OUT|=SCLK; //SCLK=1; i_data=i_data<<1; } i_data=dat; i_data&=0xf0; for(i=0;i<8;i++) { flag=SID&((i_data&0x80)>>6); if(flag)P2OUT|=SID; else P2OUT&=~SID; P2OUT&=~SCLK; //SCLK=0; P2OUT|=SCLK; //SCLK=1; i_data=i_data<<1; } i_data=dat; i_data=i_data<<4; for(i=0;i<8;i++) { 19 } void Ini_Lcd(void) { Delay_Nms(500); Write_Cmd(0x30); //基本指令集 Delay_1ms(); Write_Cmd(0x02); // 地址归位 Delay_1ms(); } void pos(uchar x,uchar y)//x:1,2,3,4 { //y:1,2,3,4,5,6,7,8 //x行y列 uchar pos; Write_Cmd(0x0c); //整体显示打开,游标关闭 Write_Cmd(0x01); //清除显示 Write_Cmd(0x06); //游标右移 Write_Cmd(0x80); //设定显示的起始地址 Delay_1ms(); Delay_1ms(); Delay_1ms(); } P2OUT&=~CS; //CS=0; Delay_Nms(10); flag=SID&((i_data&0x80)>>6); if(flag)P2OUT|=SID; else P2OUT&=~SID; P2OUT&=~SCLK; //SCLK=0; P2OUT|=SCLK; //SCLK=1; i_data=i_data<<1; switch(x) { case 1:pos=0x80+y;break; case 2:pos=0x90+y;break; case 3:pos=0x88+y;break; case 4:pos=0x98+y;break; } 20 } void LCD_12864(uchar x,uchar y,char *q)//在x行y列显示字符串q { uchar i; __delay_cycles(10); } void send(uchar x,uchar y,int date)//在x行y列显示字符串q { __delay_cycles(10); } void adc() { } void anjian() { P2DIR&=~BIT3; P2OUT|=BIT3; P2DIR&=~BIT4; P2OUT|=BIT4; P2DIR&=~BIT5; P2OUT|=BIT5; P1DIR&=~BIT7; P1OUT|=BIT7; 21 Write_Cmd(pos); pos(x,y); for(i=0;*(q+i)!='\\0';i++) Write_Data(q[i]); pos(x,y); Write_Data(date); ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start __bis_SR_register(CPUOFF + GIE); ad=ADC10MEM; date=ADC10MEM; a1=((double)date/1023)*3.64; // LPM0, ADC10_ISR will force exit } { { } i=i-10; if(i==90) i=0; { LCD_12864(3,0,\"DA转换电压:\"); send(4,2,(int)a1/10000+0x30); send(4,3,(int)a1%10000/1000+0x30); send(4,4,(int)a1%1000/100+0x30); send(4,5,(int)a1%100/10+0x30); send(4,6,(int)a1%10+0x30); LCD_12864(4,7,\"mV\"); LCD_12864(1,0,\"AD转换电流:\"); send(2,2,i/1000+0x30); send(2,3,i/100%10+0x30); send(2,4,i/10%10+0x30); send(2,5,i%10+0x30); while(!(P2IN&BIT4)); Write_Cmd(0x01); if(!(P2IN&BIT4)) { { __delay_cycles(1000); if(!(P2IN&BIT4)) //while((P2IN&BIT3)&&(P2IN&BIT5)&&(P1IN&BIT6)) LCD_12864(2,7,\"mA\"); __delay_cycles(1000); } if(!(P2IN&BIT3)) __delay_cycles(1000); if(!(P2IN&BIT3)) Write_Cmd(0x01); while(!(P2IN&BIT3)); LCD_12864(1,0,\"进入设置界面\"); 22 } if(!(P1IN&BIT7)){ __delay_cycles(1000); if(!(P1IN&BIT7)) { while(!(P1IN&BIT7)); Write_Cmd(0x01); //while((P1IN&BIT7)&&(P1IN&BIT7)) { LCD_12864(3,0,\"AD输入电流监测:\"); send(4,2,(int)a1%10+0x30); send(4,3,0x2e); send(4,4,(int)(a1*10)%10+0x30); 23 } LCD_12864(2,0,\"按2---电流\"); LCD_12864(3,0,\"按4---\"); LCD_12864(4,0,\"负载调整率\"); __delay_cycles(1000); } { if(!(P2IN&BIT5)) __delay_cycles(1000); if(!(P2IN&BIT5)) { } while(!(P2IN&BIT5)); Write_Cmd(0x01); //while((P2IN&BIT4)&&(P2IN&BIT3)) LCD_12864(3,0,\"输入电流监测:\"); send(4,2,(int)a1%10+0x30); send(4,3,0x2e); send(4,4,(int)(a1*10)%10+0x30); send(4,5,(int)(a1*100)%10+0x30); send(4,6,(int)(a1*1000)%10+0x30); LCD_12864(4,7,\"mA\"); send(4,5,(int)(a1*100)%10+0x30); send(4,6,(int)(a1*1000)%10+0x30); LCD_12864(4,7,\"mA\"); LCD_12864(1,0,\"取样电阻5R\"); Write_A_B(1, 2, Channal_AB, 1); } /////////////////////////ADS1115///////////////////////////////////// void delay(void) { uchar i; } /******************************************* 函数名称:start 功 能:完成IIC的起始条件操作 参 数:无 返回值 :无 ********************************************/ void start(void) { } /******************************************* 函数名称:stop 功 能:完成IIC的终止条件操作 24 } } } for(i = 0;i < 15;i++) _NOP(); SCL_H; SDA_H; delay(); SDA_L; delay(); SCL_L; delay(); 参 数:无 返回值 :无 ********************************************/ void stop(void) { } /******************************************* 函数名称:mack 功 能:完成IIC的主机应答操作 参 数:无 返回值 :无 ********************************************/ void mack(void) { } /******************************************* 函数名称:mnack 功 能:完成IIC的主机无应答操作 参 数:无 返回值 :无 ********************************************/ 25 SDA_L; delay(); SCL_H; delay(); SDA_H; delay(); SDA_L; _NOP(); _NOP(); SCL_H; delay(); SCL_L; _NOP();_NOP(); SDA_H; delay(); void mnack(void) { } /**********检查应答信号函数******************/ /*如果返回值为1则证明有应答信号,反之没有*/ /******************************************* 函数名称:check 功 能:检查从机的应答操作 参 数:无 返回值 :从机是否有应答:1--有,0--无 ********************************************/ void ack() { uchar i; i=0; SDA_in; SCL_H; delay(); while((P1IN&BIT1)&&(i<250)) i++; SDA_out; SCL_L; delay(); } /******************************************* 函数名称:write1 功 能:向IIC总线发送一个1 参 数:无 26 SDA_H; _NOP(); _NOP(); SCL_H; delay(); SCL_L; _NOP(); _NOP(); SDA_L; delay(); 返回值 :无 ********************************************/ void write1(void) { } /******************************************* 函数名称:write0 功 能:向IIC总线发送一个0 参 数:无 返回值 :无 ********************************************/ void write0(void) { } /******************************************* 函数名称:write1byte 功 能:向IIC总线发送一个字节的数据 参 数:wdata--发送的数据 返回值 :无 ********************************************/ void write1byte(uchar wdata) { uchar i; 27 SDA_H; delay(); SCL_H; delay(); SCL_L; delay(); SDA_L; delay(); SCL_H; delay(); SCL_L; delay(); } /******************************************* 函数名称:read1byte 功 能:从IIC总线读取一个字节 参 数:无 返回值 :读取的数据 ********************************************/ uchar read1byte(void) { uchar rdata = 0x00,i; for(i = 0;i < 8;i++) { } 28 for(i = 8;i > 0;i--) { } SDA_H; _NOP(); if(wdata & 0x80) write1(); else write0(); wdata <<= 1; uchar flag; SDA_H; delay(); SCL_H; delay(); flag = SDA_val; rdata <<= 1; if(flag) rdata |= 0x01; SCL_L; delay(); SDA_in; SDA_out; return rdata; } void Confige1115(uchar channel) { uchar a_channel; switch (channel) { case 0:a_channel=0xC0;break; case 1:a_channel=0xD0;break; case 2:a_channel=0xE0;break; case 3:a_channel=0xF0;break; default: break; } start(); write1byte(address); ack(); write1byte(config); ack(); write1byte(a_channel); ack(); write1byte(Lsiwei); ack(); stop(); } uint read1115() { uchar result_l,result_h; uint result; start(); write1byte(address); ack(); write1byte(conversion); ack(); stop(); delay_ms(5); 29 start(); write1byte(address+1); ack(); result_h=read1byte(); ack(); result_l=read1byte(); ack(); stop(); result=result_h*256+result_l; return result; } uint go_1115(uchar temp) { uint result_gd; Confige1115(temp); delay_ms(5); result_gd=read1115(); delay_ms(5); return result_gd; } /////////////////////////////////////////// main() { uchar i; uint result=0; WDTCTL = WDTPW + WDTHOLD; //关狗 Ini_Lcd(); //初始化液晶 P1DIR|=BIT0+BIT1+BIT2+BIT4+BIT5; P1OUT|=BIT0+BIT1+BIT2+BIT4+BIT5; SCL_H; //ADS1115 IIC SDA_H; SDA_out; WDTCTL = WDTPW + WDTHOLD; // Stop WDT ADC10CTL0 = ADC10SHT_2 + ADC10ON + ADC10IE; // ADC10ON, interrupt enabled 30 ADC10CTL1 = INCH_3; // input A1 ADC10AE0 |= 0x02; // PA.1 ADC option select P1DIR&=~BIT7; P1OUT|=BIT7; while(1) { LCD_12864(1,0,\"1.——界面设置\"); LCD_12864(2,0,\"2.——调整电流\"); LCD_12864(3,0,\"3.——电流监测\"); LCD_12864(4,0,\"4.——重置界面\"); while(P1IN&BIT7) { adc(); anjian(); //tlv5618_init(); // tlv5618(0x04,2047); // Write_A_B(1, 2, Channal_AB, 1); result=go_1115(channel_0); jieguo[0]=(result/10000)+0x30; jieguo[1]=(result/1000%10)+0x30; jieguo[2]=(result/100%10)+0x30; jieguo[3]=(result/10%10)+0x30; jieguo[4]=(result%10)+0x30; // while(1); } } } #pragma vector=ADC10_VECTOR __interrupt void ADC10_ISR(void) { __bic_SR_register_on_exit(CPUOFF); } 31 // Clear CPUOFF bit from 0(SR) 因篇幅问题不能全部显示,请点此查看更多更全内容