AVR單片機教程——數字輸入

咱們已經學習瞭如何使用按鍵和撥動開關,不知你有沒有好奇 button_down 和 switch_status 等函數是如何實現的。本篇教程帶你一探究竟,讓咱們從按鍵的原理開始。安全

在原理圖中,按鍵的符號以下圖所示:函數

符號很簡單,就是兩個觸點上方有一個動片,當按下時與兩個觸點接觸。實際上按鍵內部的機械結構大致上就是這樣,實現的功能是,沒有按下時兩端斷路,按下時兩端短路。學習

還有一種畫法是這樣的,即電鍵:測試

就按鍵內部的機械結構來講,第一種更加真實,但從電路角度來看,二者沒什麼區別。spa

可是咱們的開發板上的按鍵有4個引腳,這是怎麼回事呢?其實上面兩個和下面兩個分別是連通的,至關於只有兩個:3d

撥動開關,至關於單刀雙擲開關:code

從開發板反面能夠看到撥動開關有3個引腳。撥到上方時,上面兩個導通;撥到下方時,下面兩個導通。blog

然而,光知道這些原理還不夠。任何IC,包括單片機,與外界打交道的惟一途徑是引腳。單片機要知道按鍵狀態,必須由咱們搭建合適的電路,把按鍵和開關的信息轉換爲電平,鏈接到單片機上。教程

先說按鍵吧。按鍵按下時,兩引腳之間導通,若是一端接在某一極(電源或地)上,另外一端的電平就是肯定的。然而,若是不鏈接其餘器件,當沒有按下時,這一端是浮空的,電壓可能高也可能低,是無效的。而咱們但願不按下時檢測到的是另外一種電平,所以咱們能夠在按鍵一端和另外一極之間接一個電路:開發

按鍵接到地,電阻接到電源,這是一種很常見的接法,其中的電阻稱爲上拉電阻,取值幾千歐到幾十千歐都沒啥問題。這個電阻能夠在單片機內部,也能夠是一個獨立的元件。在咱們的開發板上,4個按鍵(以及4個開關,後面會提到)是經過排阻上拉的。

爲何把按鍵接在地上用上拉,而不是接在正電源上用下拉?這是個很複雜的問題。儘管在布爾代數中0和1是徹底對稱的,但電子畢竟是電子而空穴是電子的缺失,因爲某些很複雜的緣由,致使上拉比下拉更加常見(得多)。事實上,AVR單片機的引腳能夠配置獨立的上拉電阻,可是沒有下拉電阻可選(部分新型號中有)。

若是你沒有受過上拉電阻思想的薰陶,對於撥動開關,你可能會想到這種接法:

這種接法不須要額外的元器件,聽起來很妙。然而,雖然可行,這是一種很差的方法。萬一兩個觸點之間短路了怎麼辦?整塊開發板都短路保護了。儘管短路保護聽起來安全,但即便保護起來,在解決短路問題以前,開發板仍是不能用的。還有一種狀況,我真的碰到過,就是單片機上兩個相鄰的讀取開關的引腳由於焊接時的疏忽短路了,致使一旦這兩個開關狀態不同就會觸發短路保護。總之,這種接法不提倡。

與按鍵相似,在開關這邊咱們也能夠用上拉電阻的接法:

利用這兩種電路,咱們成功地將按鍵不按下與按下分別轉換成高電平和低電平,把開關位於下方和上方分別轉換成低電平和高電平。那麼,單片機怎麼讀取電平呢?庫提供了 pin_read 函數,定義在 <ee1/pin.h> 中。咱們仍是經過一個例子來學習其使用方法:保持黃燈和藍燈的狀態分別與按鍵2和開關2的電平相同。

 1 #include <ee1/pin.h>
 2 #include <ee1/led.h>
 3 
 4 #define BUTTON2 PIN_0
 5 #define SWITCH2 PIN_1
 6 
 7 int main()
 8 {
 9     led_init();
10     pin_mode(BUTTON2, INPUT);
11     pin_mode(SWITCH2, INPUT);
12     while (1)
13     {
14         led_set(LED_YELLOW, pin_read(BUTTON2));
15         led_set(LED_BLUE  , pin_read(SWITCH2));
16     }
17 }

異常簡單的例子,不是嗎?用 pin_read 讀取引腳電平,再把LED設置爲相應值。

當程序涉及端口操做時,爲了能在硬件鏈接改變時方便地修改程序,建議用宏或常量創建設備與引腳之間的映射關係。這樣在修改時就只有這個映射關係須要改動了,總比程序每一處調用都修改要方便得多。

值得一提的是,儘管今天的教程介紹了更底層的知識,但這仍不是咱們能達到的最底層的地方。在幾篇教程以後,你就能夠拋棄庫函數了。

 

做業:利用 pin_read 函數,結合以前教程中的知識,實現按鍵動做的檢測並測試之。

相關文章
相關標籤/搜索