原理圖、源代碼汗菜、元件清單等資料下載:戳我
(本教程第一让禀、二節(jié)內(nèi)容請在簡書主頁學(xué)習(xí))
通過本節(jié)學(xué)習(xí)系統(tǒng)時鐘,有助于理解第一陨界、二節(jié)的延時函數(shù)巡揍,也有助于理解在實際的項目中如何選用不同芯片及選擇芯片時鐘頻率。
第二節(jié)的跑馬燈程序中菌瘪,都調(diào)用了一個300ms的延時函數(shù):
void Delay300ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 13;
j = 156;
k = 83;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
讀者可以將第二節(jié)程序中的延時函數(shù)調(diào)用部分屏蔽腮敌,觀察顯示效果
void main(void)
{
unsigned char i,m=0xFE;
while(1)
{
for(i=0;i<8;i++)
{
P0 = m;
m = _crol_(m,1); //循環(huán)左移一次
//Delay300ms(); 屏蔽延時函數(shù)
}
}
}
通過實物觀察可知,當(dāng)屏蔽延時函數(shù)后,只能看到8顆LED全亮效果糜工。這是因為弊添,沒有延時函數(shù),單片機以極快的速度反復(fù)點亮捌木、熄滅LED油坝,由于速度過快,根據(jù)視覺暫停(視覺暫留)現(xiàn)象钮莲,就只能看到全亮效果免钻。
程序中的延時函數(shù)彼水,實際上就是多次循環(huán)執(zhí)行沒有實際功能的代碼(不影響主要功能)〈抻担現(xiàn)在通過邏輯分析,更加形象的認(rèn)識延時函數(shù)在單片機I/O口輸出過程中的作用凤覆。采集到的跑馬燈波形如圖1-3-1所示链瓦,單片機程序為C1-2-4(@11.0952MHz)
不難看出,P0.0到P0.7端口依次輸出低電平后被拉高盯桦,對應(yīng)實物電路中的LED逐個點亮慈俯、熄滅。根據(jù)程序可知拥峦,低電平的持續(xù)時間是300ms贴膘。那么邏輯分析實際測得的低電平持續(xù)時間是多少呢?利用邏輯分析儀的標(biāo)記功能略号,可以很容易的知道單片機I/O口輸出低電平時的持續(xù)時間刑峡,如圖1-3-2所示。
根據(jù)邏輯分析儀可知玄柠,低電平的持續(xù)時間為:|T1-T2|=299.85ms突梦,接近300ms,可以說是符合預(yù)期的∮鹄現(xiàn)在宫患,從新給單片機燒錄一次程序,仍然下載C1-2-4.hex这弧,但下載之前娃闲,設(shè)定時鐘頻率為22.1184MHz,如圖1-3-3所示匾浪。
下載程序后皇帮,觀察實物電路,可以發(fā)現(xiàn)跑馬燈的變化速率與在11.0952MHz時鐘頻率時相比户矢,明顯變快玲献。再次用邏輯分析得到波形,并測出一個低電平的持續(xù)時間,如圖1-3-4所示捌年。
|T1-T2|=149.85ms瓢娜, 149.85 ÷ 299.85 = 0.4997 ≈ 0.5,后者的系統(tǒng)時鐘頻率是前者的2倍礼预,延時函數(shù)代碼沒有改變眠砾,延時時間后者變?yōu)榱饲罢叩?/2。為什么系統(tǒng)時鐘頻率不同托酸,會導(dǎo)致延時函數(shù)的實際延時時間不同褒颈?這就需要引入時鐘周期、機器周期励堡、指令周期概念谷丸。
時鐘周期
計算機工作時,是在統(tǒng)一的時鐘脈沖控制下一拍一拍地進(jìn)行的应结。就像軍訓(xùn)中的齊步走口號刨疼,所有人都跟著同一個口號走,步調(diào)才能一致鹅龄,方隊才能整齊揩慕。而單片機的節(jié)拍是非常精準(zhǔn)的,一個個的節(jié)拍是一個比喻扮休,實際上是脈沖信號迎卤,脈沖信號由單片機控制器中的時序電路發(fā)出。傳統(tǒng)8051單片機玷坠,如經(jīng)常用于教學(xué)的STC89系列單片機蜗搔,需要借助單片機內(nèi)部的振蕩器和外部晶振產(chǎn)生穩(wěn)定的內(nèi)部脈沖,本書所學(xué)習(xí)的STC15系列單片機內(nèi)部集成時鐘電路侨糟,因此不需要外部晶振碍扔。
脈沖是周期性的,通常在8051單片機領(lǐng)域秕重,所說的時鐘周期就是振蕩周期不同。一個時鐘周期,是一個具體的時間溶耘,如單片機外接(或使用內(nèi)部)12MHz的晶振二拐,此時的時鐘周期為1/12us(頻率的倒數(shù)),若使用11.0592Mhz晶振凳兵,時鐘周期為1/11.0592us百新。為了便于計算說明,涉及到計算部分庐扫,本節(jié)都以12MHz為例饭望。
機器周期
在計算機中仗哨,常把一條指令的執(zhí)行過程劃分為若干個階段,每一階段完成一項工作铅辞。例如厌漂,取指令、存儲器讀斟珊、存儲器寫等苇倡,這每一項工作稱為一個基本操作。完成一個基本操作所需要的時間稱為機器周期囤踩。8051系列單片機的一個機器周期同6個S周期(狀態(tài)周期)組成旨椒,一個S周期由2個時鐘周期組成。也就是說堵漱,一個機器周期=6個狀態(tài)周期=12個時鐘周期综慎。當(dāng)單片機工作在12MHz晶振頻率下時,一個機器周期=12 x 1/12us = 1us怔锌。
指令周期
指令周期是執(zhí)行一條指令所需要的時間寥粹,由若干個機器周期組成变过。還是以軍訓(xùn)為例埃元,軍訓(xùn)口號有“一二”和“一二一”。喊一次“一二”向前邁出一步媚狰,喊一次“一二一”岛杀,邁出兩步≌腹拢“一二”和“一二一”可看作兩條指令类嗤,執(zhí)行他們的時間和動作過程都不相同。8051單片機的各種指令辨宠,需要不同的指令周期來完成遗锣。(詳見STC官方手冊《STC15全系列中文資料-第五章第2節(jié)》2015/6/29)
為了便于理解,這里總結(jié)為:一個指令周期由若干個機器周期組成嗤形,8051系列單片機的一個機器周期同6個S周期(狀態(tài)周期)組成精偿。即一個機器周期 = 6個狀態(tài)周期=12個時鐘周期。
由此可見赋兵,8051單片機的系統(tǒng)時鐘頻率最終會影響到指令周期笔咽,現(xiàn)在以NOP指令為例進(jìn)一步說明。
已知在傳統(tǒng)8051單片機中霹期,一個NOP指令的指令周期為1個機器周期叶组,即12個時間周期。STC15系列增強型單片機對NOP指令提速了12倍历造,只需要1/12個機器周期甩十,即1個時鐘周期船庇。當(dāng)系統(tǒng)時鐘頻率為12MHz時,STC15系列單片機執(zhí)行NOP指令所需時間為1/12us侣监,記為t1溢十。
(注:在KeilC51環(huán)境中,不能以某個C語句分析其指令周期达吞,Keil編譯器先把C語言編譯為匯編語言张弛,因此這里使用匯編指令介紹,讀者理解改變指令周期的原理即可)
當(dāng)改變系統(tǒng)時鐘頻率為24MHz時酪劫,執(zhí)行NOP指令仍為1/12個機器周期吞鸭,即1個時鐘周期,但此時時鐘周期為1/24M=1/24us覆糟,即為t2刻剥。
t1=1/12us
t2=1/24us
t1=2 * t2
當(dāng)提成倍數(shù)的提高系統(tǒng)時鐘頻率時,實際上是成倍數(shù)的提高指令周期滩字。第二節(jié)的延時函數(shù)造虏,實際上是多個指令的一個合集,不管用到了何種指令麦箍,當(dāng)系統(tǒng)時鐘提高一倍后(11.0592MHz變?yōu)?2.1184MHz)漓藕,延時函數(shù)中用到的所有指令都提速了一倍,因此300ms的延時函數(shù)代碼最終實現(xiàn)的是150ms延時挟裂。
在前面的介紹中享钞,為了便于計算和延時,選取的時鐘頻率為12MHz和24MHz诀蓉。實際的項目中栗竖,尤其是涉及到串口通信的開發(fā),都是使用11.0592MHz(或其倍數(shù))時鐘頻率渠啤。原因會在后續(xù)的章節(jié)中相信介紹狐肢。此處只需要明白不同時鐘頻率會影響單片機的指令執(zhí)行速度即可。
如何設(shè)計延時函數(shù)
除了IO口的輸入輸出控制沥曹,份名,IIC通信、SPI通信等也都需要不同時長的延時函數(shù)架专,下面介紹常見的延時函數(shù)的設(shè)計方法同窘。
nop()是KEILC51中特有的延時函數(shù)。(使用時需包含intrins.h)
單片機在讀取傳感器部脚、IC芯片數(shù)據(jù)時想邦,如DS18B20,DS1302等委刘,往往需要加入較短的延時丧没。當(dāng)STC15系列單片機工作在12MHz時鐘頻率下時鹰椒,nop()的延時時間為1/12us,當(dāng)工作在11.0592MHz時呕童,延時時間為1/11.0952us漆际,可以近似的認(rèn)為延時時間也是1/12us。
示例代碼:
unsigned char DS1302_ReadByte()
{
unsigned char i,dat = 0;
for (i=0; i<8; i++)
{
SCLK = 0; //時鐘線拉低
_nop_(); //延時等待
_nop_();
dat >>= 1; //數(shù)據(jù)右移一位
if (IO) dat |= 0x80; //讀取數(shù)據(jù)
SCLK = 1; //時鐘線拉高
_nop_();
_nop_();
}
return dat;
}
此代碼功能是單片機讀取DS1302芯片1字節(jié)數(shù)據(jù)夺饲,此處增加短暫的延時奸汇,是因為單片機的IO口被拉低(SCLK = 0)拉高(SCLK = 1)時,STC15系列單片機的執(zhí)行速度非惩快擂找,如果不加延時,會導(dǎo)致DS1302芯片沒有監(jiān)測到外部電平變化浩销,有可能導(dǎo)致數(shù)據(jù)溢出不正常贯涎。
(注:上述結(jié)論可能會因為實際電路、測試環(huán)境差異得出不同結(jié)論)
2 循環(huán)延時函數(shù)
部分傳感器等芯片慢洋,往往需要較長延時塘雳,如延時10us、200us等普筹,此時需要循環(huán)的方式實現(xiàn)較長時間延時“苊鳎現(xiàn)以STC15系列單片機為例,設(shè)計一個簡單的延時函數(shù)斑芜。
程序C1-3-2:
#include"STC15F2K60S2.h"
#include"intrins.h"
void Delay(unsigned int n)
{
while (n--)
{
_nop_();
}
}
void main()
{
while(1)
{
Delay(5);
Delay(10);
Delay(20);
Delay(40);
Delay(80);
Delay(160);
Delay(320);
Delay(640);
}
}
上面的延時函數(shù)實際延時時間是多少呢肩刃?通過KEIL的Debug功能,設(shè)置時鐘頻率為12MHz杏头。Debug過程如圖1-3-5圖1-3-6所示,
執(zhí)行DelayXus(5)的延時時間=0.00007500-0.00006467=0.00001033s≈10.33us
用此方法沸呐,依次求出后面的延時時間醇王,如表1-3-1所示.
函數(shù)名 | 延時時間 單位:us |
---|---|
Delay(5) | 10.33 |
Delay(10) | 18.25 |
Delay(20) | 34.08 |
Delay(40) | 65.75 |
Delay(80) | 129.09 |
Delay(160) | 255.75 |
Delay(320) | 509.25 |
Delay(640) | 1016.08 |
(注:debug方法推導(dǎo)STC15系列單片機延時時,存在誤差)
把Delay(5)
函數(shù)當(dāng)做一個10us延時的基準(zhǔn)崭添,需要50us延時函數(shù)時寓娩,可以直接調(diào)用DelayXus(25)
實現(xiàn),盡管這樣會存在一定的誤差呼渣,但實際項目開發(fā)中棘伴,大多數(shù)傳感器或IC芯片允許這種延時上的誤差,如DS18B20傳感器屁置,官方手冊規(guī)定焊夸,傳感器工作之前,需要一個480至960us的低電平脈沖蓝角,這個范圍很寬阱穗,所以延時函數(shù)不需要特別精確饭冬。
不同芯片或傳感器,也會用到較為精準(zhǔn)的延時函數(shù)揪阶,如跑馬燈的要求“每隔0.3秒點亮一顆LED”這實際上就是明確的延時要求昌抠。這就需要程序設(shè)計者有一定的程序設(shè)計能力,或通過定時器實現(xiàn)鲁僚,或通過循環(huán)實現(xiàn)炊苫。定時器延時會在后面的章節(jié)中介紹,這里主要介紹循環(huán)延時(又叫軟件延時冰沙,非定時器延時)劝评。在程序C1-3-2中,延時函數(shù)并不精準(zhǔn)倦淀,但可以通過計算的方式得到精確延時蒋畜。
這里需要注意,計算代碼延時時間撞叽,并不是簡單的計算C代碼執(zhí)行速度姻成,而是通過編譯后的匯編代碼,延時函數(shù)Delay(unsigned int n)
編譯后的匯編代碼如圖所示愿棋。
根據(jù)匯編代碼科展,設(shè)延時時間為Y,延時函數(shù)形參為X糠雨,時鐘周期為T才睹,可得到下面的公式
Y=18T*X+28T
X=(Y-28T)/18T
當(dāng)系統(tǒng)時鐘頻率為12MHz,需要延時時間為200us時甘邀,形參X=(200-28/12)/(18/12)=131.78≈132琅攘。因此DelayXus(132)就是一個200us的延時函數(shù)。但實際上松邪,這種方法不僅需要懂得編譯后的匯編代碼坞琴,且仍會存在誤差。只能說與粗略的延時相比逗抑,這種方法相對精確剧辐。
(這里不要求讀者掌握匯編代碼,讀者作為了解即可)
3 延時函數(shù)生成軟件
以通過第三方軟件延時計算機器可以得到更為精準(zhǔn)的延時函數(shù)邮府,免去了復(fù)雜繁瑣的計算荧关,STC官方的ISP軟件就提供了軟件延時計算器,如圖1-3-8所示褂傀。
簡單的5步忍啤,就可以計算出需要的延時代碼,第二節(jié)中的300ms延時函數(shù)紊服,就是通過這種方式得到的檀轨。
不同時鐘頻率對項目的影響
以STC15系列單片機為例胸竞,大多數(shù)情況下,時鐘頻率不需要特別考慮参萄。盡管更高的時鐘頻率可以讓CPU更快的執(zhí)行指令卫枝,但有些功能本身并不需要很高時鐘頻率。把第二節(jié)的跑馬燈看做是一種項目需求讹挎,現(xiàn)改為基于22.1184MHz時鐘頻率實現(xiàn)校赤,程序代碼如下。
程序C1-3-3
#include"STC15F2K60S2.h"
#include"intrins.h"
void Delay100ms() //@22.1184MHz
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 9;
j = 104;
k = 139;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void main(void)
{
unsigned char i,m=0xFE;
while(1)
{
for(i=0;i<8;i++)
{
P0 = m;
m = _crol_(m,1); //循環(huán)左移一次
Delay300ms();
}
}
}
對比程序C1-2-4和程序C1-3-1可知筒溃,除了延時函數(shù)代碼不同马篮,主函數(shù)內(nèi)代碼完全相同。無論系統(tǒng)時鐘頻率如何提高怜奖,僅僅是提高了端口輸出金額循環(huán)移位代碼的速度浑测。延時時間依然是300ms。換言之歪玲,輸出語句的執(zhí)行時間在微秒級迁央,即便是提高代碼速度后,還是在微秒級滥崩。微秒級的變化對于300ms的延時來說岖圈,影響微乎其微,人眼根本部分無法覺察區(qū)別钙皮。這里為了讓更高效的CPU實現(xiàn)延時蜂科,實際上是做執(zhí)行了更多的無實際功能的代碼。即便是在較為復(fù)雜的電路中短条,如888光立方控制512顆LED导匣,對比跑馬燈控制8顆LED,數(shù)量上差了64倍慌烧,但在合理的程序邏輯下逐抑,也可以忽略掉時鐘頻率帶來的影響。
在什么時候需要提高時鐘頻率呢屹蚊?通常是在涉及到大量計算的情況下,有必要提高系統(tǒng)時鐘頻率进每。如圖1-3-9所示的項目要求汹粤。
若數(shù)據(jù)處理部分是個比較簡單的公式:i=ii+i3+i*2+100,CPU極短的時間內(nèi)即可處理完成田晚。即便是提高時(或降低)鐘頻率嘱兼,也不會影“每0.1秒通過串口發(fā)送數(shù)據(jù)”的需求。
但隨著項目的復(fù)雜贤徒,影響單片機CPU效率的因素還有中斷芹壕、數(shù)據(jù)結(jié)構(gòu)等因素汇四。假設(shè)數(shù)據(jù)處理的算法非常復(fù)雜,數(shù)據(jù)處理的時間大于0.1秒踢涌,便不能滿足項目要求通孽。此時只有提高時鐘頻率,進(jìn)而提高指令的執(zhí)行速度睁壁,讓CPU處理數(shù)據(jù)的時間盡可能的小于項目所要求的0.1秒背苦。
當(dāng)單片機工作在最大時鐘頻率時,處理一次數(shù)據(jù)的時間仍大于0.1秒潘明,此時只能更為換其他處理速度更快的單片機行剂。這里也必須指出,STC系列單片機與STM32钳降、AVR等芯片比較厚宰,確實存在處理速度上的不足。
或許有讀者會提出遂填,為什么不直接讓所有項目都直接使用高性能芯片開發(fā)呢铲觉?會不會省去了很多后顧之憂?筆者從11年發(fā)布開源設(shè)計至今城菊,包括實際參與的項目開發(fā)备燃,以及和其他單片機工程師交流得到的經(jīng)驗便是,8051內(nèi)核的單片機在硬件成本凌唬、研發(fā)成本并齐、維護(hù)成本及研發(fā)周期上,與其他單片機相比客税,仍具有諸多優(yōu)勢况褪。一個經(jīng)驗豐富的項目研發(fā)主管首要工作就是考慮上述因素對整個項目的影響,特別是在新興的物聯(lián)網(wǎng)行業(yè)中更耻,這些項目對單片機的運算速度要求并不高测垛,單片機往往只作為數(shù)據(jù)采集和遠(yuǎn)端控制,而核心研發(fā)部分在服務(wù)器端或其他帶有操作系統(tǒng)的主控機秧均,因此需要盡可能快速的開發(fā)出硬件部分食侮,以便與軟件平臺對接。此時8051單片機因為結(jié)構(gòu)簡單目胡,開發(fā)周期短锯七,資料豐富,往往成為首選芯片誉己。
綜上所述眉尸,為了滿足不同產(chǎn)品開發(fā)需要,只有深入學(xué)習(xí)并熟練掌握8051芯片結(jié)構(gòu),才能在實際應(yīng)用更好的物盡其用噪猾,也只有熟練掌握8051單片機霉祸,才能權(quán)衡復(fù)雜的項目中,應(yīng)答使用何種芯片袱蜡。
網(wǎng)絡(luò)學(xué)習(xí)以下詞條丝蹭,可有助于理解本節(jié)內(nèi)容。
時鐘周期戒劫、機器周期半夷、指令周期、51單片機總線時序
作者水平有限迅细,編寫過程中難免出現(xiàn)不當(dāng)之處巫橄,還望讀者諸君不吝賜教,或許您有好的建議茵典,歡迎與我聯(lián)系QQ:136678431湘换,作者將報以實質(zhì)性獎勵。