找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机电容测量电路+程序设计

[复制链接]
跳转到指定楼层
楼主
ID:510819 发表于 2019-4-13 22:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
非原创,和大家分享一下
基于AT89C51单片机和555芯片构成的多谐振荡电路设计一电容测量电路,这种测量方法主要是通过一块555芯片来测量电容大小。让555芯片工作在直接反馈无稳态的状态下,555芯片输出一定频率的方波,其频率的大小跟被测量的电容之间的关系是:f=0.772/(R*Cx) ,固定R的大小,其公式就可以写为:f=k/Cx,只要能够测量出555芯片输出的频率,就可以计算出测量的电容。计算频率的方法可以利用单片机的计数器T0和中断INT0配合使用来进行测量。
1.3.1 系统硬件电路设计
该电路主要由单片机AT89C51、按键、继电器、74HC08、LCD16028、555芯片等构成,整体设计电路如图1-7所示。
图1-7
555模块简介
NE555管脚功能介绍:
1脚为地。2脚为触发输入端;3脚为输出端,输出的电平状态受触发器控制,而触发器受上比较器6脚和下比较器2脚的控制。
当触发器接受上比较器A1从R脚输入的高电平时,触发器被置于复位状态,3脚输出低电平;
2脚和6脚是互补的,2脚只对低电平起作用,高电平对它不起作用,即电压小于1Ucc/3,此时3脚输出高电平。6脚为阈值端,只对高电平起作用,低电平对它不起作用,即输入 电压大于2Ucc/3,称高触发端,3脚输出低电平,但有一个先决条件,即2脚电位必须大于Ucc/3时才有效。3脚在高电位接近电源电压Ucc,输出电流最大可打200mA。
4脚是复位端,当4脚电位小于0.4V时,不管2、6脚状态如何,输出端3脚都输出低电平。5脚是控制端。7脚称放电端,与3脚输出同步,输出电平一致,但7脚并不输出电流,所以3脚称为实高(或低)、7脚称为虚高。
555集成电路的框图及工作原理:
555集成电路开始是作定时器应用的,所以叫做555定时器或555时基电路。但后来经过开发,它除了作定时延时控制外,还可用于调光、调温、调压、调速等多种控制及计量检测。此外,还可以组成脉冲振荡、单稳、双稳和脉冲调制电路,用于交流信号源、电源变换、频率变换、脉冲调制等。由于它工作可靠、使用方便、价格低廉,目前被广泛用于各种电子产品中,555集成电路内部有几十个元器件,有分压器、比较器、基本R-S触发器、放电管以及缓冲器等,电路比较复杂,是模拟电路和数字电路的混合体,如图1所示。
555振荡器电路(无稳电路):
    由555定时器构成的多谐振荡器如图9(a)所示,其工作波形见图9(b)。
      接通电源后,电源VDD通过R1和R2对电容C充电,当Uc<1/3VDD时,振荡器输出Vo=1,放电管截止。当Uc充电到≥2/3VDD后,振荡器输出Vo翻转成0,此时放电管导通,使放电端(DIS)接地,电容C通过R2对地放电,使Uc下降。当Uc下降到≤1/3VDD后,振荡器输出Vo又翻转成1,此时放电管又截止,使放电端(DIS)不接地,电源VDD通过R1和R2又对电容C充电,又使Uc从1/3VDD上升到2/3VDD,触发器又发生翻转,如此周而复始,从而在输出端Vo得到连续变化的振荡脉冲波形。脉冲宽度TL≈0.7R2C,由电容C放电时间决定;TH=0.7(R1+R2)C,由电容C充电时间决定,脉冲周期T≈TH+TL。
1.3.2系统软件设计
系统主程序设计流程如图3-4所示,主要完成定时器的初始化,启动555芯片工作,等待中断,若有中断,则计算电容大小,显示电容大小,然后等待下一次中断。

proteus仿真
载入hex文件,如图1-8
图1-8
可以改变单刀双掷开关SW1,切换被测量的电容。LCD1602上即可显示被测电容的值,仿真时会有误差。

