前面一貼簡單討論了一下51單片機的IO輸出功能 既然是IO,有output肯定就有input 今次咱聊聊input,,輸入功能 有了input,,51就能夠根據(jù)輸入的信號 去做出下一步工作的決定 其實單片機的輸入不外乎就是兩種 一是數(shù)字輸入,由單片機去判斷輸入的高低電平 再就是模擬輸入,,最典型的就是內(nèi)置ADC外設(shè)的單片機 可以把外部輸入的電壓值與基準電壓進行比較 從而得到一定數(shù)值的二進制編碼 譬如基準電壓3.3v,,12位的線性ADC外設(shè) 就可以將外部輸入的0-3.3v電壓按比例用0-4096的十進制數(shù)去表示 換成二進制便是000000000000-111111111111 限于手頭上51片子沒有AD這個外設(shè) 咱今天聊的輸入,就從數(shù)字輸入下手 一,、按鍵基本原理 先上電路 先看上面一個圖 P0.1口,,連接到一個10k的電阻,上拉到電源Vcc(這里Vcc=5.0v) 同時連接到按鍵的一端 按鍵的另一端則直接連到地 簡單分析一下這個電路 當(dāng)按鍵沒有按下的時候 10k電阻和P0.1口沒有連接到地 由于P0端口是開漏輸出,,可以看做是懸空 那么經(jīng)過10k電阻的電流為0,,即10k電阻的壓降為0 這個時候,可以認為P0.1口的電位是5.0v,,一個高電平 So,,按鍵沒有按下,單片機可以認為P0.1口輸入了一個邏輯“1”,,也就是高電平 當(dāng)按鍵按下時 P0.1口和10k電阻均被連接到了地 這個時候,,P0.1口的電位直接被拉到0v,也就是地 So,,單片機可以認為P0.1口輸入了一個邏輯“0”,,也就是低電平 這里尤其注意一下這個10K電阻的作用 名曰上拉電阻 它的存在是非常有必要的 沒有這個電阻,P0.1口直接連接到按鍵一端或者電源,,都會產(chǎn)生不好的后果 如果直接連至電源,,按鍵按下的時候,,Vcc和地……,,后果你懂的…… 如果直接連接到按鍵的一端,在按鍵按下前 P0.1都是懸空的,,外界的干擾(EMI之類),,非常容易引起單片機的誤判 它的作用主要是按下前穩(wěn)定電平、按下后限流 在按鍵按下的時候,,電源—10k電阻—地 這個回路中 會產(chǎn)生5/100000=5mA電流,,產(chǎn)生一定的功耗 有朋友會想,加大電阻就可以解決這個問題了呀 但是電阻太大的話,,可能會出現(xiàn)開路情況 So,,幾k到幾十k是比較合適的 再看下面一個圖 嗯,簡單的發(fā)光二極管回路 這里就不多解釋了 順道拿電木板焊了個電路 電源,、地和2個IO口用排針等插 菊花面,,10k上拉電阻和220歐LED限流電阻 這個電木板質(zhì)量真次,,焊盤掉了好幾個 51讀端口的代碼特別簡單 只要直接按位或者按port來逐位讀取即可 譬如要把P01口的邏輯值賦給變量temp 直接temp = P01即可 P01輸入一個低電平,temp=0x00 P01輸入一個高電平,,temp=0x01 上個測試代碼
簡單閱讀一下代碼 大概的功能就是判斷P01口電平是否為0 為0的話,,P11口電平取反,,也就是LED點亮或者熄滅 編譯下載,看看結(jié)果 不難發(fā)現(xiàn) 按鍵雖然能夠控制51去點亮或者熄滅LED 但是似乎并不是那么順手 不能非常準確地操作LED的亮或者滅 為嘛,? 二,、去抖 在解決上面問題之前 必須意識到,按鍵其實是一個機械彈性開關(guān)結(jié)構(gòu) 在按下或者松開的瞬間,,也就是機械觸點斷開,、閉合時 不會穩(wěn)定地接通或者斷開,存在一連串的抖動 這種抖動時間與按鍵的機械特性有關(guān),,幾個ms到幾十個ms都有可能 由于51執(zhí)行代碼的速度是us級 So,,自己感覺只按下了一次按鍵 其實51已經(jīng)反復(fù)多次執(zhí)行了按鍵按下的操作 所以造成上面gif中的現(xiàn)象 所以,按鍵去抖,,是無論哪種單片機都需要面臨的問題 當(dāng)然,,有些比較有特點的單片機會有按鍵相關(guān)的外設(shè),無需過多關(guān)注去抖,,這個在此不討論 有關(guān)去抖,,有硬件和軟件兩種辦法 硬件上去抖的辦法 第一種是使用RS觸發(fā)器/鎖存器 鎖存器的工作特點就決定了,即使有按鍵抖動,,也不會影響上如兩個與非門構(gòu)成的RS鎖存器的輸出 再一種是在按鍵上并聯(lián)一個合適大小的電容 其實就是利用電容充放電的特性,,無它 硬件去抖,基本上不占用單片機的資源 致命的缺陷是需要額外的器件 會使PCB面積,、BOM,、成本有所增加 在成本為王的時代,基本上這種辦法很少有人使用了 但是非??煽?/p> 再來看看軟件去抖 第一種是使用延時去抖,,是目前用得比較多的 上個代碼
簡單分析一下上面的代碼 最最核心的就是 如果發(fā)現(xiàn)P01的按鍵被按下 就延時100ms后再讀一下P01的值 注意一下,這里的100ms其實和按鍵的機械特性有關(guān) 根據(jù)實際情況調(diào)整 如果還是被按下的狀態(tài),,則認為按鍵確實被按下 單片機再進行下一步操作 上個GIF 可以發(fā)現(xiàn) 按鍵已經(jīng)可以很準確地控制LED的亮滅了 但是,,單片在執(zhí)行delay_ms(100)的時候 其它任何事情都不能做呀 所以很多時候,這個延時會采用定時器中斷來完成 這個后面再討論 其實還有一種不需要延時的去抖方法 可以理解成一個狀態(tài)機 上代碼
利用狀態(tài)機的編程思想 代碼上有解釋了,,這里不過多深入討論 上GIF 可以看得出來 其實效果也還不錯 三,、矩陣鍵盤 到這里,一個基本鍵盤需要考慮的東西 大概就是這么多了 還有一種針對比較多按鍵的電路組態(tài) 叫做是矩陣鍵盤 簡單介紹一下吧 上個結(jié)構(gòu)圖 上圖是個4x4鍵盤,,16個按鍵 按照前面的方法,,得需要16個IO口才能完成接入 這里其實只需要P1口的8個端口即可 這種矩陣鍵盤判斷按鍵的方法有好幾種 用的比較多的有2種 一是行/列掃描法,分兩步 1,、判斷鍵盤中有無鍵按丿將全部行線Y0-Y3置低電平,,然后檢測列線的狀態(tài)。只要有一列的電平為低,,則表示鍵盤中有鍵被按下,,而且閉合的鍵位于低電平線丿根行線相交叉皿個按鍵之中。若所有列線均為高電平,,則鍵盤中無鍵按下 2,、判斷閉合鍵所在的位置 在確認有鍵按下后,即可進入確定具體閉合鍵的過程,。其方法是:依次將行線置為低電平,,即在置某根行線為低電平時,其它線為高電平,。在確定某根行線位置為低電平后,,再逐行檢測各列線的電平狀態(tài)。若某列為低,,則該列線與置為低電平的行線交叉處的按鍵就是閉合的按鍵 再一個是翻轉(zhuǎn)法,,三步 1、行線輸出全為0,,讀出列線值,。 2、列線輸出上次讀入的列線值,。 3,、讀入行線值,,并與前次列線值組合,,生成組合碼值。根據(jù)這個組合碼來確定被按下的按鍵,。 沒來得及做個矩陣鍵盤 如有疑問,,可把問題發(fā)送給“云漢電子社區(qū)”微信公眾號平臺,我們會及時回復(fù),,關(guān)注公眾號可閱讀更多51系列教程,!我們歡迎您的溝通,! |
|