與Bug斗爭(zhēng)其樂(lè)無(wú)窮
玩轉(zhuǎn)單片機(jī)有幾年的時(shí)間了,從接觸51開(kāi)始就走上了看不到盡頭的程序員之路。也許大多會(huì)認(rèn)為,敲了幾天幾夜代碼將作品或者項(xiàng)目完美完成的那一刻是最開(kāi)心最得意的時(shí)候。我卻認(rèn)為,真正快樂(lè)的是與Bug斗爭(zhēng)的過(guò)程,最后完成作品或項(xiàng)目只是這種快樂(lè)的終點(diǎn)。那么我們?cè)撛趺慈?duì)待Bug才能做到,游走在Bug世界里享受無(wú)盡的快樂(lè)。
本文引用地址:http://m.butianyuan.cn/article/158899.htm一些高手在程序的編寫方面都有了自己的風(fēng)格,可以將程序做很好的規(guī)劃。以縝密的思維構(gòu)造程序架構(gòu),以編程規(guī)范來(lái)打造程序的外觀。Bug已經(jīng)在高手面前無(wú)所遁形。所以Bug只是高手們用來(lái)愉悅的玩物。用來(lái)享受那一刻的征服感。為了讓菜鳥(niǎo)也能享受其中的快樂(lè),我分享一下自己的經(jīng)驗(yàn),讓大家能在程序員這條路上走的快樂(lè),而不是整天熬夜帶來(lái)的孤獨(dú)感,菜鳥(niǎo)入門通常以89c52單片機(jī)入門,那么我就針對(duì)這個(gè)講講如何破Bug。
1.裝上攝像頭定點(diǎn)監(jiān)控
找出Bug就像找小偷一樣,我們需要在程序中裝上多個(gè)攝像頭,當(dāng)程序出現(xiàn)問(wèn)題時(shí)我們可以知道是在哪一個(gè)地方。這點(diǎn)是相當(dāng)?shù)膶?shí)用,對(duì)于無(wú)法仿真的51單片機(jī),要了解程序內(nèi)部運(yùn)行的狀態(tài)和變量現(xiàn)在的值,就顯得很無(wú)語(yǔ),簡(jiǎn)直束手無(wú)策。那么就請(qǐng)加入串口程序的代碼,利用串口將一些重要變量的值或者信息發(fā)送到上位機(jī)上進(jìn)行觀測(cè)。這樣就像是在各點(diǎn)裝上了攝像頭,而監(jiān)控畫面就是我們的上位機(jī)軟件。串口的收發(fā)程序都有成熟的模塊所以初學(xué)者也不用擔(dān)心用不了的問(wèn)題?,F(xiàn)階段如果寫不出來(lái)就直接COPY來(lái)用用反正也不用錢,所以在調(diào)試的時(shí)候要充分發(fā)揮串口的作用,讓問(wèn)題變得清晰明了。用的最多就是發(fā)送字符串,發(fā)送16進(jìn)制數(shù)據(jù)和十進(jìn)制數(shù)據(jù)。列舉一個(gè)小小的例子:
例一:感覺(jué)程序中是沒(méi)運(yùn)行到子函數(shù)A中。
那么就不要只感覺(jué)了,就在A中放上一個(gè)攝像頭用來(lái)監(jiān)控此處。在子函數(shù)A的開(kāi)頭加一句發(fā)送字符串的程序:
UartSendString(“現(xiàn)在進(jìn)入函數(shù)A了哦!n”); //發(fā)送到上位機(jī)看是否運(yùn)行了函數(shù)A。
這樣大家體會(huì)到攝像頭的作用了吧,時(shí)刻掌握程序運(yùn)行的狀況。讓Bug逃不出手掌心。
2. 清晰的路標(biāo)
所謂清晰的路標(biāo)的第一個(gè)意思就是在程序中加入詳細(xì)的注釋,在追捕Bug中我們要看路標(biāo),分析他會(huì)逃串到哪里。單片機(jī)編程就是一個(gè)邏輯思維。我一直將89C52單片機(jī)看作是一個(gè)沒(méi)頭沒(méi)腦只有幾十個(gè)腳的小笨蛋。這個(gè)小笨蛋能完成各種小制作是靠什么呢?當(dāng)然是靠我們偉大的程序員來(lái)給他灌輸思想,告訴他如何去運(yùn)用自己的幾十個(gè)腳。當(dāng)測(cè)試當(dāng)中這個(gè)小笨蛋沒(méi)有按照我們的想法去做事,那么就肯定是哪里的邏輯出現(xiàn)了問(wèn)題。這個(gè)時(shí)候程序的注釋就體現(xiàn)出了優(yōu)勢(shì)。我們按照自己寫下的路標(biāo)來(lái)將整個(gè)路程走一遍,看是否有什么漏洞導(dǎo)致迷路。那么整個(gè)運(yùn)行過(guò)程就無(wú)法逃離自己的掌握之中。這點(diǎn)就不舉例了,大家在實(shí)踐中體會(huì)吧。只需要將程序看作一條路,自己在頭腦中走一邊就行。
清晰的路標(biāo)除了指程序中的注釋還指每個(gè)變量和每個(gè)函數(shù)的命名清晰明了。這就是所說(shuō)的程序規(guī)范。如果程序規(guī)范了,就好像是給了程序一個(gè)鐵的紀(jì)律。程序可讀性提高,看起來(lái)也美觀。可以說(shuō)每個(gè)人寫程序都有自己的風(fēng)格,如果是剛接觸單片機(jī)的童鞋就不一定了。變量總是i和j或者來(lái)幾個(gè)k , y , z。函數(shù)名都有可能是void abc(); 如果真這樣,那就悲劇了。這樣調(diào)試的時(shí)候很迷茫,程序的直觀性不好。在調(diào)試中還要不停的跳轉(zhuǎn)到對(duì)應(yīng)的函數(shù)來(lái)看看這個(gè)到底完成的是個(gè)什么功能。我給大家兩個(gè)小建議吧,如果現(xiàn)在還沒(méi)有規(guī)范自己程序的童鞋可以借鑒一下:
(1)函數(shù)名和變量名盡量用英文單詞組成或者其縮寫組成。我列舉幾個(gè)ucGUI里的一些函數(shù)名:GUI_DispStringAt(); GUI_DrawHLine(); GUI_Clear(); GUI_SetColor(); 有了很規(guī)范的命名,大家只學(xué)要看到函數(shù)名就知道這個(gè)函數(shù)是什么功能。變量名我也列舉ucGUI里面的幾個(gè)GUI_RED ,GUI_TM_NORMAL。大家看變量名也可以知道是什么意思。這個(gè)就是規(guī)范了函數(shù)名和變量名的好處
(2)如果是指針變量前面加個(gè)p,如果是全局變量前面加個(gè)g。變量名由幾個(gè)單詞組成的中間加上“_”來(lái)隔開(kāi)。
說(shuō)到這里,我們只是做了對(duì)抗Bug的一個(gè)前期準(zhǔn)備。只要做好上面幾步,那么親愛(ài)的菜鳥(niǎo)就可以不用對(duì)51單片機(jī)的Bug產(chǎn)生恐懼,接下來(lái)就是你玩弄Bug的過(guò)程了。有人說(shuō)些程序的人本身就有一種霸氣,一種渴望征服的愉悅感。因?yàn)槌绦騿T可以控制一樣?xùn)|西完全按照自己的思維去運(yùn)行。我個(gè)人也是這么認(rèn)為的。所以做好上面幾步,你就可以將程序看作是你手中的玩物。我總結(jié)了幾條針對(duì)51單片機(jī)對(duì)抗Bug的技巧:
(1)在重要的點(diǎn)放上攝像頭UartSendString(“提示的內(nèi)容”);
(2)對(duì)于變量的觀察就將數(shù)據(jù)發(fā)送到上位機(jī)觀察。
(3)碰到卡死現(xiàn)象可以按照(1)的方法,將發(fā)送提示信息的函數(shù)多放幾個(gè)地方來(lái)了解程序運(yùn)行的情況
(4)如果是邏輯上的錯(cuò)誤就好好回顧一下程序,通過(guò)注釋再來(lái)理清思路,找Bug游戲不能心急。
(5)要定點(diǎn)檢查一個(gè)地方可以加入強(qiáng)制卡死while(1);
3. 后續(xù)工作
通過(guò)上面的兩點(diǎn)基本上可以找出程序中的Bug,既然找出來(lái)了,只要對(duì)癥下藥,除掉他必然不是難事。如果自己除不掉也可以找度娘和各種論壇,因?yàn)槟悻F(xiàn)在知道了明確的問(wèn)題,可以有針對(duì)性的去找解決的辦法。那么程序都調(diào)試完成了,但是程序中還余留下一些我們調(diào)試時(shí)候的殘?jiān)?,這個(gè)怎么辦的。那么就要使用一些小技巧怎么一次性清楚所有的攝像頭呢?
在程序中可以這樣寫:
在程序的開(kāi)頭或者頭文件里定義:#define HAPPY_DEBUG
在程序調(diào)試時(shí)加入攝像頭就按照如下的格式:
??????? #ifdef HAPPY_DEBUG
?????????????? UartSendString(“現(xiàn)在進(jìn)入函數(shù)A了哦!n”);
??????? #endif
寫程序是很短的時(shí)間,調(diào)試程序是一個(gè)漫長(zhǎng)的過(guò)程。只有做好前期的準(zhǔn)備后面依靠自己的調(diào)試技巧,就能玩弄Bug于鼓掌之中,而不是被Bug搞的頭昏腦脹。找出Bug的那一瞬間就是快樂(lè),解決Bug的那一刻更是興奮。這就是與Bug斗爭(zhēng)的快樂(lè)所在。在孤獨(dú)的程序員道路上我們也要尋求自己的快樂(lè),這就是其中之一。
51單片機(jī)相關(guān)文章:51單片機(jī)教程
攝像頭相關(guān)文章:攝像頭原理
評(píng)論