閱讀相關(guān)系列章節(jié)
單片機(jī)關(guān)鍵技術(shù)基礎(chǔ)詳解(一)
單片機(jī)關(guān)鍵技術(shù)基礎(chǔ)詳解(二)
? ? ? ?作為經(jīng)驗(yàn)豐富的嵌入式系統(tǒng)的開(kāi)發(fā)人員,既有大型系統(tǒng)的經(jīng)驗(yàn)(波音777飛行控制)又有小型單人項(xiàng)目(筆記本電腦熱風(fēng)扇控制)經(jīng)驗(yàn),應(yīng)避開(kāi)單臺(tái)機(jī)器或語(yǔ)言的具體利弊,將更多的時(shí)間花在應(yīng)用程序設(shè)計(jì)和構(gòu)建上,并且獨(dú)立于語(yǔ)言和CPU內(nèi)核。這方面部分來(lái)自于對(duì)類似系統(tǒng)的工作,只是“再用于“下一個(gè)項(xiàng)目(雖然要求完全不同,并且切換到了微控制器)。我也參與過(guò)由幾個(gè)獨(dú)立的設(shè)備組成的系統(tǒng),每個(gè)設(shè)備都有自己的程序和微控制器,各部分經(jīng)常在不同的子項(xiàng)目之間來(lái)回使用:某個(gè)子項(xiàng)目中的編碼器可能是另一個(gè)項(xiàng)目的測(cè)試器,或當(dāng)完成自己的子項(xiàng)目的編碼后,會(huì)投入另一個(gè)子項(xiàng)目,以幫助完成項(xiàng)目。缺乏基于系統(tǒng)的設(shè)計(jì)方法會(huì)覺(jué)得這些情況很困難,難以按照計(jì)劃完成。通過(guò)獨(dú)立的系統(tǒng)設(shè)計(jì)可避免機(jī)器依賴性,讓設(shè)計(jì)復(fù)用和基于團(tuán)隊(duì)的設(shè)計(jì)不僅成為可能,而且加大了成功機(jī)會(huì)(如以后的增加要求)。
最近的一個(gè)項(xiàng)目是我更加疑慮,幾乎每次都是,必須使設(shè)計(jì)適應(yīng)(有時(shí)根本就是)所選的語(yǔ)言和機(jī)器。我們已經(jīng)以某個(gè)系統(tǒng)架構(gòu)和設(shè)計(jì)開(kāi)始,只是按一般方式考慮了集成微控制器及其外圍設(shè)備,我們只關(guān)注我們需要什么并不關(guān)心它是如何實(shí)現(xiàn)的,至少我們是這么認(rèn)為的。我們選擇了一些非常專業(yè)外設(shè)的新器件,并且開(kāi)始編碼時(shí),發(fā)現(xiàn)需要花費(fèi)大量的時(shí)間來(lái)了解如何構(gòu)建硬件,以及如何根據(jù)需求最好地利用。當(dāng)我們發(fā)現(xiàn)好的方式來(lái)利用設(shè)備的某特征時(shí),設(shè)備的此特點(diǎn)通過(guò)代碼嵌入了系統(tǒng)級(jí)設(shè)計(jì)。我們已不再堅(jiān)持我們的系統(tǒng),不得不讓機(jī)器和具體操作改變了系統(tǒng)設(shè)計(jì)。于是只好停下來(lái)檢查問(wèn)題和實(shí)施方案,通過(guò)系統(tǒng)重新設(shè)計(jì)分離出依賴機(jī)器的“修復(fù)”,然后將“修復(fù)”融入系統(tǒng)四周的“包裝”中。
當(dāng)設(shè)計(jì)某個(gè)應(yīng)用時(shí)(甚至單一微控制器),以調(diào)溫器為例,有一個(gè)創(chuàng)建好了的系統(tǒng)級(jí)視圖,描述了硬件和實(shí)施某種方式的應(yīng)用程序。該視圖用于多種用途,例如,可作為與高層管理人員或另一個(gè)小組進(jìn)行交流的工具(不希望知道所有細(xì)節(jié)),如自動(dòng)化測(cè)試人員。如果僅將其視為“視圖”而不是系統(tǒng)設(shè)計(jì),并且實(shí)施不是從系統(tǒng)設(shè)計(jì)自上而下,而是將其用作起點(diǎn),則問(wèn)題就出現(xiàn)了??紤]圖1所示的溫控系統(tǒng)。

