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