本设计

51单片机简易电容测量仪仿真设计( proteus仿真+程序+讲解视频)

仿真图proteus7.8及以上

程序编译器:keil 4/keil 5

编程语言:C语言

设计编号:S0039

1.主要功能:

利用51单片机设计一个简易电容测量仪
1.利用51单片机和555芯片构成的多谐振荡电路设计一电容测量电路
2.通过按键切换测量量程,量程由LED指示灯显示,测量数值通过LCD1602显示。
3.量程10pf-500uf

资料下载链接(可点击):

【腾讯文档】S0039 网盘链接

https://docs.qq.com/doc/DS3NsQWJtUkRSU1RN

以下为本设计资料展示图:

2.仿真

开始仿真

测量300nF 实测数值269nF

测量30uF 实测数值26.85uF

img

img

3. 程序

img

#include <reg52.h>
#include "1602.h"
#include "delay.h"

sbit vo = P3^2;	     // 用于检测P3.2口的值,计算时间。  计时器0的开与断
sbit tr = P3^7;								 // 产生一个低电平脉冲
 										 // 超量程提示灯
sbit ledclc = P2^0;

sbit con1 = P1^5;                            // 用于控制继电器,实现档位选择
sbit con2 = P1^6;								
sbit con3 = P1^7;								

sbit key1 = P1^0;							  // 独立按键部分,用于用户选择量程
sbit key2 = P1^1;
sbit key3 = P1^2;
sbit key4 = P1^3;

sbit led1 = P2^1;							  // 量程提示灯
sbit led2 = P2^2;
sbit led3 = P2^3;
sbit led4 = P2^4;


unsigned int tw;                                // 用于获取定时器的数值

float ftemp;									 // 用于计算电容值的中间变量

unsigned long int c;								// 存放电容值

unsigned char need;							 // 需要测量时置1,一次测量结束置0
unsigned char R;                            // 表示不同的档位
unsigned char flag;	                          // 数据处理结束置1
unsigned char temp[8];                        // 存放电容值的各个位	 
unsigned char zimu1[] = " range is higher";		   //量程太高
unsigned char zimu2[] = "The value of Cap";
unsigned char zimu3[] = "please press key";
unsigned char zimu4[] = "     to measure ";
unsigned char zimu5[] = " range is lower ";	
void process(unsigned long int c);	                 // 数据处理函数
void keyscan();								 // 键盘扫描函数
void ledlight(unsigned char R);					 //	量程指示灯函数
void init_timer0()	                             // 定时器0  初始化    
{
	TMOD = 0x09;		   // gate置1,方式1,16位计时,定时器由P3.2控制开断
	TH0 = 0x00;
	TL0 = 0x00;
	EA   = 1;
	ET0 = 1;	                                    
	TR0 = 1;
}
void init_INT1 ()								    // 定时器0  初始化
{
	EA = 1;
	IT1 = 1;                                      // 下降沿触发
	EX1 = 1;
}		  
void main()
{
 	ledclc = 1;								    // 超量程提示灯熄灭
 	need = 0;		                                // 一开始无需测量
    con1 = con2 = con3 = 1;
	flag = 0;
  	init_timer0();								    // 初始化
	init_INT1();
	LCD_init();
 	dispchar1(zimu3);
	dispchar2(zimu4);
	while(1)
	{
	  	if(need == 1)
		{											// 当需要测量时
			if(vo == 0 ) //vo == 0时检测计数器的值可能还没开始计数,可能计数结束
			{
				 if(TH0 != 0x00 || TL0 != 0x00) // 是计数结束 若有读数,用tw 存下 
				 {
				 	 tw = TH0 << 8;
					 tw = tw | TL0;	
					 TH0 = 0x00;		               // 一次结束,计时器清零
					 TL0 = 0x00;
                     need = 0;    // 需要再次测量时,need置1.避免tw的值被更//改   即不需要测量时,一直保持
					 EX1 = 1;		 				// 开外部中断1
				 }
				 else 	 // 反之,证明没有计数,无电容,默认值tw置0
				 {
				 	tw = 0;
				 }
			}

			ftemp = tw / 1.1  ; // 计算电容值   根据公式 tw = 1.1 * R * C

			c = (unsigned long int)(ftemp )*100;    //扩大了一百倍   便于后续程序
//取两位小数点
			process(c);		 // 调用数据处理函数,根据不同的R值进行处理																			
		}							 
		if(flag == 1 ) // 数据处理结束   每次处理结束,证明需要更新显示的数据
		{
			if(tw>=50000 || ledclc == 0)			// 量程超出
			{
				dispchar3(zimu1);               // 量程太高
				ledclc = 0;
			}						
			else if(tw<=100 && ledclc == 1)		   //量程太低
			{
				dispchar3(zimu5);
				ledclc = 0;
			}
			else   
      		{
				dispchar1(zimu2);
				disp(temp);
			}		  					
			flag = 0;
		}		
	}    
}
 
void timer0()  interrupt 1	              // 定时器0中断  用于超量程提示
{
 	ledclc = 0;
}

