100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > 基于51单片机的数字电容容值测量仪proteus仿真原理图PCB

基于51单片机的数字电容容值测量仪proteus仿真原理图PCB

时间:2023-02-09 04:13:55

相关推荐

基于51单片机的数字电容容值测量仪proteus仿真原理图PCB

功能介绍:

0.本系统采用STC89C52作为单片机

1.系统支持15pF~450uF电容测量

2.按键可更改测量量程

3.除了采用LCD1602可以实时显示测量参数,同时具有LED可以显示各个档位

4.该方案电容容值测量原理是基于NE555振荡电路来设计的

原理图:

PCB:

主程序:

#include <reg52.h>#include "lcd1602.h"#include "delay.h"sbit VO = P3^2; // 用于检测P3.2口的值,计算时间。 计时器0的开与断sbit TR = P3^7; // 产生一个低电平脉冲// 超量程提示灯sbit BUZZER = P2^0;sbit RELAY1 = P1^5; // 用于控制继电器,实现档位选择sbit RELAY2 = P1^6;sbit RELAY3 = P1^7;sbit KEY1 = P3^4; // 独立按键部分,用于用户选择量程sbit LED1 = P2^1; // 量程提示灯sbit LED2 = P2^2;sbit LED3 = P2^3;sbit LED4 = P2^4;unsigned int tw = 0; // 用于获取定时器的数值float ftemp = 0; // 用于计算电容值的中间变量unsigned long int c = 0; // 存放电容值bit measureFlag = 0; // 需要测量时置1,一次测量结束置0unsigned char R = 1; // 表示不同的档位unsigned char finishFlag = 0; // 数据处理结束置1unsigned char temp[8]; // 存放电容值的各个位void Timer0_Init(); // 定时器0 初始化void Ext1_Init(); // 外部中断1 初始化void Process(unsigned long int c); // 数据处理函数void Key_Scan(); // 键盘扫描函数void Mode_Select(unsigned char R); //量程指示灯函数void Disp(unsigned char *p);void main(){BUZZER = 1;// 超量程蜂鸣器关闭TR = 1;measureFlag = 0; // 一开始无需测量finishFlag = 0;Timer0_Init(); // 初始化Ext1_Init();LCD_Init();LCD_DispStr(0, 0, "please press key");LCD_DispStr(0, 1, "to measure ");Mode_Select(R);while (1){if (measureFlag == 1){// 当需要测量时if (VO == 0) // VO == 0时检测计数器的值可能还没开始计数,可能计数结束{if (TH0 != 0x00 || TL0 != 0x00) // 是计数结束 若有读数,用tw 存下{tw = TH0 << 8;tw = tw | TL0;TH0 = 0x00; // 一次结束,计时器清零TL0 = 0x00;measureFlag = 0; // 需要再次测量时,measureFlag置1.避免tw的值被更//改 即不需要测量时,一直保持EX1 = 1; // 开外部中断1}else // 反之,证明没有计数,无电容,默认值tw置0{tw = 0;}}ftemp = tw / 1.0; // 计算电容值 根据公式 tw = 1.0 * R * Cc = (unsigned long int)(ftemp)*100; //扩大了一百倍 便于后续程序//取两位小数点Process(c);// 调用数据处理函数,根据不同的R值进行处理}DelayMs(10);if (finishFlag == 1) // 数据处理结束 每次处理结束,证明需要更新显示的数据{if (tw >= 50000 || BUZZER == 0) // 量程超出{LCD_DispStr(0, 0, " range is higher");LCD_DispStr(0, 1, "");BUZZER = 0;}else if (tw <= 100 && BUZZER == 1) //量程太低{LCD_DispStr(0, 0, " range is lower ");LCD_DispStr(0, 1, "");BUZZER = 0;}else{LCD_DispStr(0, 0, "The value of Cap");Disp(temp);}finishFlag = 0;}Key_Scan();}}void Timer0_Init() // 定时器0 初始化{TMOD = 0x09; // gate置1,方式1,16位计时,定时器由P3.2控制开断TH0 = 0x00;TL0 = 0x00;EA = 1;ET0 = 1;TR0 = 1;}void Ext1_Init() // 外部中断1 初始化{EA = 1;IT1 = 1; // 下降沿触发EX1 = 1;}void Timer0_Interrupt() interrupt 1 // 定时器0中断 用于超量程提示{BUZZER = 0;}void Ext1_Interrupt() interrupt 2 // 外部中断1 启动测量按键按下,用于产生低脉冲,启动555定时器{unsigned char a;TR = 1; // tr端一个负脉冲a = 1;while (--a);TR = 0;a = 20;while (--a);TR = 1;// tr端负脉冲结束 大约40us的负脉冲measureFlag = 1; // 表示需要测量BUZZER = 1;// 关闭先前的超量程提示EX1 = 0; // 暂时关闭外部中断,一次测量结束,再开放外部中断}void Disp(unsigned char *p) // 显示数据{unsigned char i;LCD_LocateXY(3, 1);for (i = 0; i < 6; i++){if (4 == i){LCD_WriteData(0x2e);}LCD_WriteData('0' + (*p));p++;}}void Process(unsigned long int c){if (R == 1) // 10M 的电阻 量程10pf ~ 5000pf{c = c / 10;LCD_LocateXY(10, 1);LCD_WriteData(' ');LCD_WriteData('p');LCD_WriteData('f');LCD_WriteData(' ');LCD_WriteData(' ');}if (R == 2) // 100k 的电阻 量程5nf~ 500nf{c = c / 100;LCD_LocateXY(10, 1);LCD_WriteData(' ');LCD_WriteData('n');LCD_WriteData('f');LCD_WriteData(' ');LCD_WriteData(' ');}if (R == 3) // 1k欧姆 的电阻 量程0.5uf ~ 50uf{c = c / 1000; // 扩大了一百倍 单位 c = tw/500 ufLCD_LocateXY(10, 1);LCD_WriteData(' ');LCD_WriteData('u');LCD_WriteData('f');LCD_WriteData(' ');LCD_WriteData(' ');}if (R == 4) // 100欧姆 的电阻 量程50uf ~ 500uf{c = c / 100; // 扩大了一百倍 单位 c = tw/500 ufLCD_LocateXY(10, 1);LCD_WriteData(' ');LCD_WriteData('u');LCD_WriteData('f');LCD_WriteData(' ');LCD_WriteData(' ');}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;finishFlag = 1;}void Key_Scan(){if (KEY1 == 0){DelayMs(10);if (KEY1 == 0) // b3按下{while (KEY1 == 0);if (R == 4){R = 0;}R++;Mode_Select(R);BUZZER = 1;LCD_DispStr(0, 0, "please press key");LCD_DispStr(0, 1, "to measure ");}}}void Mode_Select(unsigned char R){if (1 == R){LED1 = 1;LED2 = 1;LED3 = 1;LED4 = 0;RELAY1 = 0;RELAY2 = 0;RELAY3 = 0;}if (2 == R){LED1 = 1;LED2 = 1;LED3 = 0;LED4 = 1;RELAY1 = 1;RELAY2 = 1;RELAY3 = 0;}if (3 == R){LED1 = 1;LED2 = 0;LED3 = 1;LED4 = 1;RELAY1 = 0;RELAY2 = 0;RELAY3 = 1;}if (4 == R){LED1 = 0;LED2 = 1;LED3 = 1;LED4 = 1;RELAY1 = 0;RELAY2 = 1;RELAY3 = 1;}}

仿真演示视频:

/video/BV1jd4y1M7Dy/

实物演示视频:

/video/BV1fP41137BD/

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。