?
顯示系統(tǒng)相對(duì)簡(jiǎn)單,卻反映了許多嵌入式產(chǎn)品設(shè)計(jì)。在“溫度傳感”部分包含溫度輸入,其輸出進(jìn)入主系統(tǒng)“控制邏輯”部分。“控制邏輯”的其它輸入是標(biāo)記“用戶輸入”的部分,代表人機(jī)接口,大概設(shè)置了恒溫器的溫度調(diào)節(jié)。“控制邏輯”部分根據(jù)這些輸入確定了如何命令供暖、通風(fēng)和空調(diào)(HVAC)系統(tǒng),以保持恒溫器設(shè)定的溫度,將這些命令發(fā)送到“熱與冷命令”部分。最后一個(gè)部分是“顯示輸出”,將當(dāng)前系統(tǒng)狀態(tài)傳遞到用戶。當(dāng)前系統(tǒng)狀態(tài)的一部分是恒溫設(shè)置,另一部分是最新的溫度讀數(shù),最后部分是正在執(zhí)行的命令,以迫使溫度返回恒溫設(shè)置(即加熱、冷卻和/或打開(kāi)或關(guān)閉風(fēng)扇)。
正如前面所述,這是一個(gè)直接和相對(duì)簡(jiǎn)單的應(yīng)用,非常簡(jiǎn)單以至于不需要考慮系統(tǒng),而是很自然地跳到實(shí)施(我相信大多數(shù)讀者甚至可以說(shuō)出最喜歡的微控制器供應(yīng)商的型號(hào))。可以是用于次級(jí)市場(chǎng)的高端PC游戲圖形系統(tǒng)的墻恒溫器或溫度管理裝置。用于墻恒溫器的微控制器的具體實(shí)施基本不需用于圖形系統(tǒng)。重點(diǎn)是,無(wú)論設(shè)計(jì)顯得多么簡(jiǎn)單,都有很好的理由先設(shè)計(jì)系統(tǒng),然后實(shí)現(xiàn)它。將其盡量設(shè)計(jì)成適合通常應(yīng)用。
開(kāi)始時(shí),需要考慮理想的系統(tǒng)設(shè)計(jì),然后生成layers,在理想的系統(tǒng)和實(shí)際實(shí)施之間構(gòu)建wrappers(有時(shí)是雜亂的)?!翱刂七壿嫛辈糠肿鳛榭驁D的核心是有充分理由的-因?yàn)樗窍到y(tǒng)的內(nèi)核。周圍的每個(gè)部分都服務(wù)于“控制邏輯”部分,要根據(jù)需要提供“服務(wù)”。
應(yīng)自“溫度傳感器”部分開(kāi)始。其理由是獲得當(dāng)前/瞬時(shí)溫度,并以一致的格式提供出來(lái)。從“控制邏輯”的角度來(lái)看,其作用是“獲取溫度”,并以格式化的值(xxx.xx攝氏度)返回當(dāng)前溫度值。溫度傳感器部分的硬件wrappers將包括實(shí)施中任何需要用來(lái)將原溫度傳感輸入“翻譯”成預(yù)期格式的攝氏度。這可能意味著需要考慮獲得新讀數(shù)的最佳時(shí)間,如果溫度讀數(shù)中有太多的噪音(無(wú)論何種原因),應(yīng)添加過(guò)濾算法,并且如果溫度硬件出現(xiàn)故障,應(yīng)采用決策邏輯。重點(diǎn)是,“溫度傳感器”部分的輸出是什么,而且傳遞到“控制邏輯”應(yīng)為理想的溫度,所有的噪音,實(shí)際隱藏的細(xì)節(jié)都應(yīng)很容易的由wrapper代替。
如果設(shè)計(jì)需要從系統(tǒng)中三個(gè)不同的點(diǎn)測(cè)量三個(gè)溫度值(對(duì)于計(jì)算機(jī)箱內(nèi)的計(jì)算機(jī)很普遍)怎么辦?處理這三個(gè)溫度是控制邏輯問(wèn)題(例如,何時(shí)多路輸出也將受到控制)?如果是這樣,從1個(gè)溫度轉(zhuǎn)換到3個(gè)溫度首先意味著“溫度傳感器”部分要更新,以提供3個(gè)溫度和為每個(gè)溫度實(shí)施創(chuàng)建的wrappers(允許多種類型的輸入),然后控制邏輯也因?yàn)槎鄠€(gè)輸出而更新。這可能意味著三個(gè)不同的“GetTemperature_n”服務(wù)或需要更新服務(wù)以確定是識(shí)別哪個(gè)溫度的參量。
如果三個(gè)溫度僅僅用于加權(quán)以得到一個(gè)“更真實(shí)”的系統(tǒng)溫度,控制邏輯不需要改變,只需將含wrappers的溫度傳感塊以統(tǒng)一格式輸入這三個(gè)溫度,然后通過(guò)一個(gè)wrappers來(lái)對(duì)這三個(gè)溫度進(jìn)行加權(quán),生成控制邏輯所需的單一溫度。這種方法易于包含來(lái)自不同的溫度輸入(例如,圖形處理器的二極管結(jié)測(cè)量和連接到PCB的模擬熱敏電阻),因?yàn)閣rappers將系統(tǒng)邏輯與硬件隔離開(kāi)。
讓我們以兩個(gè)不同的實(shí)現(xiàn)例子驗(yàn)證這個(gè)論點(diǎn):一個(gè)用于墻恒溫器,另一個(gè)是顯卡上的溫度控制子系統(tǒng)。首先對(duì)于墻恒溫器,如圖2所示,假定使用基于8051的賽普拉斯PSoC3設(shè)備?!皽囟葌鞲衅鳌辈糠值挠布蛇B接到ADC(16位Δ-Σ轉(zhuǎn)換器)的熱敏電阻組成。“用戶輸入”部分的硬件由5個(gè)常開(kāi)按鍵開(kāi)關(guān)組成,一邊連接到電路接地端,另一邊連接到含內(nèi)部上拉電阻的5輸入數(shù)字端口?!盁岷屠涿睢蹦K的硬件部分包括三個(gè)功率場(chǎng)效應(yīng)管,由配置為開(kāi)漏低輸出的3輸出端口驅(qū)動(dòng)。最后,“顯示輸出”塊的硬件實(shí)現(xiàn)是串行字符液晶顯示器,能夠根據(jù)需要顯示字母數(shù)字字符串。