void exint1	() interrupt 2	  // 外部中断0  用于产生低脉冲,启动555定时器
{
	unsigned char a;
	tr = 1;				                            // tr端一个负脉冲
	a = 1;
	while(--a);
	tr = 0;
	a = 20;
	while(--a);
	tr = 1;		               // tr端负脉冲结束	   大约40us的负脉冲
	need = 1;										// 表示需要测量
	ledclc = 1;									    // 关闭先前的超量程提示
	EX1 = 0;		 // 暂时关闭外部中断,一次测量结束,再开放外部中断
}

void process(unsigned long int c)
{
		if(R == 1)	  // 10M	 的电阻		   量程10pf ~ 5000pf
		{
			c = c /10;		  
 			lcd_pos(0x4a);
		   	LCD_write_Data(' ');
			LCD_write_Data('p');
			LCD_write_Data('f');
			LCD_write_Data(' ');
			LCD_write_Data(' ');
		}
		if(R == 2)		  // 100k 的电阻	       量程5nf~ 500nf
		{
			c = c /100;		  
 			lcd_pos(0x4a);
		   	LCD_write_Data(' ');
			LCD_write_Data('n');
			LCD_write_Data('f');
			LCD_write_Data(' ');
			LCD_write_Data(' ');			
		}
		if(R == 3)		      //1k欧姆 的电阻		   量程0.5uf ~ 50uf
		{
			c = c /1000;		 // 扩大了一百倍 单位  c = tw/500   uf
 			lcd_pos(0x4a);
		   	LCD_write_Data(' ');
			LCD_write_Data('u');
			LCD_write_Data('f');
			LCD_write_Data(' ');
			LCD_write_Data(' ');     		
		}
		if(R == 4)		 //100欧姆 的电阻		   量程50uf ~ 500uf
		{
			c = c /100;		  // 扩大了一百倍 单位  c = tw/500   uf
 			lcd_pos(0x4a);
		   	LCD_write_Data(' ');
			LCD_write_Data('u');
			LCD_write_Data('f');
			LCD_write_Data(' ');
			LCD_write_Data(' ');				        		
		}
		temp[0] = c / 100000;		                // 千位
		temp[1] = c / 10000 % 10;	                // 百位					
		temp[2] = c / 1000 % 10;   	                // 十位
		temp[3] = c / 100 %10;	                    // 个位	
		temp[4] = c / 10 % 10;	    
		temp[5] = c  % 10;
		flag = 1;
}
void keyscan()
{
	if(key1 == 0)
	{
		delay_ms(10);
		if(key1 == 0)		                        //  b3按下
		{
			while(key1==0);
			R = 1;        // 10M 的电阻	       量程10pf~ 5000pf(5nf)
			con1 = 0;
			con2 = 0;
			con3 = 0;
			ledclc = 1;
			dispchar1(zimu3);
			dispchar2(zimu4);
		}
	}
	if(key2 == 0)									   //  b4按下
	{
		delay_ms(10);
		if(key2 == 0)
		{
			while(key2==0);
			R = 2;             // 100k 的电阻	       量程5nf~ 500nf
			con1 = 1;
			con2 = 1;
			con3 = 0;
			ledclc = 1;
			dispchar1(zimu3);
			dispchar2(zimu4);
		}
	}

	if(key3 == 0)									     //  b5按下
	{
		delay_ms(10);
		if(key3 == 0)
		{
			while(key3==0);
			R = 3; 
			con1 = 0;       // 1k欧姆 的电阻		   量程0.5uf ~ 50uf
			con2 = 1;
			con3 = 1;
			ledclc = 1;
			dispchar1(zimu3);
			dispchar2(zimu4);
		}
	}
	if(key4 == 0)									     //  b6按下
	{
		delay_ms(10);
		if(key4 == 0)
		{
			while(key4==0);
			R = 4;
			con1 = 0;       // 100欧姆 的电阻	   量程50uf ~ 500uf
			con2 = 0;
			con3 = 1;
			ledclc = 1;
			dispchar1(zimu3);
			dispchar2(zimu4);
		}
	}
	ledlight(R);
}	
void ledlight(unsigned char R)
{
	if(1 == R)
	{
		led1 = 1;
		led2 = 1;
		led3 = 1;
		led4 = 0;
	}
	if(2 == R)
	{
		led1 = 1;
		led2 = 1;
		led3 = 0;
		led4 = 1;
	}
	if(3 == R)
	{
		led1 = 1;
		led2 = 0;
		led3 = 1;
		led4 = 1;
	}
	if(4 == R)
	{
		led1 = 0;
		led2 = 1;
		led3 = 1;
		led4 = 1;
	}
 }

4.设计资料内容清单

下载方式见文章开头视频

img

资料下载链接(可点击):

https://docs.qq.com/doc/DS3NsQWJtUkRSU1RN

更多资源 点击下方链接:

https://docs.qq.com/sheet/DS0xIa0llTmtNakRW

微信公众号:嘉盛单片机

img