我們繼續來說矩陣按鍵的問題,這次是用在實際電路中的。在仿真中我們沒有發現問題,但是文章最後我提出了,這個電路在實際應用中一定是存在問題的,那麼問題在哪裡呢?
這是我們分析的電路。
前幾篇我們也對硬體進行了測試,我們可以發現,仿真沒有問題,但是凡是按鍵開關,在實際應用中,都會出現按鍵按下響應不穩定的情況,我們稱之為抖動,在實際應用中,抖動的問題,是一定存在的,無論電路優化的多麼完美,那麼我們在現在這個階段,如何處理呢,依然是採用軟體延時消抖大法。
對這個方法不是很熟悉的,可以翻閱前期文章,我們此處不再詳細展開。就直接使用了。抖動的發生,是我們檢測到按鍵的變化開始的,也就是檢測到按鍵發生改變,接著就要消抖了。
P1=0xef; //第四行1110 1111
if(P1!=0xef){keyJS();}
這是我們按鍵檢測的代碼,第一行代碼我們對行進行了置零,然後檢測是那一列發生了改變。當我們檢測到按鍵被按下時,就進入了判斷語句,也就是這個時候,需要進行按鍵的消抖了。為了方便理解,我先把消抖寫在外邊。
原本我們判斷後就會直接進行按鍵的計算輸出,但是這樣就會造成一次按下,卻輸出了三次以上的結果,在有些場合是不行的,會觸發誤動作,所以我們就需要消抖操作。我們這裡採用的是延時消抖的方法,在掃描時,先讓行置零,然後判斷置零後是否有按鍵按下,如果有按鍵按下,那麼此時P1的埠值就會與設定的存在不同,通過判斷不同,來進入判斷語句,為了防止抖動影響,我們先讓按鍵的鍵值保存起來,然後等待一段時間,接著判斷當前的P1值與之前保存的是否一致,如果一致,就認為按鍵按下了,並且已經穩定,然後就可以執行按鍵處理程序了,處理完,為了防止按鍵的連續重複操作,我們需要對按鍵的抬起進行監控,當檢測到按鍵已經抬起,此時緩存值會與P1不同,就會跳出循環,就不會出現長按按鍵,反覆檢測開關,導致連續動作。
好的理論有了,我們進行下仿真。先進行軟體仿真,出現錯誤方便修改。
軟體仿真打開後,導入程序,然後打開運行,首先出現的界面是所有埠都是高電位,P1的低四位在不斷的掃描。接著我們按下任意一個按鍵,按三次看下結果。
可以看到,上方的二極體顯示的是0000 0011,轉譯成十進位就是3.我們為了驗證測試下多次多個按鍵按下,就選擇中間八個按鍵依次按下。
此時顯示的是000 1011,翻譯成十進位就是8+2+1=11,我們操作了11次,顯示11,說明仿真沒有問題,至少證明程序可以實現功能,接下來我們使用電路板測試下。
在程序中運行完美的程序,到了我的電路板上就失控了。
完全沒有反應好不,什麼情況?難道要翻車?我一個好好的教程要變成一個維修課程了。這是我遇到的第一個故障,目前不清楚是硬體還是軟體故障,程序是兩天前寫的,外出兩天回來,第一次下載就這樣,我相信我的硬體應該不會有問題,因為矩陣按鍵很簡單,就是按鍵兩端連上線,然後連接到單片機上就可以了,而LED小燈就更簡單了。那麼消除故障的過程就這麼猝不及防的開始吧,因為後期製作過程中必然會遇到更多的問題。趁著小孩睡覺了,我來看看故障究竟出在哪裡。
我們比較方便的就是去判斷軟體的問題,因為程序出現問題的概率遠遠大於硬體。首先我先寫個測試的文件。新建一個工程吧。
語句就儘可能簡單,主要測試延時和按鍵響應問題。來判斷是否是硬體出了毛病。我會挨個判斷四個按鍵。
編譯後下載到單片機中。呦呵,沒有反應!難道是我太急躁,代碼有問題?我把代碼修改的簡單些。
嗯,這次基本就可以判斷是代碼的問題了,按下按鍵,LED就熄滅了。接下來是四個按鍵測試下。
這是四個按鍵,我先下載看下效果。
哎呦,不錯哦,說明按鍵是沒有毛病的。那就看之前的代碼了,檢查代碼也是個技術活。我們的測試文件中沒有體現出按鍵輸出的處理函數,這次就添加上按鍵處理函數。函數從代碼上沒有看出有什麼問題,通過循環判斷出符合哪一個,然後執行P0加一,然後返回,看似問題不在這裡。
好吧,程序下載好之後,確實沒有反應了。
if(key0==0)
{delay(3);if(key0==0)
{keyJS();while(key0==0);}}
這是判斷的代碼,我把key4置0了,然後再把key0置零,這時P1》01110111》0x77.
按照道理上說,此時應該可以執行才對,為什麼?
我們再把代碼寫的簡單些,看是不是我們程序的流程存在瑕疵。
再次編譯後下載到單片機中測試。我的老天,還是不行,問題不應該在代碼,這個代碼是不會有問題的,我要回過頭查下硬體了,先測試下當我按下P1.0時是否有0電位輸入。
這是按鍵沒有按下時的電壓。我用的是18650電池,電壓是3.9V正常的。
按下P1.0就變成了0V,這說明問題不在此處。
哎呦,電壓也沒有問題呢,什麼情況?我檢查下電路,首先是電源電路,對所有電源進行重現排查,然後重新插緊。再次測試下,然後好了。
這個問題出在哪裡呢?且待我細細分析一番,以免後期同樣故障無法排除。
。。。。。。。
嗯,知道問題在哪裡了,主要是麵包板的問題,因為我們這裡近段時間在下雨,估計南方的同志們也是如此,希望雨水趕快消停。由於天氣潮溼,我得麵包板的負極接線頭有些鏽蝕了,就造成了接觸電阻增加,平時點亮單個小燈還好,但是如果電流增加,例如我們做16個按鍵的掃描,然後8個LED的點亮,就會耗費大量的電流,此時電流的增加,就會造成接觸電阻分壓增加,繼而就會造成單片機電源電壓低於3.3V,處於假死狀態,然後所有埠就會復位,效果跟按下復位鍵一樣,就是硬體死機了。將插針處理好後,就可以了。此時我們之前的程序重新下載到單片機中,再次檢測一下。
指示燈000 1100
指示燈1000 1100
指示燈0100 1100
到這裡基本就可以看出來,代碼運行正常了。通過這次實際運行測試,我們可以看出,實際的操作可以讓我們學習到仿真無法帶來的知識。通過檢修,我們可以明白,往往硬體故障都是有原因的,這些原因都隱藏在電流、電壓這些數據之中。儘管使用PCB製作的板子會穩定很多,但是同樣你對電路的了解也就會少很多,最多知道這是幹什麼的,回頭就會忘記電路怎麼連了。而我們學習單片機的,只寫代碼是徒有靈魂,就像你知道火箭可以飛到月球,可是不會造,豈不是空談?總之好的軟體工程師,必然不會是硬體小白。
馬上放假了,可以多動手練習練習。