?
對(duì)于第2個(gè)應(yīng)用,即顯示卡,將用戶輸入從離散開(kāi)關(guān)變?yōu)?a href="http://www.www27dydycom.cn/tags/i2c/" target="_blank">I2C基于寄存器的從接口(由主CPU而不是人類直接控制),并將串行LCD顯示變?yōu)镾PI-從控制顯示器(使用一系列的寄存器和指令,可能是安裝在主計(jì)算機(jī)外殼前面板上的遠(yuǎn)程變頻顯示,未安裝到顯卡上)。溫度輸入和HVAC命令保持不變。圖3顯示了早期實(shí)施的變化,假定使用基于8051的賽普拉斯PSoC3設(shè)備。

?
用戶輸入的兩種實(shí)現(xiàn)均可服務(wù)于“GetThermostatSetting”、“IsHeaterEnabled”、“IsCoolerEnabled”和“IsFanOn”。對(duì)于第一個(gè)墻恒溫器應(yīng)用,“用戶輸入”將數(shù)字端口包裝到所列的服務(wù)中,當(dāng)設(shè)備被調(diào)用時(shí),提供端口的實(shí)時(shí)讀數(shù)(一種可能的實(shí)施)。對(duì)于另一個(gè)應(yīng)用,基于I2C從機(jī)的實(shí)現(xiàn),相同的服務(wù)將來(lái)自I2C主機(jī)寫(xiě)入的寄存器的最新值返回到“控制邏輯”部分,也許經(jīng)常返回也許僅在上電時(shí)返回。并且這些實(shí)現(xiàn)還有很多其它特點(diǎn),包括用作切換鍵的墻上按鈕開(kāi)關(guān)而不是瞬間讀數(shù),甚至在“用戶輸入”部分的wrappers深層進(jìn)行邊沿觸發(fā)異步處理。
綜合上述的關(guān)鍵是:系統(tǒng)設(shè)計(jì)隱藏了硬件細(xì)節(jié);硬件和實(shí)施細(xì)節(jié)被系統(tǒng)設(shè)計(jì)包裝并隱藏。通過(guò)外端設(shè)計(jì)(即代碼)的實(shí)施細(xì)節(jié),可以保護(hù)這些應(yīng)用實(shí)現(xiàn)時(shí)避免分裂,可以做到個(gè)性化的設(shè)計(jì),權(quán)衡利弊,保證項(xiàng)目成功交付,并仍然能夠提供可復(fù)用性和組設(shè)計(jì)。不要讓賣方牽引注意力——先設(shè)計(jì)系統(tǒng),然后加強(qiáng)保護(hù)系統(tǒng)設(shè)計(jì)實(shí)現(xiàn)細(xì)節(jié)不被抄襲。
二、單片機(jī)設(shè)計(jì)與KeilC編程總結(jié)
1基本原則
質(zhì)量是關(guān)鍵。沒(méi)有人會(huì)對(duì)很差的工作感到滿足。當(dāng)完成高質(zhì)量的工作時(shí),你會(huì)為此而感到驕傲。不管你是否知道,你都會(huì)因?yàn)槟愕母哔|(zhì)量工作而得到信譽(yù)。因此,要想為自己所做的事感到驕傲,就需要建立個(gè)人標(biāo)準(zhǔn),并為達(dá)到這一標(biāo)準(zhǔn)而努力奮斗。在達(dá)到這些標(biāo)準(zhǔn)時(shí),再提高標(biāo)準(zhǔn)并繼續(xù)努力。挑戰(zhàn)自己去完成更優(yōu)良的工作,你將會(huì)為自己的成就而感到驚訝。
1.1 了解單片機(jī)的能力
【規(guī)則1】設(shè)計(jì)滿足要求的最精簡(jiǎn)的系統(tǒng)。
正確估計(jì)單片機(jī)的能力,知道單片機(jī)能做什么,最大程度的挖掘單片機(jī)的潛力對(duì)一個(gè)單片機(jī)系統(tǒng)設(shè)計(jì)者來(lái)說(shuō)是至關(guān)重要的。我們應(yīng)該有這樣一個(gè)認(rèn)識(shí),即單片機(jī)的處理能力是非常強(qiáng)大的。早期的PC 機(jī),其CPU(8086)處理能力和8051 相當(dāng),卻能處理相當(dāng)復(fù)雜的任務(wù)。單片機(jī)的能力的關(guān)鍵就在軟件設(shè)計(jì)者編寫(xiě)的軟件上。只有充分地了解到單片機(jī)的能力,才不會(huì)做出“冗余”的系統(tǒng)設(shè)計(jì)。而采用許多的外圍芯片來(lái)實(shí)現(xiàn)單片機(jī)能實(shí)現(xiàn)的功能。這樣做即增加了系統(tǒng)成本,也可能會(huì)降低了系統(tǒng)的可靠性。
1.2 系統(tǒng)可靠性至關(guān)重要
【規(guī)則2】使用看門狗。
看門狗電路通常是一塊在有規(guī)律的時(shí)間間隔中進(jìn)行更新的硬件。更新一般由單片機(jī)來(lái)完成,如果在一定間隔內(nèi)沒(méi)能更新看門狗,那看門狗將產(chǎn)生復(fù)位信號(hào),重新復(fù)位單片機(jī)。更新看門狗的具體形式多是給看門狗芯片相關(guān)引腳提供一個(gè)電平上升沿或讀寫(xiě)它的某個(gè)寄存器。使用看門狗電路將在單片機(jī)發(fā)生故障進(jìn)行死機(jī)狀態(tài)時(shí),重新復(fù)位單片機(jī)。當(dāng)前有多種看門狗的芯片,如MAXIM 公司的MAX802,MAX813等。而且,有好多種單片機(jī)中本身就集成有看門狗。一個(gè)外部的看門狗是最好的,因?yàn)樗灰蕾囉趩纹瑱C(jī)。如果可能的話,看門狗更新程序不應(yīng)該放在中斷或是子程序中,原則上應(yīng)該放在主程序中。我曾經(jīng)見(jiàn)過(guò)一個(gè)工程師,他所調(diào)試的程序在運(yùn)行時(shí)偶而會(huì)引起看門狗的復(fù)位動(dòng)作,于是他干脆在每10ms 就中斷一次的時(shí)鐘中斷程序中清看門狗。我相信他也知道使看門狗失去作用,可他卻沒(méi)有不是去查明引起這個(gè)現(xiàn)象的真正原因。因此,我想提醒大家:不論什么理由,絕對(duì)不要忽略系統(tǒng)故障的真正原因。高質(zhì)量的產(chǎn)品來(lái)自于高素質(zhì)的工程師,高質(zhì)量的產(chǎn)品造就高素質(zhì)的工程師。
【規(guī)則3】確定系統(tǒng)的復(fù)位信號(hào)可靠。
這是一個(gè)很容易忽略的問(wèn)題。當(dāng)你在設(shè)計(jì)單片機(jī)系統(tǒng)時(shí),你腦中有這個(gè)概念嗎?什么樣的復(fù)位信號(hào)才是可靠的嗎?你用示波器查看過(guò)你設(shè)計(jì)的產(chǎn)品的復(fù)位信號(hào)嗎?不穩(wěn)定的復(fù)位信號(hào)可能會(huì)產(chǎn)生什么樣的后果?你有沒(méi)有發(fā)現(xiàn)過(guò)你所設(shè)計(jì)的單片機(jī)系統(tǒng),每次重新上電啟動(dòng)后,數(shù)據(jù)變得亂七八糟,并且每一次現(xiàn)象并不相同,找不出規(guī)律,或者有時(shí)候干脆不運(yùn)行,或者有時(shí)候進(jìn)入一種死機(jī)狀態(tài),有時(shí)候又一點(diǎn)事都沒(méi)有正常運(yùn)行?在這種情況下,你應(yīng)該查一下你的系統(tǒng)的復(fù)位信號(hào)。一般在單片機(jī)的數(shù)據(jù)手冊(cè)(Datasheet)中都會(huì)提到該單片機(jī)需要的復(fù)位信號(hào)的要求。一般復(fù)位信號(hào)的寬度應(yīng)為。復(fù)位電平的寬度和幅度都應(yīng)滿足芯片的要求,并且要求保持穩(wěn)定。還有特別重要的一點(diǎn)就是復(fù)位電平應(yīng)與電源上電在同一時(shí)刻發(fā)生,即芯片一上電,復(fù)位信號(hào)就已產(chǎn)生。不然,由于沒(méi)有經(jīng)過(guò)復(fù)位,單片機(jī)中的寄存器的值為隨機(jī)值,上電時(shí)就會(huì)按PC 寄存器中的隨機(jī)內(nèi)容開(kāi)始運(yùn)行程序,這樣很容易進(jìn)行誤操作或進(jìn)入死機(jī)狀態(tài)。
【規(guī)則4】確定系統(tǒng)的初始化有效。
系統(tǒng)程序開(kāi)始應(yīng)延時(shí)一段時(shí)間。這是很多單片機(jī)程序設(shè)計(jì)中的常用方法,為什么呢?因?yàn)橄到y(tǒng)中的芯片以及器件從上電開(kāi)始到正常工作的狀態(tài)往往有一段時(shí)間,程序開(kāi)始時(shí)延時(shí)一段時(shí)間,是讓系統(tǒng)中所有器件到達(dá)正常工作狀態(tài)。究竟延時(shí)多少才算合適?這取決于系統(tǒng)的各芯片中到達(dá)正常工作狀態(tài)的時(shí)間,通常以最慢的為準(zhǔn)。一般來(lái)說(shuō),延時(shí)20-100 毫秒已經(jīng)足夠。對(duì)于系統(tǒng)中使用嵌入式MODEM 等“慢熱”型的器件來(lái)說(shuō),則應(yīng)更長(zhǎng)。當(dāng)然,這都需要在系統(tǒng)實(shí)際運(yùn)行中進(jìn)行調(diào)整。
【規(guī)則5】上電時(shí)對(duì)系統(tǒng)進(jìn)行檢測(cè)。
上電時(shí)對(duì)系統(tǒng)中進(jìn)行檢測(cè)是單片機(jī)程序中的一個(gè)良好設(shè)計(jì)。在硬件設(shè)計(jì)時(shí)也應(yīng)該細(xì)細(xì)考慮將各個(gè)使用到的芯片、接口設(shè)計(jì)成容易使用軟件進(jìn)行測(cè)試的模式。很多有經(jīng)驗(yàn)的單片機(jī)設(shè)計(jì)者都會(huì)在系統(tǒng)上電時(shí)(特別是第一次上電時(shí))進(jìn)行全面的檢測(cè),或者更進(jìn)一步,將系統(tǒng)的運(yùn)行狀態(tài)中分為測(cè)試模式和正常運(yùn)行模式,通過(guò)加入測(cè)試模式對(duì)系統(tǒng)進(jìn)行詳細(xì)的檢測(cè),使得系統(tǒng)的批量檢測(cè)更為方便容易。另外要注意的是,一個(gè)簡(jiǎn)單明了的故障顯示界面也是頗要費(fèi)得心思的。比如:系統(tǒng)的外部RAM(數(shù)據(jù)存儲(chǔ)器)是單片機(jī)系統(tǒng)中常用的器件。外部RAM 如果存在問(wèn)題,程序通常都會(huì)成為一匹脫韁的野馬。因此,程序在啟動(dòng)時(shí)(至少在第一次上電啟動(dòng)時(shí))一定要對(duì)外部RAM 進(jìn)行檢測(cè)。檢測(cè)內(nèi)容包括:1)檢測(cè)RAM 中的單元。這主要通過(guò)寫(xiě)入和讀出的數(shù)據(jù)保持一致。
2)檢測(cè)單片機(jī)與RAM 之間的地址數(shù)據(jù)總線??偩€即沒(méi)有互相短路,也沒(méi)有連接到“地”上。另外,很多芯片,都提供了測(cè)試的方法。如串行通信芯片UART,都帶環(huán)路測(cè)試的功能。
【規(guī)則6】按EMC 測(cè)試要求設(shè)計(jì)硬件。
EMC 測(cè)試要求已經(jīng)成為產(chǎn)品的必需。有很多的文章關(guān)于這方面的。
1.3 軟件編程和調(diào)試
【規(guī)則7】盡可能使用Small 模式編譯
對(duì)比起Large 模式和Compact 模式,Small 模式能生成更為緊湊的代碼。在Small模式下,C51 編譯器將沒(méi)有使用關(guān)鍵詞,如idata、pdata、xdata 特殊聲明的變量通通放在data 單元中。在編程中,對(duì)于在的數(shù)據(jù)區(qū),可以指定放在外部存儲(chǔ)器中。
【規(guī)則8】在仿真前做好充分的準(zhǔn)備
單片機(jī)硬件仿真器給單片機(jī)開(kāi)發(fā)者帶來(lái)了極大的方便,同時(shí)也很容易造成人的依賴性。很多時(shí)候,沒(méi)有仿真器卻能促使工程師寫(xiě)出更高質(zhì)量的程序。也許在硬件仿真調(diào)試之前,下面準(zhǔn)備工作將會(huì)對(duì)你有用:
1)程序編完后,對(duì)代碼仔細(xì)逐行檢查。檢查代碼的錯(cuò)誤,建立自己的代碼檢查表,對(duì)經(jīng)常易錯(cuò)的地方進(jìn)行檢查。檢查代碼是否符合編程規(guī)范。
2)對(duì)各個(gè)子程序進(jìn)行測(cè)試。測(cè)試的方法:用程序測(cè)試程序,編制一個(gè)調(diào)用該子程序的代碼,建立要測(cè)試子程序的入口條件,再看看它是否按預(yù)期輸出結(jié)果。
3)如果代碼有修改,再次對(duì)代碼進(jìn)行檢查。
4)有可能的話,進(jìn)行軟件仿真——Keil C 的軟件仿真功能十分強(qiáng)大。軟件仿真可以防止因硬件的錯(cuò)誤,如器件損壞、線路斷路或短路,而引起調(diào)試的錯(cuò)誤。
5)開(kāi)始硬件仿真。
【規(guī)則9】使用庫(kù)函數(shù)
重用代碼,尤其是是標(biāo)準(zhǔn)庫(kù)的代碼,而不是手工編寫(xiě)你自己的代碼。這樣更快、更容易也更安全。KeilC 中提供了多個(gè)庫(kù)函數(shù),這些庫(kù)函數(shù)的用法在KeilC 的幫助文件中有詳細(xì)的描述。
【規(guī)則10】使用const。
這一點(diǎn)在很多經(jīng)典的關(guān)于C 和C++的書(shū)籍中是必談的要點(diǎn)。在《Exceptional C++》一書(shū)中,對(duì)這點(diǎn)有很精彩的描述,現(xiàn)摘錄如下:“沒(méi)有正確的安全意識(shí)的槍手在世界上是不可能活的很長(zhǎng)的。const 觀念不正確的程序員也是一樣和沒(méi)有時(shí)間戴緊帽子的正確,沒(méi)有時(shí)間檢查帶電電線的電工一樣不會(huì)活的很長(zhǎng)。”在C 語(yǔ)言中,const 修飾符表示告訴編譯器此函數(shù)將不會(huì)改變被修飾的變量的指向的任何值(除了強(qiáng)制類型轉(zhuǎn)換)。當(dāng)把指針作為參數(shù)傳遞時(shí),總是合適地使用const,不僅可以防止你無(wú)意中錯(cuò)誤的賦值,而且還可以防止在作為參數(shù)將指針傳遞給函數(shù)時(shí)可能會(huì)修改了本不想改變的指針?biāo)赶虻膶?duì)象的值。如:
const int num= 7;
num = 9; //有/可能得到編譯器的警告。
const char *ptr,則表示該指針?biāo)赶虻膬?nèi)容不會(huì)被改變,如果在程序中被發(fā)生對(duì)其賦值的操作,編譯時(shí)將出錯(cuò)誤提示。如:
const char *ptr = “hello”;
*ptr = `H`;//錯(cuò)誤,所指內(nèi)容不可改變也可將const 放在星號(hào)后面來(lái)聲明指針本身不可改變。如:
char* const ptr;
ptr++; //錯(cuò)誤,指針本身不可改變
也可同時(shí)禁止改變指針和它所引用的內(nèi)容,其形式如下: const char* const ptr;
【規(guī)則11】使用static
static 是一個(gè)能夠減少命名沖突的有用工具。將只在一個(gè)模塊文件中的變量和函數(shù)使用static 修飾,將不會(huì)和其他模塊可能具有相同名稱的函數(shù)和變量在模塊連接時(shí)不會(huì)產(chǎn)生名稱沖突。一般來(lái)說(shuō),只要不是提供給其它模塊使用的函數(shù),和非全局變量,均應(yīng)使用static 修飾。將子程序中的變量使用static 修飾時(shí),表示這個(gè)變量在程序開(kāi)始時(shí)分配內(nèi)存,在程序結(jié)束時(shí)釋放,它們?cè)诔绦驁?zhí)行期間保持它們的值。如:
void func1(void)
{
static int time = 0;
time++
}
void func2(void)
{
static int time = 0;
time++;
}
兩個(gè)子程序中的time 變量使用static 修飾,所以它們是靜態(tài)變量,每調(diào)用一次time將進(jìn)行加1,并保持這個(gè)值。它們的功能與下面程序相似:
int time1 = 0;
int time2 = 0;
void func1(void)
{
time1++
}
void func2(void)
{
time2++;
}
我們可以看出,使用static 修飾后,模塊中的全局變量減少,使得程序的更為簡(jiǎn)單。
【規(guī)則12】不要忽視編譯器的警告。
編譯器的給出的警告都是有的放矢,在沒(méi)有查清引起警告的真正原因之前,不要忽視它。
【規(guī)則13】注意溢出問(wèn)題,寫(xiě)安全的代碼。
1.4 KeilC 編程
【規(guī)則14】深入了解你所用的工具。
仔細(xì)查看KeilC 附帶的幫助文件,你能找到你期待已久的東西。KeilC 是當(dāng)前最好用的單片機(jī)開(kāi)發(fā)軟件。要充分利用該軟件的功能,就必須對(duì)它深入的進(jìn)行了解。
【規(guī)則15】不要使用語(yǔ)言的冷僻特性,并且記住,耍小聰明會(huì)貽害無(wú)窮。最重要的是編寫(xiě)你理解的代碼,理解你編寫(xiě)的代碼,你就可能會(huì)做得很好。
2 推薦書(shū)目
要成為一個(gè)優(yōu)秀的單片機(jī)系統(tǒng)產(chǎn)品設(shè)計(jì)工程師,興趣、熱情、責(zé)任心至關(guān)重要。
2.1 單片機(jī)技術(shù)學(xué)習(xí)
《微機(jī)原理及應(yīng)用(從16 位到32 位) 》戴梅萼等著清華大學(xué)出版社。學(xué)校教材,也是當(dāng)年我學(xué)習(xí)單片機(jī)的啟蒙書(shū)。
2.2 C51 編程學(xué)習(xí)
《單片機(jī)高級(jí)語(yǔ)言C51 Windows 環(huán)境編程與應(yīng)用》作者:徐愛(ài)鈞彭秀華電子工業(yè)出版社。這本書(shū)幾乎覆蓋了C51 編程的方方面面,最新版本對(duì)當(dāng)前使用最廣的keilC 也有很詳細(xì)的講述。對(duì)于剛學(xué)C51 編程的同志,本書(shū)是上上之選,強(qiáng)力推薦。比起現(xiàn)今書(shū)市上的所謂什么“C51 編程圣經(jīng)”之類的書(shū)強(qiáng)得多。
2.3 C 語(yǔ)言編程必讀
《C 陷阱與缺陷》Andrew Koenig 著
《C 專家編程》Peter Van Der Linden 著
C 語(yǔ)言開(kāi)發(fā)技術(shù)經(jīng)典之作,C 程序員必讀之書(shū),數(shù)十年來(lái)經(jīng)久不衰。如果你想對(duì)C語(yǔ)言全面的掌握,真正了解C 語(yǔ)言的精髓,這兩本書(shū)是必讀之作。由人民郵電出版社出版的中文譯本也還不錯(cuò)。
2.4 程序設(shè)計(jì)技術(shù)方面
《數(shù)據(jù)結(jié)構(gòu)》 嚴(yán)蔚敏 清華大學(xué)出版社。清華大學(xué)出版社的教材質(zhì)量穩(wěn)定,中規(guī)中矩,價(jià)格相對(duì)來(lái)說(shuō)也便宜一點(diǎn)。
《程序設(shè)計(jì)實(shí)踐》Brian W. Kernighan Rob Pike 著;《代碼大全》
三、MCS-51單片機(jī)終端及外中斷軟件編程
?
MCS-51單片機(jī)有多個(gè)中斷源,以8051為例,有5個(gè)中斷源,兩個(gè)外中斷、兩個(gè)定時(shí)中斷和一個(gè)串行中斷,這一節(jié)我們討論外中斷軟件編程。
外中斷是由外部原因引起的中斷,有兩個(gè)中斷源。即外中斷0(INT0)和外中斷1(INT1),中斷請(qǐng)求信號(hào)由引腳P3.2(INT0)和P3.3(INT1)輸入。
外中斷請(qǐng)求信號(hào)有兩種方式,一是電平方式,二是脈沖方式??赏ㄟ^(guò)有關(guān)控制位的定義進(jìn)行規(guī)定。
電平方式為低電平有效,只需在單片機(jī)的(INT0)和(INT1)中斷請(qǐng)求輸入端采樣到有效的低電平時(shí),就會(huì)激活外部中斷。
脈沖方式則在脈沖的后負(fù)跳沿有效,即在相鄰兩個(gè)機(jī)器周期對(duì)中斷請(qǐng)求引入端進(jìn)行采樣中,如前一次為高,后一次為低即為有效中斷請(qǐng)求。這就要求在這種中斷方式,中斷請(qǐng)求信號(hào)的脈沖寬度必須大于一個(gè)機(jī)器周期,以保證電平變化能被單片機(jī)采樣到。
定時(shí)器控制寄存器 (TCON)
外中斷請(qǐng)求方式的控制位在定時(shí)控制寄存器TCON(地址為88H)中的位88(IT0)和位8A(IT1)兩個(gè)位,當(dāng)IT0(IT1)=0為電平方式,IT0(IT1)=1為脈沖方式。同時(shí)在此寄存器中的位89(IE0)和位8B(IE1)為外中斷請(qǐng)求標(biāo)志位,當(dāng)CPU采樣到INT0(INT1)端出現(xiàn)有效中斷請(qǐng)求時(shí),此位由硬件置1。在中斷響應(yīng)完成后轉(zhuǎn)向中斷服務(wù)時(shí),再由硬件自動(dòng)清0。
下面我們對(duì)有關(guān)控制位作說(shuō)明:
·EA——中斷允許總控制位,EA=0,中斷總禁止,禁止所有中斷。EA=1,中斷總允許,總允許位打開(kāi)后,各中斷的允許或禁止由各中斷允許控制位設(shè)置決定。
·EX0(EX1)——外部中斷允許控制位,EX0(EX1)=0,禁止外部中斷。EX0(EX1)=1,允許外部中斷。
·ET0(ET1)——定時(shí)/計(jì)數(shù)中斷允許控制位,ET0(ET1)=0,禁止定時(shí)/計(jì)數(shù)中斷。ET0(ET1)=1,允許定時(shí)/計(jì)數(shù)中斷。
·ES——串行中斷允許控制位,ES=0,禁止串行中斷。ES=1,允許串行中斷。
中斷的允許和禁止就是中斷的開(kāi)放和關(guān)閉,中斷允許就是開(kāi)放中斷,中斷的禁止就是關(guān)閉中斷。從以上說(shuō)明我們可看出,MCS-51的中斷允許是通過(guò)兩級(jí)控制的,以EA位作為總中斷控制位,以各中斷控制位為分控制位。當(dāng)總中斷位為禁止?fàn)顟B(tài)時(shí),不管分控制位是允許或禁止整個(gè)中斷都是禁止的。只有當(dāng)EA=1(允許)時(shí),才能由各分控制位設(shè)置各自的中斷允許與禁止。MCS-51單片機(jī)復(fù)位后,IE=00H,因此中斷處于禁止?fàn)顟B(tài)。
值得一提的是:?jiǎn)纹瑱C(jī)中斷響應(yīng)后不會(huì)自動(dòng)關(guān)閉中斷,因此在轉(zhuǎn)入中斷服務(wù)程序后,應(yīng)由軟件指令禁止中斷。
中斷優(yōu)先級(jí)控制寄存器 (IP)
MCS-51的中斷優(yōu)先級(jí)控制比較簡(jiǎn)單,只設(shè)置了高、低兩個(gè)級(jí)別的有限級(jí),各中斷源的優(yōu)先級(jí)別由優(yōu)先寄存器(IP)進(jìn)行控制。
·PX0——外中斷0(INT0)優(yōu)先級(jí)控制位。
·PT0——定時(shí)中斷0(T0)優(yōu)先級(jí)控制位。
·PX1——外中斷1(INT1)優(yōu)先級(jí)控制位。
·PT1——定時(shí)中斷1(T1)優(yōu)先級(jí)控制位。
·PS ——串行中斷(ES)優(yōu)先級(jí)控制位。
控制位=0,優(yōu)先級(jí)為低??刂莆?1,優(yōu)先級(jí)為高。
中斷優(yōu)先級(jí)是為了中斷嵌套服務(wù)的,控制原則為:
(1) 低優(yōu)先級(jí)中斷不能打斷高優(yōu)先級(jí)的中斷服務(wù),而高優(yōu)先級(jí)的中斷服務(wù)可以打斷低優(yōu)先級(jí)的中斷服務(wù)。
(2) 同級(jí)的中斷已經(jīng)響應(yīng),其他中斷將被禁止。
(3) 如果同級(jí)的多個(gè)中斷源同時(shí)出現(xiàn),CPU將按查詢次序確定哪個(gè)中斷被響應(yīng),次序?yàn)椋和庵袛?→定時(shí)中斷0→外中斷1→定時(shí)中斷1→串行中斷。
中斷控制寄存器的狀態(tài)設(shè)置
在應(yīng)用中,我們可以通過(guò)相應(yīng)的控制寄存器來(lái)使用中斷系統(tǒng),因此從使用的角度上看,這些控制寄存器是面向用戶的。這些控制寄存器既可以進(jìn)行字節(jié)尋址,也可以進(jìn)行位尋址,也就是對(duì)位狀態(tài)的尋址既可以使用字節(jié)操作指令也可以使用位操作指令,例如:
MOV IE,#81H
如使用位操作指令,也可寫(xiě)為:
SETB EA
SETB EX0
對(duì)于一般的外中斷程序,我們可以這樣安排:
ORG 0000H ;主程序入口
START: AJMP MAIN
ORG 0003H ;外中斷程序入口
AJMP INT00
MAIN: MOV IE,#81H ;允許總中斷和外中斷
…… ;主程序
……
……
INT00: …… ;外中斷服務(wù)程序
……
RETI ;中斷返回
?
四、STC89C52最小系統(tǒng)
自己動(dòng)手做了一個(gè)STC89C52單片機(jī)最小系統(tǒng)板,下面是實(shí)物圖!下面是原理圖,拿出來(lái)僅供參考.
單片機(jī)部分
單片機(jī)與PC機(jī)接口部分
測(cè)試部分
現(xiàn)在就做的過(guò)程中遇到的問(wèn)題說(shuō)一下.
1. 線路連接問(wèn)題: 這個(gè)問(wèn)題只要仔細(xì)一點(diǎn)應(yīng)該沒(méi)有什么問(wèn)題.
2.電容選擇問(wèn)題: 在這里很容易出問(wèn)題,一般要選好一點(diǎn)的電容,具體參數(shù)一定要根據(jù)電平轉(zhuǎn)換芯片類型而定. 我在這里選的是電解電容.剛開(kāi)始用的是瓷片電容,發(fā)現(xiàn)不太好用,程序下載不進(jìn)去,所以推薦大家用好一點(diǎn)的電容
3.電平轉(zhuǎn)換芯片最好用進(jìn)口的,國(guó)內(nèi)的不怎么好用.據(jù)說(shuō)容易出問(wèn)題(自己沒(méi)有用過(guò),我用的是美信公司的).可以通過(guò)測(cè)第2腳和第6腳的電壓來(lái)確定電路是否正常工作,一般第2腳電壓為+8.6伏到+10伏之間,第6腳為-8.6伏到-10伏之間.
4.還有當(dāng)時(shí)犯了一個(gè)很幼稚的錯(cuò)誤,就是沒(méi)有搞清接口是公頭還是母頭(公頭的輸出線正好是母頭的輸入線)
5.下載的時(shí)候先點(diǎn)下載,然后再給單片機(jī)上電!
評(píng)論