矿石收音机论坛

 找回密码
 加入会员

QQ登录

只需一步,快速开始

搜索
楼主: xjw01

LCR表设计成功了!

  [复制链接]
     
发表于 2011-10-10 16:50:55 | 显示全部楼层
出套件的价格要是和 LTC2400 表头套件的价钱差不多就好了
回复 支持 反对

使用道具 举报

     
发表于 2011-10-10 19:49:16 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2011-10-10 20:11:15 | 显示全部楼层
本帖最后由 xjw01 于 2011-10-11 07:03 编辑

这个版本简化了直流输出滤波器。
V1.0版,到此结束。

myLCR.PNG
  1. /*************************************
  2. LCR表驱动程序 V1.0
  3. xjw01 于莆田 2011.10
  4. **************************************/
  5. //====================================
  6. #define uchar unsigned char
  7. #define uint  unsigned int
  8. #define ulong  unsigned long
  9. #include <reg52.h>
  10. #include <math.h>

  11. void delay(uint loop) { uint i; for(i=0;i<loop;i++); } //延时函数
  12. void delay2(uint k){ for(;k>0;k--) delay(10000); } //长延时,k=100大约对应1秒

  13. //========================AD转换=============================
  14. sfr P1ASF = 0x9D; //将P1置为模拟口寄存器(使能),各位中为1的有效
  15. sfr ADC_CONTR = 0xBC; //A/D转换控制寄存器
  16. sfr ADC_res   = 0xBD; //A/D转换结果寄存器
  17. sfr ADC_resl  = 0xBE; //A/D转换结果寄存器

  18. void set_channel(char channel){
  19. P1ASF = 1<<channel;
  20. ADC_CONTR = channel+128; //最高位是电源开关,低3位通道选择
  21. delay(1); //首次打开电源应延迟,使输入稳定
  22. }
  23. uint get_AD2(){
  24. ADC_CONTR |= 0x08;             //00001000,置ADC_START=1启动A/D 转换
  25. while ( !(ADC_CONTR & 0x10) ); //等待A/D转换结束(ADC_FLAG==0)
  26. ADC_CONTR &= 0xE7;             //11100111,置ADC_FLAG=0清除结束标记, 置ADC_START=0关闭A/D 转换
  27. return ADC_res*4 + ADC_resl;
  28. }

  29. /*
  30. uchar get_AD(){
  31. ADC_CONTR |= 0x08;             //00001000,置ADC_START=1启动A/D 转换
  32. while( !(ADC_CONTR & 0x10) );  //等待A/D转换结束(ADC_FLAG==0)
  33. ADC_CONTR &= 0xE7;             //11100111,置ADC_FLAG=0清除结束标记, 置ADC_START=0关闭A/D 转换
  34. return ADC_res;
  35. }
  36. */
  37. //============================EEPROW偏程=========================
  38. sfr IAP_data  = 0xC2;
  39. sfr IAP_addrH = 0xC3;
  40. sfr IAP_addrL = 0xC4;
  41. sfr IAP_cmd   = 0xC5;
  42. sfr IAP_trig  = 0xC6;
  43. sfr IAP_contr = 0xC7;
  44. /********************
  45. 写字节时,可以将原有数据中的1改为0,无法将0改为1,只能使用擦除命令将0改为1
  46. 应注意,擦除命令会将整个扇区擦除
  47. *********************/
  48. uchar readEEP(uint k){ //读取
  49. IAP_addrL = k;    //设置读取地址的低字节,地址改变才需要设置
  50. IAP_addrH = k>>8; //设置读取地址的高字节,地址改变才需要设置
  51. IAP_contr = 0x81; //设置等待时间,1MHz以下取7,2M以下取6,3M取5,6M取4,12M取3,20M取2,24M取1,30M取0,前导1表示许档IAP
  52. IAP_cmd = 1;      //读取值1,写取2,擦除取3,擦除时按所在字节整个扇区撺除
  53. IAP_trig = 0x5A;  //先送5A
  54. IAP_trig = 0xA5;  //先送5A再送A5立即触发
  55. return IAP_data;
  56. }
  57. void writeEEP(uint k, uchar da){ //写入
  58. IAP_data = da;    //传入数据
  59. IAP_addrL = k;    //设置读取地址的低字节,地址改变才需要设置
  60. IAP_addrH = k>>8; //设置读取地址的高字节,地址改变才需要设置
  61. IAP_contr = 0x81; //设置等待时间,1MHz以下取7,2M以下取6,3M取5,6M取4,12M取3,20M取2,24M取1,30M取0,前导1表示许档IAP
  62. IAP_cmd = 2;      //读取值1,写取2,擦除取3,擦除时按所在字节整个扇区撺除
  63. IAP_trig = 0x5A;  //先送5A
  64. IAP_trig = 0xA5;  //先送5A再送A5立即触发
  65. }
  66. void eraseEEP(uint k){ //擦除
  67. IAP_addrL = k;    //设置读取地址的低字节,地址改变才需要设置
  68. IAP_addrH = k>>8; //设置读取地址的高字节,地址改变才需要设置
  69. IAP_contr = 0x81; //设置等待时间,1MHz以下取7,2M以下取6,3M取5,6M取4,12M取3,20M取2,24M取1,30M取0,前导1表示许档IAP
  70. IAP_cmd = 3;      //读取值1,写取2,擦除取3,擦除时按所在字节整个扇区撺除
  71. IAP_trig = 0x5A;  //先送5A
  72. IAP_trig = 0xA5;  //先送5A再送A5立即触发
  73. }

  74. xdata struct Ida{
  75. int bas;    //比值基数
  76. } cs;

  77. void cs_RW(char rw){
  78. uchar i,*p = &cs;
  79. if(rw){
  80.   eraseEEP(0);
  81.   for(i=0;i<sizeof(cs);i++) writeEEP(i,p[i]);
  82. }else{
  83.   for(i=0;i<sizeof(cs);i++) p[i]=readEEP(i);
  84. }
  85. }





  86. /**********
  87. 字形编码图
  88.    32
  89.    -
  90. 64| | 128
  91.    -  16
  92. 1| | 8
  93.    _. 4
  94.    2
  95. **********/
  96. uchar code zk[20]={235,136,179,186,216,122,123,168,251,250}; //字库
  97. uchar code zk2[7]={241,25,11,233,27,50,155};//p,n,u,m,0,k,M

  98. uchar disp[6]={168,251,250}; char cx=-1; //显示缓存,cx光标位置
  99. sfr P1M1=0x91; //P1端口设置寄存器
  100. sfr P1M0=0x92; //P1端口设置寄存器
  101. sfr P0M1=0x93; //P0端口设置寄存器
  102. sfr P0M0=0x94; //P0端口设置寄存器
  103. sfr P2M1=0x95; //P2端口设置寄存器
  104. sfr P2M0=0x96; //P2端口设置寄存器
  105. sfr P3M1=0xB1; //P3端口设置寄存器
  106. sfr P3M0=0xB2; //P3端口设置寄存器

  107. sbit ds3=P2^4; //数码管扫描口
  108. sbit ds2=P2^5; //数码管扫描口
  109. sbit ds1=P2^6; //数码管扫描口
  110. sbit ds0=P2^7; //数码管扫描口

  111. sbit spk=P2^3; //蜂鸣器
  112. sbit Kb=P2^1; //量程开关B
  113. sbit Ka=P2^2; //量程开关A

  114. sbit DDS2=P1^2;//移相方波输出口
  115. sbit K3=P1^7;
  116. sbit K4=P1^6;
  117. sbit K5=P1^5; //7.8kHz滤波开关
  118. sbit K6=P1^4;
  119. sbit K8=P2^0; //100Hz滤波开关



  120. //==============字符显示函数====================
  121. xdata uchar menu=1,menuB=1;
  122. void cls(){ char i; for(i=0;i<6;i++) disp[i]=0; } //清屏
  123. void showDig(long f){ //显示数字
  124. uchar i;
  125. cls();
  126. for(i=0;i<6;i++) { disp[i]=zk[f%10], f/=10; if(!f) break; }
  127. }
  128. void showDig2(float f,char dw){ //显示浮点数
  129.   char i,b=0,b2=0,fh=0;
  130.   if(f<0) fh=1,f=-f;
  131.   for(i=0;i<2;i++){ if(f>=1000) f/=1000, b++;  }
  132.   for(i=0;i<4;i++){ if(f<1)     f*=1000, b--;  }
  133.   for(i=0;i<3;i++){ if(f<1000)  f*=10,   b2++; }
  134.   showDig(f);
  135.   disp[b2] += 4; //小数点
  136.   if(!dw) return;
  137.   disp[0] = zk2[b+4];  //显示单位
  138.   if(fh) disp[0] += 4; //显示符号
  139. }



  140. //==============低频信号DDS====================
  141. //PCA相关寄存器
  142. sfr CMOD = 0xD9;   //钟源选择控制等
  143. sfr CH = 0xF9;     //PCA的计数器
  144. sfr CL = 0xE9;     //PCA的计数器
  145. sfr CCON = 0xD8;   //PCA控制寄存器
  146. sfr CCPAM0 = 0xDA; //PCA模块0工作模式寄存器
  147. sfr CCPAM1 = 0xDB; //PCA模块1工作模式寄存器
  148. sfr CCAP0L = 0xEA; //模块0捕获寄存器低位
  149. sfr CCAP0H = 0xFA; //模块0捕获寄存器高位

  150. sbit PPCA  = IP^7;   //PCA的中断优先级设置
  151. sbit CCF0  = CCON^0; //PCA的模块0中断标志
  152. sbit CCF1  = CCON^1; //PCA的模块1中断标志
  153. sbit CR = CCON^6;    //PCA计数器使能

  154. void PWM_init(){ //把PCA置为PWM
  155.   CMOD = 2;   //0000 0010 计数源选择,钟源取fosc/2
  156.   CL = CH = 0;
  157.   CCAP0L = CCAP0H = 192; //占空比为25%
  158.   //CCPAM0=0x42;//0100 0010,PCA的模块0设置为PWM模式,无中断
  159.   CCPAM0=0x53;//0101 0011,PCA的模块0设置为PWM模式,有中断,下降沿中断
  160.   PPCA = 1;   //优先中断
  161.   //CR = 1;   //开始计数
  162.   EA = 1;     //开总中断
  163. }

  164. uint ph=0, phM=256, feq=1000; //相位,phM相位步进值
  165. uchar code sinB[256]={
  166. //查询表中不可装载零值,否则会造成无中断产生
  167. 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,
  168. 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,
  169. 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,
  170. 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,
  171. 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,
  172. 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,
  173. 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,
  174. 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
  175. };
  176. uchar code fbB[256]={ //方波DDS查询表
  177. 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,
  178. 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,
  179. 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,
  180. 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,
  181. 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,
  182. 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,
  183. 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,
  184. 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
  185. };
  186. uchar chuX=0; //方波DDS初相
  187. void PCAinter(void) interrupt 7 {//PCA中断
  188.   uchar x,y;
  189.   CCF0=0; //清除中断请求,以免反复中断
  190.   x = ph >> 8;     //截断正弦相位累加器,取高8位
  191.   y = x + chuX;    //方波相位
  192.   CCAP0H = sinB[x];//正弦DDS输出
  193.   DDS2 = fbB[y];   //方波DDS输出
  194.   ph += phM;       //相位累加
  195. }
  196. void setDDS(uint f){ //参考时钟是c=(fosc/2)/256=32000000/2/256=62500,频率f=c*phM/2^16
  197. feq = f;
  198. phM=f*65536.0/62500; //phM=f*2^16/62500
  199. ph = 0;              //高频时,使波形对称
  200. if(!f) CR=0; else CR=1;
  201. }

  202. //相位控制函数
  203. xdata char xw=0; //相位
  204. void set90(char k){ //设置方波的相位差
  205.   k %= 4;
  206.   if(k<0) k += 4;
  207.   if(k==0) chuX=0;   //移相0度
  208.   if(k==1) chuX=128; //移相180度
  209.   if(k==2) chuX=64;  //移相90度
  210.   if(k==3) chuX=192; //移相270度
  211.   xw = k;
  212. }
  213. void set902() { set90(xw+1); } //相位步进

  214. //==============量程控制函数====================
  215. xdata char rng=1; //量程
  216. void setRng(char k){//切换量程
  217. if(k==0) Ka=0,Kb=0; //100欧
  218. if(k==1) Ka=1,Kb=0; //1k欧
  219. if(k==2) Ka=0,Kb=1; //10k欧
  220. if(k==3) Ka=1,Kb=1; //100k欧
  221. rng = k;
  222. }
  223. void setRng2(){ setRng( (rng+1)%4); } //量程步进

  224. //==============增益控制函数====================
  225. float gain[4]={1,3,10,30};  //增益表
  226. char curGain=1; //当前增益索引号
  227. void setGain(char k){ //设置电路增益
  228.   if(k>3) k=3;
  229.   if(k<0) k=0;
  230.   if(k==0) K4=0,K6=0; //1倍
  231.   if(k==1) K4=0,K6=1; //3倍
  232.   if(k==2) K4=1,K6=0; //10倍
  233.   if(k==3) K4=1,K6=1; //30倍

  234.   curGain = k;
  235. }
  236. void setGain2(){ setGain((curGain+1)%4); }

  237. //==============设置频率====================
  238. uchar mT = 6; //测量速度
  239. void setF(char k){
  240.   if(k==-1){ //步进
  241.     k = 0;
  242.     if(feq==100)  k=1;
  243.     if(feq==1000) k=2;
  244.     if(feq==7813) k=0;
  245.   }
  246.   if(k==0) { setDDS(100);   K5=0; K8=1; mT=15; } //置为100Hz
  247.   if(k==1) { setDDS(1000);  K5=0; K8=0; mT=6;  } //置为1kHz
  248.   if(k==2) { setDDS(7813);  K5=1; K8=0; mT=6;  } //置为7.8125kHz
  249. }

  250. //==============LCR测量====================
  251. xdata int Vxy[4]={0,0,0,0};  //Vxy[Vx1,Vy1,Vx2,Vy2]
  252. xdata char Vga[4]={1,1,1,1}; //上下臂增益记录表
  253. xdata uchar tim=0,tims=0;
  254. xdata char pau=0; //暂停坐标自动旋转
  255. int Vfull = 950;
  256. void timerInter1(void) interrupt 3 {//T1中断
  257.   char a,g; int c;
  258.   static int Ve0=0;
  259.   if(pau) return;
  260.   tims++;
  261.   if(tims>=mT){ //tim进位触发
  262.    tims = 0, tim++;
  263.    if(tim>=8) tim=0;
  264.    a = tim/2; //x1,y1,x2,y2指针
  265.    c = get_AD2(); //读取电压值
  266.    if(c) c+=3;    //零点非线性改正
  267.    if(tim%2){
  268.      if(Ve0>c) Vxy[a] = Ve0; //保存当前电压
  269.          else      Vxy[a] = -c;
  270.          Vga[a] = curGain; //保存当前增益
  271.    }else Ve0 = c;
  272.    if(tim==3||tim==7){ //上下臂切换
  273.      //电压模值才能反应运放的输出幅度,所以增益切换判断得用模值
  274.          if(tim==3) K3=1, c = sqrt(1.0*Vxy[2]*Vxy[2]+1.0*Vxy[3]*Vxy[3]), g=Vga[2]; //切换到下臂
  275.          if(tim==7) K3=0, c = sqrt(1.0*Vxy[0]*Vxy[0]+1.0*Vxy[1]*Vxy[1]), g=Vga[0]; //切换到上臂
  276.          //切换后一定要设定一个g值,不论c为何值
  277.          setGain(g);
  278.      if(c>Vfull)       setGain(g-1);
  279.      if(c<Vfull/33*10) setGain(g+1);
  280.      if(c<Vfull/33*3)  setGain(g+2);
  281.      if(c<Vfull/33*1 ) setGain(g+3);
  282.    }
  283.    set90(tim+1); //相位旋转
  284.   }
  285. }

  286. char sfdw=1; //是否显示单位
  287. void showR(char xm){ //显示电阻
  288.   xdata float a,b,c,e;
  289.   xdata float x1 =  Vxy[0]/gain[Vga[0]];
  290.   xdata float y1 =  Vxy[1]/gain[Vga[1]];
  291.   xdata float x2 = -Vxy[2]/gain[Vga[2]];
  292.   xdata float y2 = -Vxy[3]/gain[Vga[3]];
  293.   xdata float bs;
  294.   char i;
  295.   for(i=0;i<4;i++){ //判断是否溢出
  296.     if(abs(Vxy[i])<Vfull) continue;
  297.     disp[0]=disp[1]=disp[2]=disp[3]=4;
  298.     return;
  299.   }
  300.   if(rng==0) bs=100;
  301.   if(rng==1) bs=1000;
  302.   if(rng==2) bs=10000;
  303.   if(rng==3) bs=100000;

  304.   a = x2*x2+y2*y2;
  305.   b = x1*x2+y1*y2;
  306.   c = x2*y1-x1*y2;
  307.   if(!a) { cls(); disp[3]=115;disp[2]=disp[1]=97; return; }
  308.   if(xm==0){ showDig2(c/a*bs,sfdw); }//显示X值
  309.   if(xm==1){ showDig2(b/a*bs,sfdw); }//显示R值
  310.   if(xm==2){ showDig2(c/a*bs / 6.283/feq, sfdw); }//显示L值
  311.   if(xm==3){ showDig2(a/c/bs / 6.283/feq, sfdw); }//显示C值
  312.   if(xm==4||xm==9){ //显示Q值
  313.     if(!b) { showDig(9999); return; }
  314.         c = fabs(c/b);
  315.         if     (c>=1000) { showDig(999   ); }
  316.     else if(c>=100 ) { showDig(c     ); }
  317.     else if(c>=10  ) { showDig(c*10  );  disp[1] += 4; }
  318.     else if(c>=1   ) { showDig(c*100 );  disp[2] += 4; }
  319.     else             { showDig(c*1000);  disp[3] += 4; }
  320.   }
  321.   e = (b*b+c*c)/a;
  322.   if(xm==5){ showDig2(e/c*bs,sfdw); }//显示并联X值
  323.   if(xm==6){ showDig2(e/b*bs,sfdw); }//显示并联R值
  324.   if(xm==7){ showDig2(e/c*bs / 6.283/feq,sfdw); }//显示并联L值
  325.   if(xm==8){ showDig2(c/e/bs / 6.283/feq,sfdw); }//显示并联C值

  326. }
  327. //void timerInter(void) interrupt 1 {}//T0中断

  328. void showMsg(uchar a){ //临时跳出信息
  329.   P0 = ~a;
  330.   ds0=1, ds1=ds2=ds3=0;
  331.   delay2(50);
  332. }
  333. main(){
  334. uchar i=0,j=0,kn=0,key=0;
  335. uchar dispN=0; //显示扫描索引
  336. uchar spkN=0;  //蜂鸣器发声时长
  337. uchar nn=0;
  338. uchar XRQ=1;


  339. TCON=0, TMOD=0x12; //将T0置为自动重装定时器,T1置为定时器
  340. TH1 = 47, TL1 = 171; //20ms秒定时
  341. TR1=1;  //T1开始计数
  342. TR0=0;  //T0暂停计数
  343. ET1=1;  //T1开中断
  344. ET0=1;  //T1开中断
  345. EA=1;   //开总中断
  346. PT0=1;  //设置优先级


  347. set_channel(0); //设置AD转换通道
  348. P2M0 = 0xFF;    //P2.01234567置为推勉输出
  349. P1M0 = 0xFC;    //P1.234567置为推换口
  350. P1M1 = 0x01;    //P1.0置为高阻抗

  351. //请注意启动延时0.5秒方可读取cs_RW
  352. //cs_RW(0); //读取比值基数(调零时已做开机延时,确保电压上升到可读取EEPROW)

  353. PWM_init();//DDS初始化
  354. set90(2);  //初始设置相位
  355. setRng(1); //初始设置量程
  356. setGain(1); //初始设置增益
  357. setF(1);    //DDS初始设置为1kHz

  358. while(1){
  359.   //显示disp
  360.   nn++;
  361.   dispN=(++dispN)%4; //扫描器移动
  362.   ds0=ds1=ds2=ds3=0;
  363.   if(dispN==0) ds0=1;
  364.   if(dispN==1) ds1=1;
  365.   if(dispN==2) ds2=1;
  366.   if(dispN==3) ds3=1;
  367.   P0=~disp[dispN]; //显示
  368.   //扫描键盘
  369.   //键盘响应
  370.   //key = (~P3)&0xfc;
  371.   key = ~P3;
  372.   if(key&&kn<255) kn++; else kn=0;
  373.   for(i=0;key;i++) key/=2; key=i;
  374.   if(kn==20) spkN=50; else key=0;   //当按下一定时间后,key才有效,否则无效。spkN发声时长设置
  375.   if(spkN) spkN--, spk=0; else spk=1; //键盘发声
  376.   //菜单系统
  377.   if(key==8 && menu!=0) { menuB=menu, menu=0; key=0; } //菜单键
  378.   if(key==7) setRng2(); //量程步进
  379.   if(key==6) setF(-1);  //设置频率
  380.   if(menu==0){ //显示量程和菜单
  381.     showDig(menuB);
  382.         if(key==8) menu = menuB;
  383.         if(key>=1&&key<=7) menu = key;
  384.         key = 0;
  385.   }
  386.   if(menu==1){ //自动LCR测量(串联)
  387.     pau = 0;
  388.         if(key>=1&&key<=5){ //扩展一位显示
  389.           if(key-1==XRQ) { if(sfdw==0) sfdw = 1; else sfdw = 0; }
  390.           else sfdw = 1;
  391.           XRQ = key-1; //X,R,L,C,Q
  392.         }
  393.         if(key>=1&&key<=5) XRQ = key-1; //X,R,L,C,Q
  394.     showR(XRQ);
  395.   }
  396.   if(menu==2){ //自动LCR测量(并联)
  397.     pau = 0;
  398.         if(key>=1&&key<=5){ //扩展一位显示
  399.           if(key-1==XRQ) { if(sfdw==0) sfdw = 1; else sfdw = 0; }
  400.           else sfdw = 1;
  401.       XRQ = key+4; //X,R,L,C,Q
  402.         }
  403.     showR(XRQ);
  404.   }
  405.   if(menu==3){ //手动调试
  406.     pau = 1;
  407.         if(key==1) { setGain2(); showMsg( zk[curGain] );} //增益控制
  408.         if(key==2) { };
  409.     if(key==3) { K3=~K3;     showMsg(zk[K3]);       } //切换上下臂
  410.     if(key==4) { set902();   showMsg(zk[xw]);       } //相位旋转
  411.     if(nn%16==0) showDig(get_AD2());
  412.   }
  413.   delay(4000);
  414. }//while end
  415. }

