標題:
自制萬用表Proteus仿真(RLC檢測電路+單片機程序)
[打印本頁]
作者:
1598207459
時間:
2019-8-8 00:10
標題:
自制萬用表Proteus仿真(RLC檢測電路+單片機程序)
自制儀表仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png
(5.44 KB, 下載次數(shù): 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顯示數(shù)組
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; //數(shù)據(jù)變量
uchar flag; //轉(zhuǎn)換完成標志位
unsigned long cnt,cnt1; //長整形數(shù)據(jù) 記錄振蕩器計數(shù)的次數(shù)
uchar f_cnt; //時間溢出次數(shù)變量
//函數(shù)聲明
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); //寫數(shù)據(jù)
void lcd_display(uchar add,uchar dat); //指定地址寫數(shù)據(jù)
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) //寫數(shù)據(jù)
{
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); //設(shè)置顯示模式
delay_ms(10);
lcd_write_com(0x0c);
lcd_write_com(0x06);
lcd_write_com(0x01); //清屏指令
delay_ms(2);
}
void timer_init(void) //定時器初始化函數(shù)
{
TMOD=0X51; //設(shè)置定時器工作模式
PT0=1;
TH0=0x3c; //給定時器0裝設(shè)初值 50ms
TL0=0xb0;
TH1=0; //不設(shè)初值
TL1=0;
ET0=1; //開中斷
ET1=1;
TR0=1; //開定時器
TR1=1;
EA=1; //開總中斷
}
void lcd_display(uchar add,uchar dat) //lcd指定地址寫數(shù)據(jù)
{
lcd_write_com(add);
lcd_write_dat(dat);
delay_us();
}
void real_display(void) //數(shù)據(jù)顯示函數(shù)
{
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); //最高位數(shù)據(jù)不等于零就顯示
else
lcd_display(0x80+2,' '); //否則顯示空格 以下同樣
if(data7||data6)
lcd_display(0x80+3,0x30+data6); //最高位數(shù)據(jù)不等于零就顯示
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) //誤差修正函數(shù)
{
uchar i,k;
unsigned long wucha;
if(cnt<100000) //修正頻率范圍
{
if(cnt>980&&cnt<2100) //在不同頻率對數(shù)據(jù)進行修改 經(jīng)驗值 資料參考
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) //數(shù)據(jù)轉(zhuǎn)化完成
{
real_display(); //數(shù)據(jù)處理并顯示
flag=0;
}
}
}
void timer0() interrupt 1 //定時器0中斷函數(shù)
{
uchar timer0;
TH0=0x3c; //50ms定時
TL0=0xb0;
timer0++; //時間變量
if(timer0==20) //1s進入一次
{
timer0=0;
TR1=0; //定時器1中斷關(guān)閉
EA=0; //總中斷關(guān)閉
cnt=TL1+TH1*256+f_cnt*65536; //計算1S計數(shù)的個數(shù)
correct(); //修正一下數(shù)據(jù)
cnt1=(1e+9)/(2*0.693 *cnt)-20000/2; //如果開關(guān)都不按下 計算數(shù)值并且顯示
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 此處是修正好的數(shù)據(jù)
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; //將數(shù)據(jù)的各位取出
data5=cnt1%100000/10000;
data4=cnt1%10000/1000;
data3=cnt1%1000/100;
data2=cnt1%100/10;
data1=cnt1%10;
flag=1; //測量完成標志位
TH1=0; //給定時器裝設(shè)初始值 T0 T1
TL1=0;
TH0=0x3c; //定時器0裝設(shè)初值 50ms
TL0=0xb0;
cnt=0; //記錄時間清零
f_cnt=0; //記錄時間清零
EA=1; //打開總中斷
TR1=1; //打開定時器1中斷
}
}
void int1() interrupt 3 // 定時器1中斷函數(shù) 計算時間(溢出次數(shù))
{
f_cnt++;
}
復(fù)制代碼
所有資料51hei提供下載:
仿真(RLC檢測電路).zip
(275.26 KB, 下載次數(shù): 125)
2019-8-8 00:07 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
作者:
haiyang33333
時間:
2020-4-15 16:13
用的仿真軟件不是proteus??
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1