51單片機簡易電容測量儀仿真設(shè)計( proteus仿真+程序+講解視頻)仿真圖proteus7.8及以上
程序編譯器:keil 4/keil 5
編程語言:C語言
設(shè)計編號:S0039
51單片機最小系統(tǒng)的相關(guān)知識
單片機最小系統(tǒng),或者稱為 最小應(yīng)用系統(tǒng),是指用最少的元件組成的單片機可以工作的系統(tǒng)。對51系列單片機來說,最小系統(tǒng)一般應(yīng)該包括:單片機、晶振電路、復(fù)位電路。下面給出一個51單片機的最小系統(tǒng)電路圖。
復(fù)位電路:
一、復(fù)位電路的用途:單片機復(fù)位電路就好比電腦的重啟部分,當(dāng)電腦在使用中出現(xiàn)死機,按下重啟按鈕電腦內(nèi)部的程序從頭開始執(zhí)行。單片機也一樣,當(dāng)單片機系統(tǒng)在運行中,受到環(huán)境干擾出現(xiàn)程序跑飛的時候,按下復(fù)位按鈕內(nèi)部的程序自動從頭開始執(zhí)行。單片機復(fù)位電路如下圖:
二、復(fù)位電路的工作原理在書本上有介紹,51單片機要復(fù)位只需要在第9引腳接個高電平持續(xù)2US就可以實現(xiàn),那這個過程是如何實現(xiàn)的呢?在單片機系統(tǒng)中,系統(tǒng)上電啟動的時候復(fù)位一次,當(dāng)按鍵按下的時候系統(tǒng)再次復(fù)位,如果釋放后再按下,系統(tǒng)還會復(fù)位。所以可以通過按鍵的斷開和閉合在運行的系統(tǒng)中控制其復(fù)位。
開機的時候為什么會復(fù)位:在電路圖中,電容的的大小是10uF,電阻的大小是10k。所以根據(jù)公式,可以算出電容充電到電源電壓的0.7倍(單片機的電源是5V,所以充電到0.7倍即為3.5V),需要的時間是10K*10UF=0.1S。也就是說在單片機啟動的0.1S內(nèi),電容兩端的電壓時在03.5V增加。這個時候10K電阻兩端的電壓為從51.5V減少(串聯(lián)電路各處電壓之和為總電壓)。所以在0.1S內(nèi),RST引腳所接收到的電壓是5V~1.5V。在5V正常工作的51單片機中小于1.5V的電壓信號為低電平信號,而大于1.5V的電壓信號為高電平信號。所以在開機0.1S內(nèi),單片機系統(tǒng)自動復(fù)位(RST引腳接收到的高電平信號時間為0.1S左右)。
按鍵按下的時候為什么會復(fù)位:在單片機啟動0.1S后,電容C兩端的電壓持續(xù)充電為5V,這是時候10K電阻兩端的電壓接近于0V,RST處于低電平所以系統(tǒng)正常工作。當(dāng)按鍵按下的時候,開關(guān)導(dǎo)通,這個時候電容兩端形成了一個回路,電容被短路,所以在按鍵按下的這個過程中,電容開始釋放之前充的電量。隨著時間的推移,電容的電壓在0.1S內(nèi),從5V釋放到變?yōu)榱?.5V,甚至更小。根據(jù)串聯(lián)電路電壓為各處之和,這個時候10K電阻兩端的電壓為3.5V,甚至更大,所以RST引腳又接收到高電平。單片機系統(tǒng)自動復(fù)位。
晶振電路:
晶振電路:晶振是晶體振蕩器的簡稱 在電氣上它可以等效成一個電容和一個電阻并聯(lián)再串聯(lián)一個電容的二端網(wǎng)絡(luò) 電工學(xué)上這個網(wǎng)絡(luò)有兩個諧振點 以頻率的高低分其中較低的頻率是串聯(lián)諧振 較高的頻率是并聯(lián)諧振 由于晶體自身的特性致使這兩個頻率的距離相當(dāng)?shù)慕咏?在這個極窄的頻率范圍內(nèi) 晶振等效為一個電感 所以只要晶振的兩端并聯(lián)上合適的電容它就會組成并聯(lián)諧振電路 這個并聯(lián)諧振電路加到一個負(fù)反饋電路中就可以構(gòu)成正弦波振蕩電路 由于晶振等效為電感的頻率范圍很窄 所以即使其他元件的參數(shù)變化很大 這個振蕩器的頻率也不會有很大的變化
晶振有一個重要的參數(shù) 那就是負(fù)載電容值 選擇與負(fù)載電容值相等的并聯(lián)電容 就可以得到晶振標(biāo)稱的諧振頻率
一般的晶振振蕩電路都是在一個反相放大器(注意是放大器不是反相器)的兩端接入晶振 再有兩個電容分別接到晶振的兩端 每個電容的另一端再接到地 這兩個電容串聯(lián)的容量值就應(yīng)該等于負(fù)載電容 請注意一般IC的引腳都有等效輸入電容 這個不能忽略
一般的晶振的負(fù)載電容為15pF或12.5pF 如果再考慮元件引腳的等效輸入電容 則兩個22pF的電容構(gòu)成晶振的振蕩電路就是比較好的選擇
如上圖:晶振是給單片機提供工作信號脈沖的 這個脈沖就是單片機的工作速度 比如 12M晶振 單片機工作速度就是每秒12M 當(dāng)然 單片機的工作頻率是有范圍的 不能太大 一般24M就不上去了 不然不穩(wěn)定
晶振與單片機的腳XTAL0和腳XTAL1構(gòu)成的振蕩電路中會產(chǎn)生偕波(也就是不希望存在的其他頻率的波) 這個波對電路的影響不大 但會降低電路的時鐘振蕩器的穩(wěn)定性 為了電路的穩(wěn)定性起見 ATMEL公司只是建議在晶振的兩引腳處接入兩個10pf-50pf的瓷片電容接地來削減偕波對電路的穩(wěn)定性的影響 所以晶振所配的電容在10pf-50pf之間都可以的 沒有什么計算公式
P0口的上拉電阻:
P0口作為I/O口輸出的時候時 輸出低電平為0 輸出高電平為高組態(tài)(并非5V,相當(dāng)于
懸空狀態(tài))。也就是說P0 口不能真正的輸出高電平,給所接的負(fù)載提供電流,因此必須接上拉電阻(一電阻連接到VCC),由電源通過這個上拉電阻給負(fù)載提供電流。 由于P0口內(nèi)部沒有上拉電阻,是開漏的,不管它的驅(qū)動能力多大,相當(dāng)于它是沒有電源的,需要外部的電路提供,絕大多數(shù)情況下P0口是必需加上拉電阻的。
1.一般51單片機的P0口在作為地址/數(shù)據(jù)復(fù)用時不接上拉電阻。
2.作為一般的I/O口時用時,由于內(nèi)部沒有上拉電阻,故要接上上拉電阻?。?/p>
3.當(dāng)p0口用來驅(qū)動PNP管子的時候,就不需要上拉電阻,因為此時的低電平有效; 4.當(dāng)P0口用來驅(qū)動NPN管子的時候,就需要上拉電阻的,因為此時只有當(dāng)P0為1時候,才能夠使后級端導(dǎo)通。
31腳EA/Vpp接電源:
STC89C51/52或其他51系列兼容單片機特別注意:對于31腳(EA/Vpp),當(dāng)接高電平時,單片機在復(fù)位后從內(nèi)部ROM的0000H開始執(zhí)行,當(dāng)接低電平時,復(fù)位后直接從外部ROM的0000H開始執(zhí)行,這一點是初學(xué)者容易忽略的。
視頻
基于51單片機簡易電容測量儀仿真設(shè)計( proteus仿真+程序+講解視頻)
1.主要功能:
利用51單片機設(shè)計一個簡易電容測量儀
1.利用51單片機和555芯片構(gòu)成的多諧振蕩電路設(shè)計一電容測量電路
2.通過按鍵切換測量量程,量程由LED指示燈顯示,測量數(shù)值通過LCD1602顯示。
3.量程10pf-500uf
2.仿真
開始仿真
測量300nF 實測數(shù)值269nF
測量30uF 實測數(shù)值26.85uF
3. 程序
#include <reg52.h>
#include "1602.h"
#include "delay.h"
sbit vo = P3^2; // 用于檢測P3.2口的值,計算時間。 計時器0的開與斷
sbit tr = P3^7; // 產(chǎn)生一個低電平脈沖
// 超量程提示燈
sbit ledclc = P2^0;
sbit con1 = P1^5; // 用于控制繼電器,實現(xiàn)檔位選擇
sbit con2 = P1^6;
sbit con3 = P1^7;
sbit key1 = P1^0; // 獨立按鍵部分,用于用戶選擇量程
sbit key2 = P1^1;
sbit key3 = P1^2;
sbit key4 = P1^3;
sbit led1 = P2^1; // 量程提示燈
sbit led2 = P2^2;
sbit led3 = P2^3;
sbit led4 = P2^4;
unsigned int tw; // 用于獲取定時器的數(shù)值
float ftemp; // 用于計算電容值的中間變量
unsigned long int c; // 存放電容值
unsigned char need; // 需要測量時置1,一次測量結(jié)束置0
unsigned char R; // 表示不同的檔位
unsigned char flag; // 數(shù)據(jù)處理結(jié)束置1
unsigned char temp[8]; // 存放電容值的各個位
unsigned char zimu1[] = " range is higher"; //量程太高
unsigned char zimu2[] = "The value of Cap";
unsigned char zimu3[] = "please press key";
unsigned char zimu4[] = " to measure ";
unsigned char zimu5[] = " range is lower ";
void process(unsigned long int c); // 數(shù)據(jù)處理函數(shù)
void keyscan(); // 鍵盤掃描函數(shù)
void ledlight(unsigned char R); // 量程指示燈函數(shù)
void init_timer0() // 定時器0 初始化
{
TMOD = 0x09; // gate置1,方式1,16位計時,定時器由P3.2控制開斷
TH0 = 0x00;
TL0 = 0x00;
EA = 1;
ET0 = 1;
TR0 = 1;
}
void init_INT1 () // 定時器0 初始化
{
EA = 1;
IT1 = 1; // 下降沿觸發(fā)
EX1 = 1;
}
void main()
{
ledclc = 1; // 超量程提示燈熄滅
need = 0; // 一開始無需測量
con1 = con2 = con3 = 1;
flag = 0;
init_timer0(); // 初始化
init_INT1();
LCD_init();
dispchar1(zimu3);
dispchar2(zimu4);
while(1)
{
if(need == 1)
{ // 當(dāng)需要測量時
if(vo == 0 ) //vo == 0時檢測計數(shù)器的值可能還沒開始計數(shù),可能計數(shù)結(jié)束
{
if(TH0 != 0x00 || TL0 != 0x00) // 是計數(shù)結(jié)束 若有讀數(shù),用tw 存下
{
tw = TH0 << 8;
tw = tw | TL0;
TH0 = 0x00; // 一次結(jié)束,計時器清零
TL0 = 0x00;
need = 0; // 需要再次測量時,need置1.避免tw的值被更//改 即不需要測量時,一直保持
EX1 = 1; // 開外部中斷1
}
else // 反之,證明沒有計數(shù),無電容,默認(rèn)值tw置0
{
tw = 0;
}
}
ftemp = tw / 1.1 ; // 計算電容值 根據(jù)公式 tw = 1.1 * R * C
c = (unsigned long int)(ftemp )*100; //擴大了一百倍 便于后續(xù)程序
//取兩位小數(shù)點
process(c); // 調(diào)用數(shù)據(jù)處理函數(shù),根據(jù)不同的R值進行處理
}
if(flag == 1 ) // 數(shù)據(jù)處理結(jié)束 每次處理結(jié)束,證明需要更新顯示的數(shù)據(jù)
{
if(tw>=50000 || ledclc == 0) // 量程超出
{
dispchar3(zimu1); // 量程太高
ledclc = 0;
}
else if(tw<=100 && ledclc == 1) //量程太低
{
dispchar3(zimu5);
ledclc = 0;
}
else
{
dispchar1(zimu2);
disp(temp);
}
flag = 0;
}
}
}
void timer0() interrupt 1 // 定時器0中斷 用于超量程提示
{
ledclc = 0;
}
void exint1 () interrupt 2 // 外部中斷0 用于產(chǎn)生低脈沖,啟動555定時器
{
unsigned char a;
tr = 1; // tr端一個負(fù)脈沖
a = 1;
while(--a);
tr = 0;
a = 20;
while(--a);
tr = 1; // tr端負(fù)脈沖結(jié)束 大約40us的負(fù)脈沖
need = 1; // 表示需要測量
ledclc = 1; // 關(guān)閉先前的超量程提示
EX1 = 0; // 暫時關(guān)閉外部中斷,一次測量結(jié)束,再開放外部中斷
}
void process(unsigned long int c)
{
if(R == 1) // 10M 的電阻 量程10pf ~ 5000pf
{
c = c /10;
lcd_pos(0x4a);
LCD_write_Data(' ');
LCD_write_Data('p');
LCD_write_Data('f');
LCD_write_Data(' ');
LCD_write_Data(' ');
}
if(R == 2) // 100k 的電阻 量程5nf~ 500nf
{
c = c /100;
lcd_pos(0x4a);
LCD_write_Data(' ');
LCD_write_Data('n');
LCD_write_Data('f');
LCD_write_Data(' ');
LCD_write_Data(' ');
}
if(R == 3) //1k歐姆 的電阻 量程0.5uf ~ 50uf
{
c = c /1000; // 擴大了一百倍 單位 c = tw/500 uf
lcd_pos(0x4a);
LCD_write_Data(' ');
LCD_write_Data('u');
LCD_write_Data('f');
LCD_write_Data(' ');
LCD_write_Data(' ');
}
if(R == 4) //100歐姆 的電阻 量程50uf ~ 500uf
{
c = c /100; // 擴大了一百倍 單位 c = tw/500 uf
lcd_pos(0x4a);
LCD_write_Data(' ');
LCD_write_Data('u');
LCD_write_Data('f');
LCD_write_Data(' ');
LCD_write_Data(' ');
}
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;
flag = 1;
}
void keyscan()
{
if(key1 == 0)
{
delay_ms(10);
if(key1 == 0) // b3按下
{
while(key1==0);
R = 1; // 10M 的電阻 量程10pf~ 5000pf(5nf)
con1 = 0;
con2 = 0;
con3 = 0;
ledclc = 1;
dispchar1(zimu3);
dispchar2(zimu4);
}
}
if(key2 == 0) // b4按下
{
delay_ms(10);
if(key2 == 0)
{
while(key2==0);
R = 2; // 100k 的電阻 量程5nf~ 500nf
con1 = 1;
con2 = 1;
con3 = 0;
ledclc = 1;
dispchar1(zimu3);
dispchar2(zimu4);
}
}
if(key3 == 0) // b5按下
{
delay_ms(10);
if(key3 == 0)
{
while(key3==0);
R = 3;
con1 = 0; // 1k歐姆 的電阻 量程0.5uf ~ 50uf
con2 = 1;
con3 = 1;
ledclc = 1;
dispchar1(zimu3);
dispchar2(zimu4);
}
}
if(key4 == 0) // b6按下
{
delay_ms(10);
if(key4 == 0)
{
while(key4==0);
R = 4;
con1 = 0; // 100歐姆 的電阻 量程50uf ~ 500uf
con2 = 0;
con3 = 1;
ledclc = 1;
dispchar1(zimu3);
dispchar2(zimu4);
}
}
ledlight(R);
}
void ledlight(unsigned char R)
{
if(1 == R)
{
led1 = 1;
led2 = 1;
led3 = 1;
led4 = 0;
}
if(2 == R)
{
led1 = 1;
led2 = 1;
led3 = 0;
led4 = 1;
}
if(3 == R)
{
led1 = 1;
led2 = 0;
led3 = 1;
led4 = 1;
}
if(4 == R)
{
led1 = 0;
led2 = 1;
led3 = 1;
led4 = 1;
}
}
4.百度云分享鏈接
下載方式見文章開頭視頻