自制儀表仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png (5.44 KB, 下載次數: 72)
下載附件
2019-8-8 04:27 上傳
單片機源程序如下:
- #include<reg52.h>
- #define uchar unsigned char //宏定義
- #define uint unsigned int
- sbit RS=P2^6; //液晶控制端口
- sbit RW=P2^5;
- sbit E=P2^7;
- sbit R=P2^2; //RLC控制按鍵
- sbit C=P2^3;
- sbit L=P2^4;
- sbit A=P2^0; //控制IO口
- sbit B1=P2^1;
- sbit jd1=P1^0; //繼電器1
- sbit jd2=P1^1; //繼電器2
- sbit LED_R=P1^3; //RLC指示燈
- sbit LED_C=P1^4;
- sbit LED_L=P1^5;
- uchar code table1[11]={"R= R"}; //RLC顯示數組
- uchar code table2[11]={"C= pF"};
- uchar code table3[11]= {"L= mH"};
- uchar code f_table[88]={13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100};
- uchar code f_correct[88]={9,10,11,12,12,12,13,14,15,16,17,18,18,18,19,20,21,21,22,23,24,25,25,26,26,27,28,29,29,30,30,31,32,33,33,34, 35,35,36,37,38,38,39,40,41,41,42,42,43,44,45,45,46,47,48,49,49,50,51,51,52,53,54,54,55,55,56,57,57,58,59,60,60,62,62,63,64,64,65,66,66,67,67,68,69,70,71,71,};
- uchar data7,data6,data5,data4,data3,data2,data1; //數據變量
- uchar flag; //轉換完成標志位
- unsigned long cnt,cnt1; //長整形數據 記錄振蕩器計數的次數
- uchar f_cnt; //時間溢出次數變量
- //函數聲明
- void delay_us(); //us延時
- void delay_ms(uint); //ms延時
- void lcd_init(); //1602初始化
- void lcd_write_com(uchar com); //寫命令
- void lcd_write_dat(uchar dat); //寫數據
- void lcd_display(uchar add,uchar dat); //指定地址寫數據
- void delay_us() //us延時
- {
- uchar x=6;
- while(x--);
- }
- void delay_ms(uint aa) //ms延時
- {
- uint x,y;
- for(x=0;x<aa;x++)
- for(y=0;y<110;y++);
- }
- void lcd_write_com(uchar com) //寫命令
- {
- E=0;
- RS=0;
- RW=0;
- delay_us();
- P0=com;
- E=1;
- delay_us();
- E=0;
- }
- void lcd_write_dat(uchar dat) //寫數據
- {
- E=0;
- RS=1;
- RW=0;
- delay_us();
- P0=dat;
- E=1;
- delay_us();
- E=0;
- }
- void lcd_init() //lcd初始化
- {
- delay_ms(10);
- lcd_write_com(0x38); //設置顯示模式
- delay_ms(10);
- lcd_write_com(0x0c);
- lcd_write_com(0x06);
- lcd_write_com(0x01); //清屏指令
- delay_ms(2);
- }
- void timer_init(void) //定時器初始化函數
- {
- TMOD=0X51; //設置定時器工作模式
- PT0=1;
- TH0=0x3c; //給定時器0裝設初值 50ms
- TL0=0xb0;
- TH1=0; //不設初值
- TL1=0;
- ET0=1; //開中斷
- ET1=1;
- TR0=1; //開定時器
- TR1=1;
- EA=1; //開總中斷
- }
- void lcd_display(uchar add,uchar dat) //lcd指定地址寫數據
- {
- lcd_write_com(add);
- lcd_write_dat(dat);
- delay_us();
- }
- void real_display(void) //數據顯示函數
- {
- if(!R) //檢測的是電阻
- {
- A=0;B1=0;
- LED_R=0;
- LED_L=1;
- LED_C=1;
- lcd_display(0x80,table1[0]);
- lcd_display(0x80+1,table1[1]);
- lcd_display(0x80+9,table1[9]);
- lcd_display(0x80+10,table1[10]);
- }
- else
- if(!C) //檢測的是電容
- {
- A=1;B1=0;
- LED_C=0;
- LED_L=1;
- LED_R=1;
- lcd_display(0x80,table2[0]);
- lcd_display(0x80+1,table2[1]);
- lcd_display(0x80+9,table2[9]);
- lcd_display(0x80+10,table2[10]);
- }
- else
- if(!L) //檢測的是電感
- {
- A=0;B1=1;
- LED_L=0;
- LED_R=1;
- LED_C=1;
- lcd_display(0x80,table3[0]);
- lcd_display(0x80+1,table3[1]);
- lcd_display(0x80+9,table3[9]);
- lcd_display(0x80+10,table3[10]);
- }
- else
- {
- LED_L=1;
- LED_R=1;
- LED_C=1;
- }
- if(data7)
- lcd_display(0x80+2,0x30+data7); //最高位數據不等于零就顯示
- else
- lcd_display(0x80+2,' '); //否則顯示空格 以下同樣
- if(data7||data6)
- lcd_display(0x80+3,0x30+data6); //最高位數據不等于零就顯示
- else
- lcd_display(0x80+3,' '); //否則顯示空格 以下同樣
- if(data7||data6||data5)
- lcd_display(0x80+4,0x30+data5);
- else
- lcd_display(0x80+4,' ');
- if(data7||data6||data5||data4)
- lcd_display(0x80+5,0x30+data4);
- else
- lcd_display(0x80+5,' ');
- if(data7||data6||data5||data4||data3)
- lcd_display(0x80+6,0x30+data3);
- else
- lcd_display(0x80+6,' ');
- if(data7||data6||data5||data4||data3||data2)
- lcd_display(0x80+7,0x30+data2);
- else
- lcd_display(0x80+7,' ');
- lcd_display(0x80+8,0x30+data1); //顯示最低位
- }
- void correct(void) //誤差修正函數
- {
- uchar i,k;
- unsigned long wucha;
- if(cnt<100000) //修正頻率范圍
- {
- if(cnt>980&&cnt<2100) //在不同頻率對數據進行修改 經驗值 資料參考
- cnt-=1;
- if(cnt>=2100&&cnt<3900)
- cnt-=2;
- if(cnt>=3900&&cnt<4800)
- cnt-=3;
- if(cnt>=4800&&cnt<5700)
- cnt-=4;
- if(cnt>=5700&&cnt<8000)
- cnt-=5;
- if(cnt>=8000&&cnt<9100)
- cnt-=6;
- if(cnt>=9100&&cnt<10900)
- cnt-=7;
- if(cnt>=10900&&cnt<11900)
- cnt-=8;
- if(cnt>=11900&&cnt<13000)
- cnt-=9;
- if(cnt>=13000&&cnt<=100000)
- {
- k=cnt/1000;
- for(i=0;i<88;i++)
- {
- if(k==f_table[i])
- {
- cnt-=f_correct[i];
- }
- }
- }
- }
- if(cnt>100000)
- {
- wucha=(cnt/1000)*73065/100000;
- cnt-=wucha;
- }
- }
- void main()
- {
- jd2=0;
- timer_init(); //定時器初始化
- lcd_init(); //液晶初始化
- if(!C) //檢測的是電容
- {
- A=1;B1=0;
- }else
- if(!R) //檢測的是電阻
- {
- A=0;B1=0;
- }else
- if(!L) //檢測的是電感
- {
- A=0;B1=1;
- }
- while(1)
- {
- if(flag==1) //數據轉化完成
- {
- real_display(); //數據處理并顯示
- flag=0;
- }
- }
- }
- void timer0() interrupt 1 //定時器0中斷函數
- {
- uchar timer0;
- TH0=0x3c; //50ms定時
- TL0=0xb0;
- timer0++; //時間變量
- if(timer0==20) //1s進入一次
- {
- timer0=0;
- TR1=0; //定時器1中斷關閉
- EA=0; //總中斷關閉
- cnt=TL1+TH1*256+f_cnt*65536; //計算1S計數的個數
- correct(); //修正一下數據
- cnt1=(1e+9)/(2*0.693 *cnt)-20000/2; //如果開關都不按下 計算數值并且顯示
- if(!R)
- {
- A=0;B1=0;
- cnt1=(500000/(0.2*0.693*cnt))-120; //計算電阻值 R1=T/(ln2*C-2R2) 此處電容200uf (ln2=0.693)
- } //1000000us=1s 此處是修正好的數據
- else
- if(!C)
- {
- A=1;B1=0;
- cnt1=100000000/(0.693*3*510*cnt); //計算電容值 C=T/((R1+2R2)ln2) 此處 R1=R2=5100
- }
- else
- if(!L)
- {
- A=0;B1=1;
- cnt1=(1e+9)/(4*3.14*3.14*cnt*cnt*0.0463); //計算電感值 L=T/(4*3.14*3.14*C) C=(C1+C2)/(C1*2C) 電容三點式
- }
- if(!R)
- {
- if(cnt1>1000)
- {
- jd1=1;
- }
- else
- {jd1=0;}
- }
- if(!C)
- {
- if(cnt1>1000)
- {
- jd2=1;
- }
- else
- {jd2=0;}
- }
- data7=cnt1/1000000;
- data6=cnt1%1000000/100000; //將數據的各位取出
- data5=cnt1%100000/10000;
- data4=cnt1%10000/1000;
- data3=cnt1%1000/100;
- data2=cnt1%100/10;
- data1=cnt1%10;
- flag=1; //測量完成標志位
- TH1=0; //給定時器裝設初始值 T0 T1
- TL1=0;
- TH0=0x3c; //定時器0裝設初值 50ms
- TL0=0xb0;
- cnt=0; //記錄時間清零
- f_cnt=0; //記錄時間清零
- EA=1; //打開總中斷
- TR1=1; //打開定時器1中斷
- }
- }
- void int1() interrupt 3 // 定時器1中斷函數 計算時間(溢出次數)
- {
- f_cnt++;
- }
復制代碼
所有資料51hei提供下載:
仿真(RLC檢測電路).zip
(275.26 KB, 下載次數: 125)
2019-8-8 00:07 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|