仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
單片機源程序如下:
- #include <reg51.h>
- sbit nF_check = P1^0; //測量電容(nF)
- sbit uF_check = P1^1; //測量電容(uF)
- sbit stop = P1^2; //停止測量按鈕
- sbit P20 = P2^0; //百位控制
- sbit P21 = P2^1; //十位控制
- sbit P22 = P2^2; //個位及小數點控制
- sbit P23 = P2^3; //十分位控制
- sbit P24 = P2^4; //“n”或“u”顯示控制
- sbit P25 = P2^5; //“F”顯示控制
- sbit P26 = P2^6; //
- sbit P27 = P2^7; //
- sbit P30 = P3^0; //電阻電容測量繼電器
- sbit P31 = P3^1; //
- sbit P32 = P3^2; //計時停止請求(中斷0)
- sbit P33 = P3^3; //計時開始請求(中斷1)及測量開始開關
- sbit P34 = P3^4;
- sbit P35 = P3^5;
- sbit P36 = P3^6;
- sbit P37 = P3^7;
- char code word[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,
- 0x7F,0x6F,0x37,0x3E,0x71,0x80};
- //'0'~'9'和n、u、F及小數點.等字形碼
- long int N=0; //計數變量
- /********************************************************************
- 函數功能:延時函數
- 入口參數: us
- 出口參數:
- ********************************************************************/
- void delay(us)
- {
- while(us--);
- }
- /********************************************************************
- 函數功能:中斷初始化
- 入口參數:
- 出口參數:
- ********************************************************************/
- void INT0_init()
- {
- IE = 0x87; //打開總中斷及外部中斷0、1,定時器中斷0
- IT0 = 1; //下降沿觸發
- IT1 = 1;
- }
- /********************************************************************
- 函數功能:外部中斷0處理
- 入口參數:
- 出口參數:
- ********************************************************************/
- void INT0_pro(void) interrupt 0 //外部中斷0
- {
- TR0 = 0; //T0停止計時
- }
- /********************************************************************
- 函數功能:外部中斷1處理
- 入口參數:
- 出口參數:
- ********************************************************************/
- void INT1_pro(void) interrupt 2 //外部中斷1
- {
- TR0 = 1; //T0開始計時
- }
- /********************************************************************
- 函數功能:定時器0初始化
- 入口參數:
- 出口參數:
- ********************************************************************/
- void Timer_init() {
-
- TMOD = 0x02; //定時器0工作于方式2(8位自動重裝定時器)
- TH0 = 256-100; //定時器0設定時間為100us(假設晶振為12MHz,
- TL0 = 256-100; //則時鐘周期為1/12us,機器周期為1us),頻率為10kHz。
- }
- /********************************************************************
- 函數功能:定時器0中斷處理(時基)
- 入口參數:
- 出口參數:
- ********************************************************************/
- void _Timer_clock(void) interrupt 1 //定時器0(溢出)中斷,中斷1
- {
- N++;
- }
- /********************************************************************
- 函數功能:數據顯示函數
- 入口參數: CV
- 出口參數:
- ********************************************************************/
- void CV_disp(long int CV)
- {
- //數碼管位選方式--灌電流//
- P2=0xff;
- P0=word[CV/1000]; P20=0; delay(60); //千位
- P2=0xff;
- P0=word[(CV/100)%10]; P21=0; delay(60); //百位
- P2=0xff;
- P0=word[(CV/10)%10]; P22=0; delay(60); //十位
- P2=0xff;
- P0=word[CV%10]; P23=0; delay(60); //個位
-
- }
- /********************************************************************
- 函數功能:主函數
- 入口參數:
- 出口參數:
- ********************************************************************/
- void main()
- {
- long int C=0;
- INT0_init();
- Timer_init();
- while(1){
-
- //數碼管位選方式--灌電流//
- while(!nF_check) { //測量電容(nF)
- P30=1;
- if(TR0 && !P33) C=N*610/1000;//取R=10M,C為nF級,則時間常數t=RC=(10*10^6)*(C*10^-9)=C*10^-2;
- //若在t期間對已知脈沖進行計數,且選脈沖頻率f=10k=10^4,
- else N=0; //則計數值N=f*t=100C(nF),所以C=N/100。
- //C=N*610/1000是算法修正
- P2=0xff;
- P0=word[10]; P24=0; delay(60); //第5位顯示n
- P2=0xff;
- P0=word[12]; P25=0; delay(60); //第6位顯示F
- P2=0xff;
- P0=word[13]; P22=0; delay(60); //第3位顯示小數點
- CV_disp(C); //顯示測量值
- if(!stop) TR0=0;
- }
-
- while(!uF_check) { //測量電容(uF)
- P30=0;
- if(TR0 && !P33) C=N*160/10000;//取R=100k,C為uF級,則時間常數t=RC=(100*10^3)*(C*10^-6)=C*10^-1;
- //若在t期間對已知脈沖進行計數,且選脈沖頻率f=10k=10^4,
- else N=0; //則計數值N=f*t=1000C(uF),于是應有C=N/1000。
- //C=N*160/10000是為消除誤差所進行的補償運算
- P2=0xff;
- P0=word[11]; P24=0; delay(60); //第5位顯示u
- P2=0xff;
- P0=word[12]; P25=0; delay(60); //第6位顯示F
- P2=0xff;
- P0=word[13]; P22=0; delay(60); //第3位顯示小數點
- CV_disp(C); //顯示測量值
- if(!stop) TR0=0;
- }
- }
- }
復制代碼
所有資料51hei附件下載:
電容測量.7z
(113.41 KB, 下載次數: 98)
2021-11-9 17:50 上傳
點擊文件名下載附件
|