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