找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 7359|回复: 4
打印 上一主题 下一主题
收起左侧

基于单片机和NE555的3档电容测试器的设计(仿真+代码)

[复制链接]
跳转到指定楼层
楼主
开机屏幕显示欢迎界面
1、插入电容,按下相应nf、pf、uf、uf按键选择档位;
2、按下测试按键,屏幕出现提示信息,提示档位选择低或者高,如正常档位屏幕显示当前测量电容值;
3、对于大容量电容要多按几次测试键方能显示正常值;
4、复位按键按下系统复位。

设计的主要方法是采用555芯片构成单稳态触发器,将电容容量转换为脉冲宽度。通过单片机的计时器测量脉宽, 根据已知的R值,通过单片机的运算功能,计算出电容容量,最后,再通过单片机的普通I/O口控制液晶屏显示出电容容量的计算结果。系统的测量范围为10pF~ 500uF, 具有多个量程,可根据用户需要由用户选择,与用户的交互是通过键盘实现,不同量程的实现是通过单片机的I/O口控制继电器的吸合与断开来选择不同的R值,从而实现不同的量程。

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


单片机源程序如下:
  1. #include <reg52.h>
  2. #include "1602.h"
  3. #include "delay.h"

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

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

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

  15. sbit led1 = P2^1;                                                          // 量程提示灯
  16. sbit led2 = P2^2;
  17. sbit led3 = P2^3;
  18. sbit led4 = P2^4;


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

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

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

  22. unsigned char need;                                                         // 需要测量时置1,一次测量结束置0
  23. unsigned char R;                            // 表示不同的档位
  24. unsigned char flag;                                  // 数据处理结束置1
  25. unsigned char temp[8];                        // 存放电容值的各个位         
  26. unsigned char zimu1[] = " range is higher";                   //量程太高
  27. unsigned char zimu2[] = "The value of Cap";
  28. unsigned char zimu3[] = "please press key";
  29. unsigned char zimu4[] = "     to measure ";
  30. unsigned char zimu5[] = " range is lower ";        
  31. void process(unsigned long int c);                         // 数据处理函数
  32. void keyscan();                                                                 // 键盘扫描函数
  33. void ledlight(unsigned char R);                                         //        量程指示灯函数
  34. void init_timer0()                                     // 定时器0  初始化   
  35. {
  36.         TMOD = 0x09;                   // gate置1,方式1,16位计时,定时器由P3.2控制开断
  37.         TH0 = 0x00;
  38.         TL0 = 0x00;
  39.         EA   = 1;
  40.         ET0 = 1;                                            
  41.         TR0 = 1;
  42. }
  43. void init_INT1 ()                                                                    // 定时器0  初始化
  44. {
  45.         EA = 1;
  46.         IT1 = 1;                                      // 下降沿触发
  47.         EX1 = 1;
  48. }                  
  49. void main()
  50. {
  51.          ledclc = 1;                                                                    // 超量程提示灯熄灭
  52.          need = 0;                                                // 一开始无需测量
  53.     con1 = con2 = con3 = 1;
  54.         flag = 0;
  55.           init_timer0();                                                                    // 初始化
  56.         init_INT1();
  57.         LCD_init();
  58.          dispchar1(zimu3);
  59.         dispchar2(zimu4);
  60.         while(1)
  61.         {
  62.                   if(need == 1)
  63.                 {                                                                                        // 当需要测量时
  64.                         if(vo == 0 ) //vo == 0时检测计数器的值可能还没开始计数,可能计数结束
  65.                         {
  66.                                  if(TH0 != 0x00 || TL0 != 0x00) // 是计数结束 若有读数,用tw 存下
  67.                                  {
  68.                                           tw = TH0 << 8;
  69.                                          tw = tw | TL0;        
  70.                                          TH0 = 0x00;                               // 一次结束,计时器清零
  71.                                          TL0 = 0x00;
  72.                      need = 0;    // 需要再次测量时,need置1.避免tw的值被更//改   即不需要测量时,一直保持
  73.                                          EX1 = 1;                                                 // 开外部中断1
  74.                                  }
  75.                                  else          // 反之,证明没有计数,无电容,默认值tw置0
  76.                                  {
  77.                                          tw = 0;
  78.                                  }
  79.                         }

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

  81.                         c = (unsigned long int)(ftemp )*100;    //扩大了一百倍   便于后续程序
  82. //取两位小数点
  83.                         process(c);                 // 调用数据处理函数,根据不同的R值进行处理                                                                                                                                                        
  84.                 }                                                         
  85.                 if(flag == 1 ) // 数据处理结束   每次处理结束,证明需要更新显示的数据
  86.                 {
  87.                         if(tw>=50000 || ledclc == 0)                        // 量程超出
  88.                         {
  89.                                 dispchar3(zimu1);               // 量程太高
  90.                                 ledclc = 0;
  91.                         }                                                
  92.                         else if(tw<=100 && ledclc == 1)                   //量程太低
  93.                         {
  94.                                 dispchar3(zimu5);
  95.                                 ledclc = 0;
  96.                         }
  97.                         else   
  98.                       {
  99.                                 dispchar1(zimu2);
  100.                                 disp(temp);
  101.                         }                                                         
  102.                         flag = 0;
  103.                 }               
  104.                 keyscan();
  105.         }   
  106. }

  107. void timer0()  interrupt 1                      // 定时器0中断  用于超量程提示
  108. {
  109.          ledclc = 0;
  110. }

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

  125. void process(unsigned long int c)
  126. {
  127.                 if(R == 1)          // 10M         的电阻                   量程10pf ~ 5000pf
  128.                 {
  129.                         c = c /10;                  
  130.                          lcd_pos(0x4a);
  131.                            LCD_write_Data(' ');
  132.                         LCD_write_Data('p');
  133.                         LCD_write_Data('f');
  134.                         LCD_write_Data(' ');
  135.                         LCD_write_Data(' ');
  136.                 }
  137.                 if(R == 2)                  // 100k 的电阻               量程5nf~ 500nf
  138.                 {
  139.                         c = c /100;                  
  140.                          lcd_pos(0x4a);
  141.                            LCD_write_Data(' ');
  142.                         LCD_write_Data('n');
  143.                         LCD_write_Data('f');
  144.                         LCD_write_Data(' ');
  145.                         LCD_write_Data(' ');                        
  146.                 }
  147.                 if(R == 3)                      //1k欧姆 的电阻                   量程0.5uf ~ 50uf
  148.                 {
  149.                         c = c /1000;                 // 扩大了一百倍 单位  c = tw/500   uf
  150.                          lcd_pos(0x4a);
  151.                            LCD_write_Data(' ');
  152.                         LCD_write_Data('u');
  153.                         LCD_write_Data('f');
  154.                         LCD_write_Data(' ');
  155.                         LCD_write_Data(' ');                     
  156.                 }
  157.                 if(R == 4)                 //100欧姆 的电阻                   量程50uf ~ 500uf
  158.                 {
  159.                         c = c /100;                  // 扩大了一百倍 单位  c = tw/500   uf
  160.                          lcd_pos(0x4a);
  161.                            LCD_write_Data(' ');
  162.                         LCD_write_Data('u');
  163.                         LCD_write_Data('f');
  164.                         LCD_write_Data(' ');
  165.                         LCD_write_Data(' ');                                                        
  166.                 }
  167.                 temp[0] = c / 100000;                                // 千位
  168.                 temp[1] = c / 10000 % 10;                        // 百位                                       
  169.                 temp[2] = c / 1000 % 10;                           // 十位
  170.                 temp[3] = c / 100 %10;                            // 个位        
  171.                 temp[4] = c / 10 % 10;            
  172.                 temp[5] = c  % 10;
  173.                 flag = 1;
  174. }
  175. void keyscan()
  176. {
  177.         if(key1 == 0)
  178.         {
  179.                 delay_ms(10);
  180.                 if(key1 == 0)                                        //  b3按下
  181.                 {
  182.                         while(key1==0);
  183.                         R = 1;        // 10M 的电阻               量程10pf~ 5000pf(5nf)
  184.                         con1 = 0;
  185.                         con2 = 0;
  186.                         con3 = 0;
  187.                         ledclc = 1;
  188.                         dispchar1(zimu3);
  189.                         dispchar2(zimu4);
  190.                 }
  191.         }
  192.         if(key2 == 0)                                                                           //  b4按下
  193.         {
  194.                 delay_ms(10);
  195.                 if(key2 == 0)
  196.                 {
  197.                         while(key2==0);
  198.                         R = 2;             // 100k 的电阻               量程5nf~ 500nf
  199.                         con1 = 1;
  200.                         con2 = 1;
  201.                         con3 = 0;
  202.                         ledclc = 1;
  203.                         dispchar1(zimu3);
  204.                         dispchar2(zimu4);
  205.                 }
  206.         }

  207.         if(key3 == 0)                                                                             //  b5按下
  208.         {
  209.                 delay_ms(10);
  210.                 if(key3 == 0)
  211.                 {
  212.                         while(key3==0);
  213.                         R = 3;
  214.                         con1 = 0;       // 1k欧姆 的电阻                   量程0.5uf ~ 50uf
  215.                         con2 = 1;
  216.                         con3 = 1;
  217.                         ledclc = 1;
  218.                         dispchar1(zimu3);
  219.                         dispchar2(zimu4);
  220.                 }
  221.         }
  222.         if(key4 == 0)                                                                             //  b6按下
  223.         {
  224.                 delay_ms(10);
  225.                 if(key4 == 0)
  226.                 {
  227.                         while(key4==0);
  228.                         R = 4;
  229.                         con1 = 0;       // 100欧姆 的电阻           量程50uf ~ 500uf
  230.                         con2 = 0;
  231.                         con3 = 1;
  232.                         ledclc = 1;
  233.                         dispchar1(zimu3);
  234.                         dispchar2(zimu4);
  235.                 }
  236.         }
  237.         ledlight(R);
  238. }        
  239. ……………………

  240. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
程序及仿真.zip (90.48 KB, 下载次数: 190)


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:443911 发表于 2019-8-7 21:29 | 只看该作者
请问Nte-r22-5是什么元件
回复

使用道具 举报

板凳
ID:598151 发表于 2019-8-9 09:14 | 只看该作者
原理图可以分享下嘛
回复

使用道具 举报

地板
ID:269960 发表于 2019-8-10 10:33 来自手机 | 只看该作者
是测得C?的容值吗,怎么所有选项都是range is lower
回复

使用道具 举报

5#
ID:722171 发表于 2020-4-8 17:13 来自手机 | 只看该作者
有没有pcb图
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表