2赞

8回答

2收藏

[其他] 基于AT89C51单片机和555芯片构成的电容测量仿真

51单片机 51单片机 14314 人阅读 | 8 人回复 | 2012-11-01

本帖最后由 E08610225 于 2012-11-4 22:16 编辑

版主评论:
此贴子质量不错哟~~~希望大家多发类似的仿真或实例哟~

这个小实例,比较适合于初级、中级之间的朋友们去做一下~~~

1.涉及到外围电路搭建,可以提高大家的单片机应用综合性水平。
2.学习外围常用芯片。
3.提供一些设计思路。单片机设计无非就是经验的综合~所以,积累类似的小经验是对设计很有用的~

由于可以仿真,所以,操作起来就更方便了。”

正文:
     这种电容测量方法主要是通过一块555芯片来测量电容,让555芯片工作在直接反馈无稳态的状态下,555芯片输出一定频率的方波,其频率的大小跟被测量的电容之间的关系是:f=0.772/(R*Cx),我们固定R的大小,其公式就可以写为:f=k/Cx,只要我们能够测量出555芯片输出的频率,就可以计算出测量的电容。计算频率的方法可以利用单片机的计数器T0和中断INT0配合使用来测量。
555时基芯片的输出频率跟所使用的电阻R和电容Cx的关系是:f=0.772/(R*Cx),
又因为T=1/f,所以
       T=R*Cx/0.772                                            
即:Cx=0.772*T/R
如果单片机采用12M的晶振,计数器T0的值增加1,时间就增加1μS ,采用中断的方式来启动和停止计数器T0,中断的触发方式为脉冲下降沿触发,第一次中断到来启动T0,计数器的值为N1,第二次中断到来停止T0,
计数器器的值为N2,则测量方波的周期为T=(N2-N1)*1μS,如开始时刻计数器的值N1=0,则
简单时序图如下:
则   

    单片机的计数器的值N=0-65535,为了测量的精度,N的取值一般在100~5000,当电阻R越大,电容C的值就越小。取不同的电阻值,就得到不同的电容测量的量程,这里我因需测30pF左右的电容,取R=77200k,为了编写程序的方便,只计算N/100,后面的单位可以根据使用的量程自行添加.
proteus仿真电路截图如下:

proteus仿真结果:
电容测量.rar (36.46 KB, 下载次数: 372)

51程序(keil):
555电容测量程序.rar (25.78 KB, 下载次数: 308)
  1. #include "reg51.h"
  2. #include"intrins.h"//库函数

  3. #define DATA P0
  4. sbit RW=P2^1;//1602写数据
  5. sbit RS=P2^0;//1602写地址
  6. sbit EN=P2^2; //1602工作使能
  7. sbit b_test=P3^7; //开始测量电容的按键输入
  8. sbit _reset=P3^5; //555时基芯片工作控制信号
  9. unsigned int T_flag,N,C,i,Dis1,Dis0;
  10. unsigned int b[6]={0X13,0X0D,0X00,0X00,0X40,0X16}; //显示C=00pF

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

  73. }

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

  86. for(j=0;j<6;j++)//写显示第二行
  87. {
  88. wcomd(0xc0+j);
  89. Delay1ms(1);
  90. wdata(0x30+b[j]);
  91. Delay1ms(1);
  92. }
  93. Delay1ms(150);

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

分享到:
回复

使用道具 举报

回答|共 8 个

倒序浏览

沙发

幻灵_3000624

发表于 2012-11-1 15:00:14 | 只看该作者

{:soso__10568993024570925148_2:}LZ威武!!!

点评

木有见过自己夸自己的...lz丝毫不谦虚。。。哈哈!  发表于 2012-11-4 22:05
板凳

w932443004

发表于 2012-11-1 15:05:56 | 只看该作者

太好了 我来学习!
地板

好剑者

发表于 2013-7-28 19:30:17 | 只看该作者

好东东,值得珍藏。
5#

两、相忘

发表于 2016-3-16 16:02:25 | 只看该作者

泪流满面,楼主好人
6#

六号跑道

发表于 2016-6-3 09:09:00 | 只看该作者

资料已下载,过来学习,希望能正常使用
7#

柳依依

发表于 2017-5-20 20:31:46 | 只看该作者

请问代码中N=N*5/3;是什么意思呢
8#

榆林上校2000

发表于 2017-11-10 10:43:22 | 只看该作者

本帖最后由 榆林上校2000 于 2017-11-10 10:45 编辑

LZ的帖子太好了,收藏
不知精度怎样?想做个板子看看
9#

zmc419

发表于 2017-12-7 15:32:08 来自手机 | 只看该作者

太好了,有类似程序,无仿真。
您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条