复制代码
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2011-10-10 20:21:52 | 显示全部楼层
电路图中没有给出开关集成电路的引脚号,这是因为连接洞洞板时,是按“贪心”法测接线的,即尽量连接最近的开关,减小跳线。这就造成电路的开关连接顺序与所画的电路不一定相同。程序设计时,是根据开关的逻辑关系编程的,不理引脚号码的,定义好端口与开关控制线的关系后,然后结合示波器就得知开关状态,接下来就知道开关逻辑。
这种贪心接线法,效果很好,板上接了上百条飞线,也没有出线错误。
现在要仿制的话,得根据程序反推开关所在位置及引脚号。否则得重新把洞洞板的电路翻译为电路图。
回复 支持 反对

使用道具 举报

     
发表于 2011-10-10 21:02:49 | 显示全部楼层
期待楼主出套件,先定一套。
回复 支持 反对

使用道具 举报

发表于 2011-10-10 21:09:01 | 显示全部楼层
100Hz可以测 10mF 电容吗 ? 同时ESR能测出来吗?
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2011-10-10 21:16:09 | 显示全部楼层
小电容、小电感测量的表现

合电容.jpg
残余电容.jpg
LCR表测得该电容为 23.8-3.46 = 20.3pF


Q表测主调电容.jpg
Q表测合电容.jpg
Q表测得该电容为532.6-512.5 = 20.1pF





