該電橋,具有價格便宜,性能精度能滿足一般電子愛好者的使用,電路方面許老師的自述文件里都有介紹,現(xiàn)提供熱心網(wǎng)友提供的更新程序,最后聲明:所有文件的所有權(quán)益歸原作者許老師所有.
單片機源程序如下:
- //==========================================================================
- // LCR表驅(qū)動程序 V2.0
- // 許劍偉 于莆田 2012.01
- //==========================================================================
- //==========================================================================
- #define uchar unsigned char
- #define uint unsigned int
- #define ulong unsigned long
- #include <reg52.h>
- #include <math.h>
- //==========================================================================
- // 項目:LCD1602 四線驅(qū)動程序
- // 設(shè)計要點:
- // LCD1602 的運行速度慢,而單片機運行的速度快,因此容易因為速度不
- // 匹配造成調(diào)試失敗。因此,調(diào)試之前應(yīng)準確測試lcd_delay() 延時函數(shù)
- // 準確的延時量,如果不能滿足注釋中的要求,則應(yīng)調(diào)整循次數(shù)。每步操
- // 作所需的延時量,按照數(shù)據(jù)手冊指標指行,同時留下足夠的時間余量。
- // 硬件連接:
- // 至少需要9條線,電源線2條,7條信號線。信號線詳見程序中的接口定義。
- // 清注意對LCD1602對比度的調(diào)節(jié),否則無顯示。
- // 設(shè)計:許劍偉,于莆田,2010.12
- //==========================================================================
- sbit lcd_RS = P0^6; //數(shù)據(jù)命令控制位,0命令1數(shù)據(jù)
- sbit lcd_RW = P0^5; //讀寫位,0寫1讀
- sbit lcd_EN = P0^4; //使能位,下降沿觸發(fā)
- sbit lcd_D4 = P0^3; //數(shù)據(jù)端口D4
- sbit lcd_D5 = P0^2; //數(shù)據(jù)端口D5
- sbit lcd_D6 = P0^1; //數(shù)據(jù)端口D6
- sbit lcd_D7 = P0^0; //數(shù)據(jù)端口D7
- //==========================================================================
- code char path[32]={
- 0x00,0x00,0x0e,0x11,0x11,0x0a,0x1b,0x00,
- 0x00,0x11,0x11,0x13,0x1d,0x10,0x10,0x10,
- 0x0e,0x11,0x1f,0x11,0x11,0x0e,0x00,0x00,
- 0x1C,0x10,0x1B,0x12,0x1B,0x01,0x07,0x00
- };//自定義符號
- char binLian=0,ATA=0,ATB=1;
- char OX[8]={0,0,0,0,0,0,8,0};
- int DDS3=1, c3 = 0; //交替顯示變量
- char digW=4; //數(shù)字顯示位數(shù)宏
- code uchar abc[][5]={
- " err"," 40"," 120"," 360"," 1080"," 1K"," 3K"," 9K"," 27K"," 10K",
- " 30K"," 90K"," 270K"," 100K"," 300K"," 900K"," 2.7M"," 13"," 4.5"," 1.5"
- };
- void lcd_delay(int n){ //LCD專用延時函數(shù)
- //32MHz鐘頻下,約循環(huán)3000次延遲1毫秒
- int i,j;
- if(n<0) { for(i=0;i< 30;i++); return; } //10us
- if(n== 0) { for(i=0;i<150;i++); return; } //50us
- for(;n;n--){ for(j=0;j<3000;j++); } //n毫秒
- }
- //==========================================================================
- void lcd_B(char f, uchar c, char t){ //控制四線式接口LCD的7個腳
- //f=0寫命令字, f=1寫RAM數(shù)據(jù), f=2讀地址(或讀忙), f=3讀RAM數(shù)據(jù)
- lcd_EN = 0;
- lcd_RS = f%2;
- lcd_RW = f/2%2;
- //移入高四位
- lcd_D4 = c & 16;
- lcd_D5 = c & 32;
- lcd_D6 = c & 64;
- lcd_D7 = c & 128;
- lcd_EN = 1; lcd_delay(-1); lcd_EN = 0; //使能脈沖
- if(f==4) { lcd_delay(t); return; }
- //移入低四位
- lcd_D4 = c & 1;
- lcd_D5 = c & 2;
- lcd_D6 = c & 4;
- lcd_D7 = c & 8;
- lcd_EN = 1; lcd_delay(-1); lcd_EN = 0; //使能脈沖
- lcd_delay(t); //不同的命令,響應(yīng)時間不同,清零命令需要2ms
- }
- //==========================================================================
- void lcd_init(){ //LCD1602 初始化
- //啟動四線模式須勢行9個步驟,初始化所須耗時較長,約65ms,時限不可減
- lcd_delay(20); //啟動lcd之前須延時大于15ms,直到VDD大于4.5V
- lcd_B(4, 0x30, 9); //置8線模式,須延時大于4.1ms
- lcd_B(4, 0x30, 5); //置8線模式,須延時大于100us
- lcd_B(4, 0x30, 5); //置8線模式,手冊中未指定延時
- lcd_B(4, 0x20, 5); //進入四線模式
- lcd_B(0, 0x28, 5); //四線模式雙行顯示
- lcd_B(0, 0x0C, 5); //打開顯示器
- lcd_B(0, 0x80, 5); //RAM指針定位
- lcd_B(0, 0x01, 5); //啟動清屏命初始化LCD
- }
- //==========================================================================
- //=========================幾個功能常用函數(shù)=================================
- void lcd_cls() { lcd_B(0, 0x01+0, 2); } //清屏
- void lcd_cur0() { lcd_B(0, 0x0C+0, 0); } //隱藏光標
- void lcd_goto1(uchar x){if(ATB) lcd_B(0, 0x80+x, 0); else lcd_B(0, 0x94+x, 0);} //設(shè)置DDRAM地址,第1行x位
- void lcd_goto2(uchar x){if(ATB) lcd_B(0, 0xC0+x, 0); else lcd_B(0, 0xD4+x, 0);} //設(shè)置DDRAM地址,第2行x位
- void lcd_goto3(uchar x){if(ATB) lcd_B(0, 0x94+x, 0); else lcd_B(0, 0x80+x, 0);} //設(shè)置DDRAM地址,第3行x位
- void lcd_goto4(uchar x){if(ATB) lcd_B(0, 0xD4+x, 0); else lcd_B(0, 0xC0+x, 0);} //設(shè)置DDRAM地址,第4行x位
- void lcd_putc(uchar d) { lcd_B(1, 0x00+d, 0); } //字符輸出
- void lcd_puts(uchar *s){ for(; *s; s++) lcd_B(1,*s,0); } //字串輸出
- //==============字符顯示函數(shù)====================
- void lcd_putp(float a,float b,char bo,char n, float qmin){ //帶單位顯示復(fù)數(shù),n是單位下限,qmin是最小位權(quán)值(用于限定有效數(shù)字)
- code uchar dwB[] = {'p','n','u','m',' ','k','M','G'}; //單位表
- char i,j, c=0, h=digW-1, fh[2]={' ','+'};
- long d,q,qm,Q=1; //最高位權(quán)
- float f,g=1;
- if(a<0) fh[0] = '-', a = -a;
- if(b<0) fh[1] = '-', b = -b;
- if(a>b) f = a; else f = b;
- for(i=1;i<digW;i++) Q *= 10;
- for(i=0;i<3;i++){ if(f*g >= 1000) g/=1000, c++; } //以3位為單位移動小數(shù)點,右移
- for(i=0;i<n;i++){ if(f*g < 1) g*=1000, c--; } //以3位為單位移動小數(shù)點,左移
- if ((n==1)&&(c==-1)){
- for(i=1;i<2 && f*g<Q;i++) g*=10,h--; //繼續(xù)移動小數(shù)點,使之滿字
- }else if ((n==2)&&(c==-2)){
- for(i=1;i<3 && f*g<Q;i++) g*=10,h--; //繼續(xù)移動小數(shù)點,使之滿字
- }else if ((n==4)&&(c==-4)){
- for(i=1;i<2 && f*g<Q;i++) g*=10,h--; //繼續(xù)移動小數(shù)點,使之滿字
- }else{
- for(i=1;i<digW && f*g<Q;i++) g*=10,h--; //繼續(xù)移動小數(shù)點,使之滿字
- }
- qm = g*qmin;
- for(i=0;i<2;i++){
- if(i) d = b*g; //取出實部
- else d = a*g; //取出虛部
- if(qm) d+=qm/2, d-=d%qm;//去除小于qmin的尾數(shù)
- q = Q;
- lcd_putc(fh[i]); //顯示符號
- for(j=0; j<digW; j++){ //數(shù)字輸出
- lcd_putc(d/q+48); //數(shù)字
- if(j==h) lcd_putc('.');//小數(shù)點
- d %= q, q /= 10;
- }
- if(!bo) break; //不顯示虛部
- }
- //lcd_putc(dwB[c+4]); //單位
- if(dwB[c+4]=='u') { lcd_putc(9);} else {
- if(n==1){
- if(dwB[c+4]==' ') { lcd_putc(8); OX[6]=32; } else { lcd_putc(dwB[c+4]); OX[6]=8; } //自動單位
- }
- else { lcd_putc(dwB[c+4]); OX[6]=8; }
- } //符號
- }
- void lcd_putf(float a, char n, float qmin) //帶單位顯示浮點數(shù),n是單位下限
- { lcd_putp(a,0,0,n,qmin); }
- void lcd_int(int a,char w){ //定寬顯示正整數(shù)
- char i=0, s[5] = {' ',' ',' ',' ',' '};
- if(a<0) { a=-a; lcd_puts("-"); }
- else lcd_puts(" ");
- do{
- s[i++] = a%10+48;
- a /= 10;
- }while(a);
- for(;w;w--) lcd_putc(s[w-1]);
- }
- //==========================================================================
- //===============================延時函數(shù)===================================
- void delay(uint loop) { uint i; for(i=0;i<loop;i++); } //延時函數(shù)
- void delay2(uint k) { for(;k>0;k--) delay(10000); } //長延時,k=100大約對應(yīng)1秒
- //==========================================================================
- //=================================AD轉(zhuǎn)換===================================
- sfr P1ASF = 0x9D; //將P1置為模擬口寄存器(使能),各位中為1的有效
- sfr ADC_CONTR = 0xBC; //A/D轉(zhuǎn)換控制寄存器
- sfr ADC_res = 0xBD; //A/D轉(zhuǎn)換結(jié)果寄存器
- sfr ADC_resl = 0xBE; //A/D轉(zhuǎn)換結(jié)果寄存器
- void set_channel(char channel){
- P1ASF = 1<<channel;
- ADC_CONTR = channel+128; //最高位是電源開關(guān),低3位通道選擇
- delay(1); //首次打開電源應(yīng)延遲,使輸入穩(wěn)定
- }
- uint getAD2(){
- ADC_CONTR |= 0x08; //00001000,置ADC_START=1啟動A/D 轉(zhuǎn)換
- while ( !(ADC_CONTR & 0x10) ); //等待A/D轉(zhuǎn)換結(jié)束(ADC_FLAG==0)
- ADC_CONTR &= 0xE7; //11100111,置ADC_FLAG=0清除結(jié)束標記, 置ADC_START=0關(guān)閉A/D 轉(zhuǎn)換
- return ADC_res*4 + ADC_resl;
- }
- /*
- uchar get_AD(){
- ADC_CONTR |= 0x08; //00001000,置ADC_START=1啟動A/D 轉(zhuǎn)換
- while( !(ADC_CONTR & 0x10) ); //等待A/D轉(zhuǎn)換結(jié)束(ADC_FLAG==0)
- ADC_CONTR &= 0xE7; //11100111,置ADC_FLAG=0清除結(jié)束標記, 置ADC_START=0關(guān)閉A/D 轉(zhuǎn)換
- return ADC_res;
- }
- */
- //==========================================================================
- //==================================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;
- /********************
- 寫字節(jié)時,可以將原有數(shù)據(jù)中的1改為0,無法將0改為1,只能使用擦除命令將0改為1
- 應(yīng)注意,擦除命令會將整個扇區(qū)擦除
- *********************/
- int eepEn = 0;
- void saEEP(){ //觸發(fā)并EEP保護
- if(eepEn==12345) IAP_trig = 0x5A; //先送5A
- if(eepEn==12345) IAP_trig = 0xA5; //先送5A再送A5立即觸發(fā)
- IAP_cmd = 0; //關(guān)閉令,保護
- IAP_contr = 0; //關(guān)EEPROM,保護
- IAP_trig = 0;
- IAP_addrL = 255; //設(shè)置讀取地址的低字節(jié),地址改變才需要設(shè)置
- IAP_addrH = 255; //設(shè)置讀取地址的高字節(jié),地址改變才需要設(shè)置
- }
- uchar readEEP(uint k){ //讀取
- IAP_addrL = k; //設(shè)置讀取地址的低字節(jié),地址改變才需要設(shè)置
- IAP_addrH = k>>8; //設(shè)置讀取地址的高字節(jié),地址改變才需要設(shè)置
- IAP_contr = 0x81; //設(shè)置等待時間,1MHz以下取7,2M以下取6,3M取5,6M取4,12M取3,20M取2,24M取1,30M取0,前導(dǎo)1表示許檔IAP
- IAP_cmd = 1; //讀取值1,寫取2,擦除取3,擦除時按所在字節(jié)整個扇區(qū)攛除
- saEEP(); //觸發(fā)并保護
- return IAP_data;
- }
- void writeEEP(uint k, uchar da){ //寫入
- IAP_data = da; //傳入數(shù)據(jù)
- IAP_addrL = k; //設(shè)置讀取地址的低字節(jié),地址改變才需要設(shè)置
- IAP_addrH = k>>8; //設(shè)置讀取地址的高字節(jié),地址改變才需要設(shè)置
- IAP_contr = 0x81; //設(shè)置等待時間,1MHz以下取7,2M以下取6,3M取5,6M取4,12M取3,20M取2,24M取1,30M取0,前導(dǎo)1表示許檔IAP
- IAP_cmd = 2; //讀取值1,寫取2,擦除取3,擦除時按所在字節(jié)整個扇區(qū)攛除
- saEEP(); //觸發(fā)并保護
- }
- void eraseEEP(uint k){ //擦除
- IAP_addrL = k; //設(shè)置讀取地址的低字節(jié),地址改變才需要設(shè)置
- IAP_addrH = k>>8; //設(shè)置讀取地址的高字節(jié),地址改變才需要設(shè)置
- IAP_contr = 0x81; //設(shè)置等待時間,1MHz以下取7,2M以下取6,3M取5,6M取4,12M取3,20M取2,24M取1,30M取0,前導(dǎo)1表示許檔IAP
- IAP_cmd = 3; //讀取值1,寫取2,擦除取3,擦除時按所在字節(jié)整個扇區(qū)攛除
- saEEP(); //觸發(fā)并保護
- }
- xdata struct Ida{
- char zo[3];//三個頻率下的零點改正值
- char j1; //相位補償(3倍檔)
- char j2; //相位補償(10倍檔)
- char J[4]; //相位補償(V/I變換器)
- char R[4]; //下臂電阻修正(40,1k,10k,100k)
- char g1; //增益修正(3倍檔)
- char g2; //增益修正(10倍檔)
- char phx; //1kHz以下相位改正
- char R4b; //100k檔7.8kHz頻率下的幅度補償
- char G2b; //9倍檔7.8kHz頻率下的幅度補償
- char feq; //頻率修正
- char ak; //AD斜率修正
- float QRs[3],QXs[3]; //短路清零數(shù)據(jù)
- float QRo[3],QXo[3]; //開路清零數(shù)據(jù)
- } cs;
- void cs_RW(char rw){
- uchar i,*p = &cs;
- const int offs=512;
- if(rw){
- delay2(10); //等待(防止掉電誤識別鍵盤而調(diào)用本函數(shù))
- eraseEEP(offs);
- for(i=0;i<sizeof(cs);i++) writeEEP(i+offs,p[i]);
- }else{
- for(i=0;i<sizeof(cs);i++) p[i]=readEEP(i+offs);
- }
- }
- //==========================================================================
- //==================================LCR主程序===============================
- //==========================================================================
- sfr P1M1=0x91; //P1端口設(shè)置寄存器
- sfr P1M0=0x92; //P1端口設(shè)置寄存器
- sfr P0M1=0x93; //P0端口設(shè)置寄存器
- sfr P0M0=0x94; //P0端口設(shè)置寄存器
- sfr P2M1=0x95; //P2端口設(shè)置寄存器
- sfr P2M0=0x96; //P2端口設(shè)置寄存器
- sfr P3M1=0xB1; //P3端口設(shè)置寄存器
- sfr P3M0=0xB2; //P3端口設(shè)置寄存器
- sbit spk=P2^3; //蜂鳴器
- sbit Kb=P2^1; //量程開關(guān)B
- sbit Ka=P2^2; //量程開關(guān)A
- sbit DDS2=P1^2;//移相方波輸出口
- sbit K3=P1^7;
- sbit K4=P1^6;
- sbit K5=P1^5; //7.8kHz濾波開關(guān)
- sbit K6=P1^4;
- sbit K8=P2^0; //100Hz濾波開關(guān)
- sbit K32=P1^1; //32kHz發(fā)生器
- xdata uchar menu=1,menu2=0; //菜單變量
- //==============低頻信號DDS相關(guān)參數(shù)====================
- //PCA相關(guān)寄存器
- sfr CMOD = 0xD9; //鐘源選擇控制等
- sfr CH = 0xF9; //PCA的計數(shù)器
- sfr CL = 0xE9; //PCA的計數(shù)器
- sfr CCON = 0xD8; //PCA控制寄存器
- sfr CCPAM0 = 0xDA; //PCA模塊0工作模式寄存器
- sfr CCPAM1 = 0xDB; //PCA模塊1工作模式寄存器
- sfr CCAP0L = 0xEA; //模塊0捕獲寄存器低位
- sfr CCAP0H = 0xFA; //模塊0捕獲寄存器高位
- sfr IPH = 0xB7;
- sbit PPCA = IP^7; //PCA的中斷優(yōu)先級設(shè)置
- sbit CCF0 = CCON^0; //PCA的模塊0中斷標志
- sbit CCF1 = CCON^1; //PCA的模塊1中斷標志
- sbit CR = CCON^6; //PCA計數(shù)器使能
- uint ph=0, phM=256, feq=977; //相位,phM相位步進值
- uchar *ph8 = (char*)&ph; //ph的高8位地址
- xdata float feqX=976.6; //實際輸出頻率
- uchar code sinB[256]={
- //查詢表中不可裝載零值,否則會造成無中斷產(chǎn)生
- 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,
- .......
- uchar chuX=0; //方波DDS初相
- //==============低頻信號DDS函數(shù)====================
- void PWM_init(){ //把PCA置為PWM
- CMOD = 2; //0000 0010 計數(shù)源選擇,鐘源取fosc/2
- CL = CH = 0;
- CCAP0L = CCAP0H = 192; //占空比為25%
- //CCPAM0=0x42;//0100 0010,PCA的模塊0設(shè)置為PWM模式,無中斷
- CCPAM0=0x53;//0101 0011,PCA的模塊0設(shè)置為PWM模式,有中斷,下降沿中斷
- PPCA = 1; //優(yōu)先中斷
- IPH |= 128;
- //CR = 1; //開始計數(shù)
- EA = 1; //開總中斷
- }
- void PCAinter(void) interrupt 7 {//PCA中斷
- uchar x,y;
- CCF0=0; //清除中斷請求,以免反復(fù)中斷
- x = *ph8; //截斷正弦相位累加器,取高8位
- y = x + chuX; //方波相位
- CCAP0H = sinB[x];//正弦DDS輸出
- if(DDS3) { DDS2 = fbB[y]; //方波DDS輸出
- }else {DDS2 = 0;}
- ph += phM; //相位累加
- K32 = ~K32;
- }
- 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*(1+cs.feq/10000.0); //實際輸出頻率
- ph = 0; //高頻時,使波形對稱
- if(!f) CR=0; else CR=1;
- }
- //相位控制函數(shù)
- xdata char xw=0; //相位
- void set90(char k){ //設(shè)置方波的相位差
- 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); } //相位步進
- //==============量程控制函數(shù)====================
- xdata char rng=1; //量程
- void setRng(char k){//切換量程
- if(k>3) k=3;
- if(k<0) k=0;
- if(k==0) Ka=0,Kb=0; //40歐
- 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); } //量程步進
- //==============增益控制函數(shù)====================
- char curGain=1; //當前增益索引號
- void setGain(char k){ //設(shè)置電路增益
- 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; //9倍
- if(k==3) K4=1,K6=1; //27倍
- curGain = k;
- }
- void setGain2(){ setGain((curGain+1)%4); }
- //==============AD非線性改正與過采樣=================
- uint getAD10(){ //120次采樣,用reentrant申明,有的單片機無法運行
- int i;
- long c;
- for(i=0;i<250;i++) c += getAD2();
- return (c+12)/25;
- }
- uint getAD10b(){ //120次采樣,用reentrant申明,有的單片機無法運行
- xdata long c = 0, c2 = 0;
- int i;
- for(i=0;i<250;i++){
- ADC_CONTR |= 0x08; //00001000,置ADC_START=1啟動A/D 轉(zhuǎn)換
- while ( !(ADC_CONTR & 0x10) ); //等待A/D轉(zhuǎn)換結(jié)束(ADC_FLAG==0)
- ADC_CONTR &= 0xE7; //11100111,置ADC_FLAG=0清除結(jié)束標記, 置ADC_START=0關(guān)閉A/D 轉(zhuǎn)換
- c += ADC_resl;
- c2 += ADC_res;
- }
- c3 = c;
- c = ( c2*4L + c )/25;
- c3= ( c2*4L + c3 ) -c*25;
- return c;
- }
- //==============LCR測量====================
- code float ga[4] = { 1, 3, 9, 27 }; //增益表
- code float dwR[4] = { 40, 1e3, 1e4, 1e5 }; //各檔電阻表
- xdata int Vxy[12]={0,0,0,0,1,1}; //Vxy[Vx1,Vy1,Vx2,Vy2,g1,g2]
- xdata char Sxw[4]={0,1,0,1}; //保存正確相位
- xdata int Vz[24]; //LCR測量結(jié)果隊
- xdata uchar tim=0,tims=0;
- xdata char pau=0; //暫停坐標自動旋轉(zhuǎn)
- xdata char isQ=1;
- #define Vfull 9600
- #define gad (9600/30)
- uchar mT = 6; //測量速度,mT取值為6或12或24時,可以消除數(shù)字噪聲,尾數(shù)不動,但不利于于取平均
- //==============設(shè)置頻率====================
- xdata char feqK=1; //頻率索引號
- void setF(char k){
- if(k==-1) k = (feqK+1)%3; //步進
- feqK = k;
- if(k==0) { setDDS(100); K5=0; K8=1; mT=12; } //置為100Hz
- if(k==1) { setDDS(977); K5=0; K8=0; mT=6; } //置為1kHz
- if(k==2) { setDDS(7813); K5=1; K8=0; mT=6; } //置為7.8125kHz
- TH1 = 150, TL1 = 171; //置為20ms
- tims = 0;
- tim = 0;
- ph = 0;
- }
- int absMax(int a,int b){ //取兩個數(shù)絕對值最大者
- if(a<0) a = -a;
- if(b<0) b = -b;
- if(b>a) a = b;
- return a;
- }
- char yc1=0,yc2=0; //溢出標識
- char slw = 1; //降速倍率
- char chg=0; //量程切換標記
- void timerInter1(void) interrupt 3 {//T1中斷,LCR數(shù)據(jù)采集
- code int y[5]={0,-15,30,24,0}; //滿度用30
- code int x[5]={4900,5090,5140,5500,6120};
- char g,gb,Rb,i; int c=0,cc=0;
- tims++;
- if(tims>=mT/slw) tims = 0, tim++, c = 1;
- if(tim>=4) tim=0;
- if(pau) return;
- if(!c) return; //tim未進位觸發(fā)
- c = getAD10b(); //讀取電壓值
- cc= c3;
- c -= cs.zo[feqK];
- if(cs.ak>0){
- for(i=0;i<4;i++){ //非線性改正
- if(c<x[i]||c>=x[i+1]) continue;
- c += cs.ak*( y[i] + (y[i+1]-y[i]) * ((int)(c-x[i])) / (x[i+1]-x[i]) ) / 30;
- break;
- }
- }
-
- Vxy[tim] = xw<2 ? c : -c; //保存當前電壓
- Vxy[tim+6] = xw<2 ? cc : -cc; //保存當前電壓
- Vxy[tim/2+4] = curGain; //保存當前增益
- Sxw[tim] = ( Sxw[tim]+(c<0 ? 2 : 0) )%4; //相位翻轉(zhuǎn)(預(yù)測下次的相位采用值)
- if(tim==1||tim==3){ //上下臂切換
- if(tim==1) { K3=1, c = absMax(Vxy[2],Vxy[3]), g=Vxy[5]; yc2 = c>Vfull ? 1:0; }//切換到下臂
- if(tim==3) { K3=0, c = absMax(Vxy[0],Vxy[1]), g=Vxy[4]; yc1 = c>Vfull ? 1:0; }//切換到上臂
- gb=g, Rb=rng;
- if(c>Vfull){ if(g==0&&rng>0&&K3&&isQ) Rb=rng-1; gb=0; }
- else if(c<gad*1 ) gb = g+3; //增加27倍
- else if(c<gad*3 ){ gb = g+2;if(c<gad*2&&rng>=1&&rng<=2&&K3&&isQ ) { gb=0; Rb=rng+1; }} //增加9倍
- else if(c<gad*9) gb = g+1; //增加3倍
- if(gb>3) gb = 3;
- if(g==3&&rng<3&&K3&&isQ) { gb=0; Rb=rng+1; }
- if(g==0&&c<gad*1&&rng<3&&K3&&isQ) { gb=0; Rb=rng+1; }
- setRng(Rb); setGain(gb); //置量程
- if(gb!=g || Rb!=rng) slw = 2, chg++; //量程正在改變,則加速測量
- if(tim==3){ if(!chg) slw=1; chg=0; }
- }
- set90( Sxw[ (tim+1)%4 ] ); //相位旋轉(zhuǎn)
- if(tim==3){ for(i=0;i<12;i++) Vz[i+12]=Vz[i], Vz[i]=Vxy[i]; }
- }
- void showR(char binLian, char showk){ //顯示LCR
- xdata float a=0,b=0,c=0,qq=0,dd=0,e,w,L,C;
- xdata int gr=cs.R[rng], g1=cs.g1, g2=cs.g2;
- xdata int g12 = g1 + g2; //增益最大補償
- xdata int j12 = (int)cs.j1+cs.j2; //相位最大補償
- xdata float JD = 0, G = 0, cJD; //補償變量
- xdata float v[4];
- xdata char ATC=0,d3=1;
- //LCR計算
- if(feqK<0||feqK>2) return;
- if(feq==7813&&rng==3) gr += cs.R4b; //7.8kHz時下臂修正量
- //可控增益單元的增益修正、相位補償量
- if(feq==7813) g2 += cs.G2b; //7.8kHz時9倍檔修正量
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復(fù)制代碼
所有資料51hei附件下載:
2004程序_3.0_全自動電橋V1.rar
(28.53 KB, 下載次數(shù): 470)
2021-10-21 08:35 上傳
點擊文件名下載附件
LCR 下載積分: 黑幣 -5
LCR數(shù)字電橋自制方案.pdf
(1.39 MB, 下載次數(shù): 412)
2021-10-21 19:04 上傳
點擊文件名下載附件
LCR 下載積分: 黑幣 -5
LCR數(shù)字電橋.docx
(257.25 KB, 下載次數(shù): 337)
2021-10-21 08:29 上傳
點擊文件名下載附件
LCR 下載積分: 黑幣 -5
|