程序清单如下:
用keil c编译
本工程包含一个文件
电容测量.c
  1. /******************************文件Main.c 如下****************************/
  2. //编译环境 :keil c51
  3. //mpu型号:stc89c52rc
  4. //晶振频率:12M
  5. //操作系统:win x
  6. /*************************************************************************/
  7. #include "reg51.h"
  8. #include"intrins.h"                                                                                                                              //库函数

  9. #define DATA P0
  10. sbit RW=P2^1;                                                                                                                                            //1602写数据
  11. sbit RS=P2^0;                                                                                                                                            //1602写地址
  12. sbit EN=P2^2;                                                                                                                                             //1602工作使能
  13. sbit b_test=P3^7;                                                                                                                                 //控制小灯的亮灭
  14. sbit _reset=P3^5;                                                                                                                                 //555时基芯片工作控制信号
  15. unsigned int T_flag,N,C,i,Dis1,Dis0;
  16. unsigned int b[6]={0X13,0X0D,0X00,0X00,0X40,0X16};                          //显示C=00pF

  17. /*******************************延时1ms*********************************/
  18. void Delay1ms(unsigned int mm)
  19. {unsigned int i;
  20. for(mm;mm>0;mm--)
  21.    for(i=100;i>0;i--);
  22. }
  23. /********************************检查忙否********************************/
  24. void Checkstates()
  25. {
  26. unsigned char dat;
  27. RS=0;
  28. RW=1;
  29. do{EN=1;                                                                                                                                                          //下降沿
  30.    _nop_();                                                                                                                                                          //保持一定间隔
  31.               _nop_();
  32.     dat=DATA;
  33.     _nop_();
  34.               _nop_();
  35.     EN=0;
  36. }while((dat&0x80)==1);
  37. }
  38. /*******************************LCD写命令函数****************************/
  39. void wcomd(unsigned char cmd)
  40. {
  41. Checkstates();
  42. RS=0;
  43. RW=0;
  44. DATA=cmd;
  45. EN=1;
  46. _nop_();
  47. _nop_();
  48. _nop_();
  49. _nop_();
  50. EN=0;
  51. }
  52. /******************************LCD写数据函数*******************************/
  53. void wdata(unsigned char dat)
  54. {
  55. Checkstates();
  56. RS=1;
  57. RW=0;
  58. DATA=dat;
  59. EN=1;
  60. _nop_();
  61. _nop_();
  62. _nop_();
  63. _nop_();
  64. EN=0;
  65. }
  66. /********************************初始化***********************************/
  67. void LCDINIT()
  68. {
  69. Delay1ms(15);
  70. wcomd(0x38);                                                                                                                              //功能设置
  71. Delay1ms(5);
  72. wcomd(0x38);                                                                                                                              //功能设置
  73. Delay1ms(5);
  74. wcomd(0x01);                                                                                                                              //清屏
  75. Delay1ms(5);
  76. wcomd(0x08);                                                                                                                              //关显示
  77. Delay1ms(5);
  78. wcomd(0x0c);                                                                                                                              //开显示,不开光标

  79. }

  80. /********************************显示函数********************************/
  81. void Display(void) //显示函数
  82. {
  83. unsigned char i,j;
  84. unsigned char a[12]={0X4D,0X45,0X41,0X53,0X55,0X52,0X45,0X4D,0X45,0X4E,0X54,0X53};//显示measurements
  85. LCDINIT();
  86. for(i=0;i<12;i++)                                                                                                                              //写显示第一行
  87. { wcomd(0x80+i);
  88.     Delay1ms(1);
  89.     wdata(a[i]);
  90.     Delay1ms(1);
  91.    }

  92. for(j=0;j<6;j++)                                                                                                                              //写显示第二行
  93. {
  94. wcomd(0xc0+j);
  95.   Delay1ms(1);
  96.   wdata(0x30+b[j]);
  97.   Delay1ms(1);
  98. }
  99. Delay1ms(150);

  100. }
  101. /********************************主程序函数********************************/

  102. void main()
  103. {
  104.   IE=0x81;                                                                                  //打开全部的中断控制,并开启外部中断允许
  105. TMOD=0x09;                                                                  //T0为16位计数工作方式1
  106.   IT0=1;                                                                                    //设置外部中断的触发的方式为脉冲触发
  107.   TH0=0x00;
  108.   TL0=0x00;
  109.   T_flag=0;
  110. _reset=0;
  111.   b_test=1;
  112.   while(1)
  113. {
  114.     //while(!b_test)                                                             //如果有测量按键输入就往下执行
  115.     //{
  116.      i=0;
  117.      _reset=1;                                                                              //启动555时基芯片
  118.      EX0=1;                                                                                              //开启中断0
  119.      while(_reset)                                                                         //超出等待时间,中断还没有过来,就退出
  120.       {
  121.        i++;
  122.        if(i>50000)                                                                         //设置最长等待时间
  123.         {
  124.          _reset=0;                                                                                      //最长等待时间到还没有中断,停止555
  125.         }
  126.      }
  127.      if(N<100)                                                                               //如果计数值小于100,显示SM,表示应换用小一点的量程
  128.      {
  129.        b[3]=0X1D;
  130.        b[2]=0X23;
  131.       }
  132. if(N>50000)                                                                              //如果计数值大于5000,显示LA,表示应换用大一点的量程
  133.       {
  134.        b[3]=0X11;
  135.        b[2]=0X1C;
  136.       }
  137.      if(N>=100 && N<=50000)
  138.       {
  139.        C=N/100;                                                                               //计算电容的大小
  140.        b[2]=C/10;                                                                             //计算电容值的十位
  141.        b[3]=C-b[2]*10;                                                                        //计算电容值的个位
  142.       }
  143.      //}
  144.     Display();                                                                                     //显示电容的大小
  145.               if(C>40)
  146.                 b_test=0;
  147.                 else
  148.                  b_test=1;
  149.   }

  150. /******************************外中断0服务函数*****************************/

  151. void int0(void) interrupt 0                                                           //第一次中断开始计数,第二个中断停止计数
  152. {
  153.   T_flag=!T_flag;
  154.   if(T_flag==1)
  155.   {
  156.    TR0=1;                                                                                             //开始计时
  157.   }
  158.   if(T_flag==0)
  159.   {
  160.    TR0=0;                                                                                             //停止计时
  161.    EX0=0;                                                                                             //关闭中断
  162.    _reset=0;                                                                                          //停止发出方

  163. ^^^^^^^^^^^^^^^^^^
  164. 余下内容下载附件
  165.    
复制代码


全部资料51hei下载地址:
啊啊.docx (214.44 KB, 下载次数: 175)


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

使用道具 举报

沙发
ID:722171 发表于 2020-4-6 12:31 来自手机 | 只看该作者
有没有详细介绍
回复

使用道具 举报

板凳
ID:724239 发表于 2020-4-7 18:05 | 只看该作者
右下角那个元件是什么啊
回复

使用道具 举报

地板
ID:819012 发表于 2020-9-14 21:57 | 只看该作者
请问楼主,这个原创出自哪里,急求~~!
回复

使用道具 举报

5#
ID:902516 发表于 2021-4-25 11:02 来自手机 | 只看该作者
楼主问个问题,这个程序直接烧录到主芯片就可以用了吗?显示屏需不需要
回复

使用道具 举报

6#
ID:927124 发表于 2021-5-25 16:55 | 只看该作者
出不来
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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