LC表测电感.jpg
Q表测.jpg

LCR表测量这个电感的精度稍差一点,但精度还行。
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2011-10-10 21:20:26 | 显示全部楼层
本帖最后由 xjw01 于 2011-10-10 21:22 编辑

Q表测量该电容时,我采用1.1MHz测量。
Q表测量该电感时,我采用4.0MHz测量。
回复 支持 反对

使用道具 举报

     
发表于 2011-10-10 22:05:12 | 显示全部楼层
回复 68# xjw01
LZ你这个表测ESR和ESR表测得的结果相比,数值上会有多大的误差呢?
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2011-10-10 22:30:23 | 显示全部楼层
本帖最后由 xjw01 于 2011-10-10 22:54 编辑

回复 69# 362647315


    我没有ESR表啊。
我测定ESR是采用DDS加毫伏表测量的
电解电容的ESR,在10kHz以后,ESR变化不大。用自谐振法、电桥法, 测出来的结果都差不多。

ESR指的就是等效串联电阻,LCR当然可以测量。 而且测量比较准确。
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2011-10-10 23:31:05 | 显示全部楼层
回复 66# jarvis31


    可以测量。
  不过,刚才测了一个6800uF电容,自动增益控制有问题,看来还得再调试一下,精度没有上去。
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2011-10-11 07:04:17 | 显示全部楼层
已查明,是昨天改进程序反而出了问题。现在已改回来。
电路中有一个元件的取值也不合理,已更换。
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2011-10-11 07:10:22 | 显示全部楼层
本帖最后由 xjw01 于 2011-10-11 07:12 编辑

测6800uF,得到5400uF,估计是我那个电容的容量偏小。
程序与电路图已更新。

测量这个是电容,上臂还有53字的Vy读数,精度还可以
测量时,采用了输助机械开关。
如果不采用输助开关,测值偏小一点,测量10000uF以上精度差。用了输助开关,测量下限提升了5倍以上。
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2011-10-11 07:15:08 | 显示全部楼层
这个电路最难设计的是100Hz档。
100Hz档的末级滤波器不好弄。滤波电容加大,时间常数大,影响测量速度。减小滤波器,纹波大。
1kHz最容易。
10kHz,DDS的输出滤波器不好设计。
回复 支持 反对

使用道具 举报

     
发表于 2011-10-11 07:31:39 | 显示全部楼层
DIY达到0.5级,叹为观止。还是用洞洞板搭的。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入会员

本版积分规则

小黑屋|手机版|矿石收音机 ( 蒙ICP备05000029号-1 )

蒙公网安备 15040402000005号

GMT+8, 2024-5-7 12:54

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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