自制仪表仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #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)
|