Auto_LCR_Meter_XJW01/led.c

577 lines
19 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*************************************
LCR表驱动程序 V1.0
xjw01 于莆田 2011.10
**************************************/
//====================================
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#include <reg52.h>
#include <math.h>
void delay(uint loop) { uint i; for(i=0;i<loop;i++); } //延时函数
void delay2(uint k){ for(;k>0;k--) delay(10000); } //长延时,k=100大约对应1秒
//========================AD转换=============================
sfr P1ASF = 0x9D; //将P1置为模拟口寄存器(使能),各位中为1的有效
sfr ADC_CONTR = 0xBC; //A/D转换控制寄存器
sfr ADC_res = 0xBD; //A/D转换结果寄存器
sfr ADC_resl = 0xBE; //A/D转换结果寄存器
void set_channel(char channel){
P1ASF = 1<<channel;
ADC_CONTR = channel+128; //最高位是电源开关,低3位通道选择
delay(1); //首次打开电源应延迟,使输入稳定
}
uint getAD2(){
ADC_CONTR |= 0x08; //00001000,置ADC_START=1启动A/D 转换
while ( !(ADC_CONTR & 0x10) ); //等待A/D转换结束(ADC_FLAG==0)
ADC_CONTR &= 0xE7; //11100111,置ADC_FLAG=0清除结束标记, 置ADC_START=0关闭A/D 转换
return ADC_res*4 + ADC_resl;
}
/*
uchar get_AD(){
ADC_CONTR |= 0x08; //00001000,置ADC_START=1启动A/D 转换
while( !(ADC_CONTR & 0x10) ); //等待A/D转换结束(ADC_FLAG==0)
ADC_CONTR &= 0xE7; //11100111,置ADC_FLAG=0清除结束标记, 置ADC_START=0关闭A/D 转换
return ADC_res;
}
*/
uint getAD10() reentrant { //10次采样
char i;
uint c = 0;
for(i=0;i<10;i++) c += getAD2();
return c;
}
//============================EEPROW偏程=========================
sfr IAP_data = 0xC2;
sfr IAP_addrH = 0xC3;
sfr IAP_addrL = 0xC4;
sfr IAP_cmd = 0xC5;
sfr IAP_trig = 0xC6;
sfr IAP_contr = 0xC7;
/********************
写字节时可以将原有数据中的1改为0无法将0改为1只能使用擦除命令将0改为1
应注意,擦除命令会将整个扇区擦除
*********************/
void saEEP(){ //EEP保护
IAP_cmd = 0; //关闭令,保护
IAP_contr = 0; //关EEPROM保护
IAP_trig = 0;
IAP_addrL = 255; //设置读取地址的低字节,地址改变才需要设置
IAP_addrH = 255; //设置读取地址的高字节,地址改变才需要设置
}
uchar readEEP(uint k){ //读取
IAP_addrL = k; //设置读取地址的低字节,地址改变才需要设置
IAP_addrH = k>>8; //设置读取地址的高字节,地址改变才需要设置
IAP_contr = 0x81; //设置等待时间1MHz以下取72M以下取63M取56M取412M取320M取224M取130M取0前导1表示许档IAP
IAP_cmd = 1; //读取值1写取2擦除取3擦除时按所在字节整个扇区撺除
IAP_trig = 0x5A; //先送5A
IAP_trig = 0xA5; //先送5A再送A5立即触发
saEEP(); //保护
return IAP_data;
}
void writeEEP(uint k, uchar da){ //写入
IAP_data = da; //传入数据
IAP_addrL = k; //设置读取地址的低字节,地址改变才需要设置
IAP_addrH = k>>8; //设置读取地址的高字节,地址改变才需要设置
IAP_contr = 0x81; //设置等待时间1MHz以下取72M以下取63M取56M取412M取320M取224M取130M取0前导1表示许档IAP
IAP_cmd = 2; //读取值1写取2擦除取3擦除时按所在字节整个扇区撺除
IAP_trig = 0x5A; //先送5A
IAP_trig = 0xA5; //先送5A再送A5立即触发
saEEP(); //保护
}
void eraseEEP(uint k){ //擦除
IAP_addrL = k; //设置读取地址的低字节,地址改变才需要设置
IAP_addrH = k>>8; //设置读取地址的高字节,地址改变才需要设置
IAP_contr = 0x81; //设置等待时间1MHz以下取72M以下取63M取56M取412M取320M取224M取130M取0前导1表示许档IAP
IAP_cmd = 3; //读取值1写取2擦除取3擦除时按所在字节整个扇区撺除
IAP_trig = 0x5A; //先送5A
IAP_trig = 0xA5; //先送5A再送A5立即触发
saEEP(); //保护
}
xdata struct Ida{
char zo[3];//三个频率下的零点改正值
char j1; //相位补偿(3倍档)
char j2; //相位补偿(10倍档)
char J[4]; //相位补偿(V/I变换器)
char R[4]; //下臂电阻修正(20,1k,10k,100k)
char g1; //增益修正(3倍档)
char g2; //增益修正(10倍档)
} cs;
void cs_RW(char rw){
uchar i,*p = &cs;
if(rw){
eraseEEP(0);
for(i=0;i<sizeof(cs);i++) writeEEP(i,p[i]);
}else{
for(i=0;i<sizeof(cs);i++) p[i]=readEEP(i);
}
}
/**********
字形编码图
32
-
64| | 128
- 16
1| | 8
_. 4
2
**********/
uchar code zk[20]={235,136,179,186,216,122,123,168,251,250, 59,201,2,18,50}; //字库,0-9,10,11,12,13,14
uchar code zk2[8]={241,25,11,233,27,50,155,107};//p,n,u,m,0,k,M,G
uchar disp[6]={168,251,250}; char cx=-1; //显示缓存,cx光标位置
sfr P1M1=0x91; //P1端口设置寄存器
sfr P1M0=0x92; //P1端口设置寄存器
sfr P0M1=0x93; //P0端口设置寄存器
sfr P0M0=0x94; //P0端口设置寄存器
sfr P2M1=0x95; //P2端口设置寄存器
sfr P2M0=0x96; //P2端口设置寄存器
sfr P3M1=0xB1; //P3端口设置寄存器
sfr P3M0=0xB2; //P3端口设置寄存器
sbit ds3=P2^4; //数码管扫描口
sbit ds2=P2^5; //数码管扫描口
sbit ds1=P2^6; //数码管扫描口
sbit ds0=P2^7; //数码管扫描口
sbit spk=P2^3; //蜂鸣器
sbit Kb=P2^1; //量程开关B
sbit Ka=P2^2; //量程开关A
sbit DDS2=P1^2;//移相方波输出口
sbit K3=P1^7;
sbit K4=P1^6;
sbit K5=P1^5; //7.8kHz滤波开关
sbit K6=P1^4;
sbit K8=P2^0; //100Hz滤波开关
//==============字符显示函数====================
xdata uchar menu=1,menu2=0;
void cls(){ char i; for(i=0;i<6;i++) disp[i]=0; } //清屏
void showDig(long f){ //显示数字
uchar i;
cls();
for(i=0;i<6;i++) { disp[i]=zk[f%10], f/=10; if(!f) break; }
}
void showDig2(float f,char n,char dw){ //显示浮点数,nL是单位下限控制,如n=2时最小显示到u单位
char i,b=0,b2=0,fh=0;
if(f<0) fh=1,f=-f;
for(i=0;i<3;i++){ if(f>=1000) f/=1000, b++; } //以3位为单位移动小数点把大数转粉0至999,小数点在末字
for(i=0;i<n;i++){ if(f<1) f*=1000, b--; } //以3位为单位移动小数点把小数转粉0至999,小数点在末字
for(i=0;i<3;i++){ if(f<1000) f*=10, b2++; } //对小于1000结果连同小数点整体移位使首位移到最左边
showDig(f+10000); //加10000是为了补零
disp[b2] += 4; //小数点
if(!dw) return;
disp[0] = zk2[b+4]; //显示单位
if(fh) disp[0] += 4; //显示符号
}
//==============低频信号DDS====================
//PCA相关寄存器
sfr CMOD = 0xD9; //钟源选择控制等
sfr CH = 0xF9; //PCA的计数器
sfr CL = 0xE9; //PCA的计数器
sfr CCON = 0xD8; //PCA控制寄存器
sfr CCPAM0 = 0xDA; //PCA模块0工作模式寄存器
sfr CCPAM1 = 0xDB; //PCA模块1工作模式寄存器
sfr CCAP0L = 0xEA; //模块0捕获寄存器低位
sfr CCAP0H = 0xFA; //模块0捕获寄存器高位
sbit PPCA = IP^7; //PCA的中断优先级设置
sbit CCF0 = CCON^0; //PCA的模块0中断标志
sbit CCF1 = CCON^1; //PCA的模块1中断标志
sbit CR = CCON^6; //PCA计数器使能
void PWM_init(){ //把PCA置为PWM
CMOD = 2; //0000 0010 计数源选择,钟源取fosc/2
CL = CH = 0;
CCAP0L = CCAP0H = 192; //占空比为25%
//CCPAM0=0x42;//0100 0010,PCA的模块0设置为PWM模式,无中断
CCPAM0=0x53;//0101 0011,PCA的模块0设置为PWM模式,有中断,下降沿中断
PPCA = 1; //优先中断
//CR = 1; //开始计数
EA = 1; //开总中断
}
uint ph=0, phM=256, feq=1000; //相位,phM相位步进值
xdata float feqX=1000; //实际输出频率
uchar code sinB[256]={
//查询表中不可装载零值,否则会造成无中断产生
255,255,255,255,255,255,254,254,253,252,252,251,250,249,248,247,246,245,243,242,240,239,237,236,234,232,230,229,227,225,222,220,
218,216,214,211,209,206,204,201,199,196,194,191,188,185,183,180,177,174,171,168,165,162,159,156,153,150,147,144,140,137,134,131,
128,125,122,119,116,112,109,106,103,100, 97, 94, 91, 88, 85, 82, 79, 76, 73, 71, 68, 65, 62, 60, 57, 55, 52, 50, 47, 45, 42, 40,
38, 36, 34, 31, 29, 27, 26, 24, 22, 20, 19, 17, 16, 14, 13, 11, 10, 9, 8, 7, 6, 5, 4, 4, 3, 2, 2, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 2, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 16, 17, 19, 20, 22, 24, 26, 27, 29, 31, 34, 36,
38, 40, 42, 45, 47, 50, 52, 55, 57, 60, 62, 65, 68, 71, 73, 76, 79, 82, 85, 88, 91, 94, 97,100,103,106,109,112,116,119,122,125,
128,131,134,137,140,144,147,150,153,156,159,162,165,168,171,174,177,180,183,185,188,191,194,196,199,201,204,206,209,211,214,216,
218,220,222,225,227,229,230,232,234,236,237,239,240,242,243,245,246,247,248,249,250,251,252,252,253,254,254,255,255,255,255,255
};
uchar code fbB[256]={ //方波DDS查询表
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
};
uchar chuX=0; //方波DDS初相
void PCAinter(void) interrupt 7 {//PCA中断
uchar x,y;
CCF0=0; //清除中断请求,以免反复中断
x = ph >> 8; //截断正弦相位累加器,取高8位
y = x + chuX; //方波相位
CCAP0H = sinB[x];//正弦DDS输出
DDS2 = fbB[y]; //方波DDS输出
ph += phM; //相位累加
}
void setDDS(uint f){ //参考时钟是c=(fosc/2)/256=32000000/2/256=62500,频率f=c*phM/2^16
feq = f;
phM=f*65536.0/62500; //phM=f*2^16/62500
feqX = 62500.0*phM/65536; //实际输出频率
ph = 0; //高频时,使波形对称
if(!f) CR=0; else CR=1;
}
//相位控制函数
xdata char xw=0; //相位
void set90(char k){ //设置方波的相位差
k %= 4;
if(k<0) k += 4;
if(k==0) chuX=0; //移相0度
if(k==1) chuX=64; //移相90度
if(k==2) chuX=128; //移相180度
if(k==3) chuX=192; //移相270度
xw = k;
}
void set902() { set90(xw+1); } //相位步进
//==============量程控制函数====================
xdata char rng=1; //量程
void setRng(char k){//切换量程
if(k==0) Ka=0,Kb=0; //100欧
if(k==1) Ka=0,Kb=1; //1k欧
if(k==2) Ka=1,Kb=0; //10k欧
if(k==3) Ka=1,Kb=1; //100k欧
rng = k;
}
void setRng2(){ setRng( (rng+1)%4); } //量程步进
//==============增益控制函数====================
char curGain=1; //当前增益索引号
void setGain(char k){ //设置电路增益
if(k>3) k=3;
if(k<0) k=0;
if(k==0) K4=0,K6=0; //1倍
if(k==1) K4=0,K6=1; //3倍
if(k==2) K4=1,K6=0; //10倍
if(k==3) K4=1,K6=1; //30倍
curGain = k;
}
void setGain2(){ setGain((curGain+1)%4); }
//==============LCR测量====================
xdata int Vxy[4]={0,0,0,0}; //Vxy[Vx1,Vy1,Vx2,Vy2]
xdata char Sxw[4]={0,1,0,1}; //保存正确相位
xdata char Vga[4]={1,1,1,1}; //上下臂增益记录表
xdata uchar tim=0,tims=0;
xdata char pau=0; //暂停坐标自动旋转
#define Vfull 9600
#define gad (9600/30)
uchar mT = 6; //测量速度
//==============设置频率====================
xdata char feqK=1; //频率索引号
void setF(char k){
if(k==-1){ //步进
k = 0;
if(feq==100) k=1;
if(feq==1000) k=2;
if(feq==7813) k=0;
}
if(k==0) { setDDS(100); K5=0; K8=1; mT=15; } //置为100Hz
if(k==1) { setDDS(1000); K5=0; K8=0; mT=6; } //置为1kHz
if(k==2) { setDDS(7813); K5=1; K8=0; mT=6; } //置为7.8125kHz
feqK=k;
TH1 = 47, TL1 = 171; //置为20ms
tims = 0;
tim = 0;
ph = 0;
}
int absMax(int a,int b){ //取两个数绝对值最大者
if(a<0) a = -a;
if(b<0) b = -b;
if(b>a) a = b;
return a;
}
#define avn 4 //求平无个数
xdata float vq[3][avn]; //数据缓存,用于求平均
void LCRcalc(int *v,char *g){ //LCR计算
code float ga[4] = { 1, 3, 9, 27 }; //增益表
code float dwR[4] = { 20, 1e3, 1e4, 1e5 }; //各档电阻表
xdata int g12 = (int)cs.g1+cs.g2; //增益最大补偿
xdata int j12 = (int)cs.j1+cs.j2; //相位最大补偿
xdata float JD = 0,cJD, G = 0; //补偿变量
xdata float a,b,c,e;
char i;
a = +( 1.0*v[2]*v[2] + 1.0*v[3]*v[3] );
b = -( 1.0*v[0]*v[2] + 1.0*v[1]*v[3] );
c = -( 1.0*v[2]*v[1] - 1.0*v[0]*v[3] );
a *= ga[g[0]] / ga[g[2]];
a /= dwR[rng]*(1+cs.R[rng]/10000.0); //除以下臂电阻阻值
//可控增益单元的增益修正、相位补偿量
if(g[0] == 1) JD += cs.j1, G += cs.g1;
if(g[0] == 2) JD += cs.j2, G += cs.g2;
if(g[0] == 3) JD += j12, G += g12;
if(g[2] == 1) JD -= cs.j1, G -= cs.g1;
if(g[2] == 2) JD -= cs.j2, G -= cs.g2;
if(g[2] == 3) JD -= j12, G -= g12;
JD -= cs.J[rng];
JD *= feqX/7813/1000;
cJD = 1 - JD*JD/2;
a *= 1+G/10000; //增益补偿
e = b*cJD - c*JD; //相位补偿
c = b*JD + c*cJD; //相位补偿
b = e;
//入队
for(i=1;i<avn;i++){
vq[0][i] = vq[0][i-1];
vq[1][i] = vq[1][i-1];
vq[2][i] = vq[2][i-1];
}
vq[0][0]=a, vq[1][0]=b, vq[2][0]=c;
}
void timerInter1(void) interrupt 3 {//T1中断
char g; int c;
if(pau) return;
tims++;
if(tims>=mT){ //tim进位触发
tims = 0, tim++;
if(tim>=4) tim=0;
c = getAD10(); //读取电压值
c -= cs.zo[feqK];
Vxy[tim] = xw<2 ? c : -c; //保存当前电压
Vga[tim] = curGain; //保存当前增益
Sxw[tim] += c<0 ? 2 : 0; //相位翻转(预测下次的相位采用值)
Sxw[tim] %= 4;
if(tim==1||tim==3){ //上下臂切换
//电压模值才能反应运放的输出幅度,所以增益切换判断得用模值
if(tim==1) K3=1, c = absMax(Vxy[2],Vxy[3]), g=Vga[2]; //切换到下臂
if(tim==3) K3=0, c = absMax(Vxy[0],Vxy[1]), g=Vga[0]; //切换到上臂
if(c>Vfull) g--;
else if(c<gad*1 ) g += 3; //增加27倍
else if(c<gad*3 ) g += 2; //增加9倍
else if(c<gad*9) g++; //增加3倍
setGain(g);
}
set90( Sxw[ (tim+1)%4 ] ); //相位旋转
LCRcalc(Vxy,Vga);
}
}
char sfdw=1; //是否显示单位
void showR(char xm, char binLian){ //显示LCR
char i;
xdata float a=0,b=0,c=0,e,w;
for(i=0;i<avn;i++)
a += vq[0][i]/avn,
b += vq[1][i]/avn,
c += vq[2][i]/avn;
//电学量显示
if(!a) { cls(); disp[3]=115;disp[2]=disp[1]=97; return; }
w = 2*3.1415926*feqX;
if(!binLian){ //串联
e = a;
if(xm==0){ showDig2(c/e,1, sfdw); }//显示X值,显示到毫欧
if(xm==1){ showDig2(b/e,1, sfdw); }//显示R值,显示到毫欧
if(xm==2){
if(c<0) showDig2(e/c/w,4, sfdw); //显示C值,显示到pF
else showDig2(c/e/w,2, sfdw); //显示L值,显示到uH
}
}else{ //并联
e = (b*b+c*c)/a;
if(xm==0){ showDig2(e/c,1, sfdw); }//显示并联X值,显示到毫欧
if(xm==1){ showDig2(e/b,1, sfdw); }//显示并联R值,显示到毫欧
if(xm==2){
if(c<0) showDig2(c/e/w,4, sfdw);//显示并联C值,显示到pF
else showDig2(e/c/w,2, sfdw);//显示并联L值,显示到uH
}
}
if(xm==3){ //显示Q值
if(!b) { showDig(9999); return; }
c = fabs(c/b);
if (c>=1000) { showDig(999 ); }
else if(c>=100 ) { showDig(c ); }
else if(c>=10 ) { showDig(c*10 ); disp[1] += 4; }
else if(c>=1 ) { showDig(c*100 ); disp[2] += 4; }
else { showDig(c*1000); disp[3] += 4; }
}
}
//void timerInter(void) interrupt 1 {}//T0中断
void showMsg(uchar a){ //临时跳出信息
P0 = ~a;
ds0=1, ds1=ds2=ds3=0;
delay2(50);
}
main(){
uchar i=0,kn=0,key=0;
uchar dispN=0; //显示扫描索引
uchar spkN=0; //蜂鸣器发声时长
uint nn=0;
uchar XRQ=1;
char binLian=0; //并联1,串联0
delay2(80); //启动延时
cs_RW(0); //读EEPROM
TCON=0, TMOD=0x12; //将T0置为自动重装定时器T1置为定时器
TH1 = 0, TL1 = 0;
TR1=1; //T1开始计数
TR0=0; //T0暂停计数
ET1=1; //T1开中断
ET0=1; //T1开中断
EA=1; //开总中断
PT0=1; //设置优先级
set_channel(0); //设置AD转换通道
P2M0 = 0xFF; //P2.01234567置为推勉输出
P1M0 = 0xFC; //P1.234567置为推换口
P1M1 = 0x03; //P1.0置为高阻抗
//请注意启动延时0.5秒方可读取cs_RW
//cs_RW(0); //读取比值基数(调零时已做开机延时确保电压上升到可读取EEPROW)
PWM_init();//DDS初始化
set90(2); //初始设置相位
setRng(1); //初始设置量程
setGain(1); //初始设置增益
setF(1); //DDS初始设置为1kHz
while(1){
//显示disp
nn++;
dispN=(++dispN)%4; //扫描器移动
ds0=ds1=ds2=ds3=0;
if(dispN==0) ds0=1;
if(dispN==1) ds1=1;
if(dispN==2) ds2=1;
if(dispN==3) ds3=1;
P0=~disp[dispN]; //显示
//扫描键盘
//键盘响应
//key = (~P3)&0xfc;
key = ~P3;
if(key&&kn<255) kn++; else kn=0;
for(i=0;key;i++) key/=2; key=i;
if(kn==20) spkN=50; else key=0; //当按下一定时间后key才有效否则无效。spkN发声时长设置
if(spkN) spkN--, spk=0; else spk=1; //键盘发声
//菜单系统
if(key==8) { menu=0; key=0; XRQ=-1;} //菜单键
if(menu>=1&&menu<=4){
if(key==7) setRng2(); //量程步进
if(key==6) setF(-1); //设置频率
}
if(menu==0){ //显示量程和菜单
showDig(10000);
if(key>=1 && key<=7) menu = key, menu2 = 0;
key = 0;
}
if(menu==1){ //自动LCR测量(串联)
pau = 0;
if(XRQ==-1) XRQ=1, sfdw=1;
if(key==4) { //串并联切换
if(binLian) { binLian=0; showMsg(122); } //转为串联
else { binLian=1; showMsg(241); } //转为并联
}
if(key==1) { if(XRQ==0) sfdw++; else sfdw=1; XRQ = 0; }
if(key==2) { if(XRQ==1) sfdw++; else sfdw=1; XRQ = 1; }
if(key==3) { if(XRQ==2) sfdw++; else sfdw=1; XRQ = 2; }
if(key==5) XRQ = 3;
sfdw %= 2;
showR(XRQ,binLian);
if(binLian && nn%512<50) { for(i=0;i<4;i++) disp[i] |= 4; }
}
if(menu==2){ //显示增益档位
showDig(Vga[0]*100+Vga[2]+10000);
disp[1]=disp[3]=0;
}
if(menu==3){ //手动调试
pau = 1;
if(key==1) { setGain2(); showMsg( zk[curGain] );} //增益控制
if(key==2) { };
if(key==3) { K3=~K3; showMsg(zk[K3]); } //切换上下臂
if(key==4) { set902(); showMsg(zk[xw]); } //相位旋转
if(nn%64==0) { showDig( getAD10()); disp[1]+=4; }
}
if(menu==7){ //设置零点偏移数
char *p,bc=1, feqD=1,rngD=1;
static char kc=0, mo=0;
if(menu2==0) p = cs.zo+0, feqD=0, rngD=2; //100Hz零点校准,接入10欧电阻
if(menu2==1) p = cs.zo+1, feqD=1, rngD=2; //1kHz零点校准,接入10欧电阻
if(menu2==2) p = cs.zo+2, feqD=2, rngD=2; //7.8kHz零点校准,接入10欧电阻
if(menu2==3) p = cs.J+0, feqD=2, rngD=0; //VI变换器相位校准,接入20电阻
if(menu2==4) p = cs.J+1, feqD=2, rngD=1; //VI变换器相位校准,接入1k电阻
if(menu2==5) p = cs.J+2, feqD=2, rngD=2; //VI变换器相位校准,接入10k电阻
if(menu2==6) p = cs.J+3, feqD=2, rngD=3; //VI变换器相位校准,接入100k电阻
if(menu2==7) p = &cs.j1, feqD=2, rngD=1; //运放3倍档相位校准,接入3.3k电阻
if(menu2==8) p = &cs.j2, feqD=2, rngD=1; //运放10倍档相位校准,接入10k电阻
if(menu2==9) p = cs.R+0, bc=2, feqD=1, rngD=0; //VI变换器模值校准,接入20欧
if(menu2==10) p = cs.R+1, bc=2, feqD=1, rngD=1; //VI变换器模值校准,接入1k欧
if(menu2==11) p = cs.R+2, bc=2, feqD=1, rngD=2; //VI变换器模值校准,接入10k欧
if(menu2==12) p = cs.R+3, bc=2, feqD=1, rngD=3; //VI变换器模值校准,接入100k欧
if(menu2==13) p = &cs.g1, bc=2, feqD=1, rngD=1; //运放3倍增益校准,接入2k欧电阻
if(menu2==14) p = &cs.g2, bc=2, feqD=1, rngD=1; //运放10倍增益校准,接入10k欧电阻
if(key==1) *p += bc; //X键增
if(key==2) *p -= bc; //R键减
if(key==3) { cs_RW(1); setF(feqK); } //L键保存
if(key==4) *p = 0; //C键清除
if(key==5) { if(menu2==0) menu2=14; else menu2--; mo=0; showMsg(menu2<9?zk[menu2]:zk[menu2-6]+4); }
if(key==6) { if(menu2==14)menu2=0; else menu2++; mo=0; showMsg(menu2<9?zk[menu2]:zk[menu2-6]+4); }
if(key==7) mo = (mo+1)%2;
if(key==4){ //恢复到默认值
if(++kc==5){
kc = 0;
cs.j1 = 16, cs.j2 = 18;
cs.g1 = 0, cs.g2 = 0;
cs.zo[0] = 15;
cs.zo[1] = 17;
cs.zo[2] = 15;
cs.J[0] = cs.J[1] = cs.J[2] = 0, cs.J[3] = 20;
cs.R[0] = cs.R[1] = cs.R[2] = cs.R[3] = 0;
}
}
else { if(key) kc=0; }
if(mo){
if(feqD!=feqK) setF(feqD);
if(rngD!=rng) setRng(rngD);
if(menu2>=3 && menu2<=8) showR(3,1); //显示Q
else showR(1,1); //显示电阻
}else{
sfdw = 0;
showDig(abs(*p));
if(*p<0) disp[3] = 16;
}
}
delay(4000);
}//while end
}