AVR單片機教程——撥動開關

在按鍵的上方有4個撥動開關。開關與按鍵,在原理和使用方法上都是很相似的,但有不一樣的用途——按鍵按下後鬆開就會彈起,而開關能夠保存其狀態。html

<switch.h> 定義了與開關相關的函數。switch_status 對應 button_down ,switch_changed 對應 button_pressed ,使用與按鍵是基本相同的。函數

這裏經過一個異常簡單的例子來演示開關函數的使用,並說明開關操做與按鍵的細微差異:使LED與開關狀態保持同步。spa

仿照上一篇教程,咱們能夠簡單地把 button_pressed 替換爲 switch_changed :code

 1 #include <ee1/led.h>
 2 #include <ee1/switch.h>
 3 #include <ee1/delay.h>
 4 
 5 int main()
 6 {
 7     led_init();
 8     switch_init(PIN_NULL, PIN_NULL);
 9     while (1)
10     {
11         if (switch_changed(SWITCH_0))
12             led_flip(LED_GREEN);
13         delay(40);
14     }
15 }

若是把按鍵撥到關(即下)再復位單片機,一切安好,可是若是一開始是開的狀態,LED的狀態會老是與開關相反。爲何呢?由於開關能夠保存狀態,這是第一個差異。htm

因此,咱們能夠每次得知開關狀態改變後讀取開關狀態,並傳給LED:blog

 1 #include <ee1/led.h>
 2 #include <ee1/switch.h>
 3 #include <ee1/delay.h>
 4 
 5 int main()
 6 {
 7     led_init();
 8     switch_init(PIN_NULL, PIN_NULL);
 9     while (1)
10     {
11         if (switch_changed(SWITCH_0))
12             led_set(LED_GREEN, switch_status(SWITCH_0));
13         delay(40);
14     }
15 }

這也引出了第二個差異——當 switch_changed 返回 true 時,咱們不能直接知曉開關的狀態,須要手動調用 switch_status ;而對於相應的按鍵操做,咱們知道此時按鍵必定處於按下的狀態。教程

若是復位時開關狀態爲開,除了第一次撥動按鍵之前,LED老是與按鍵同步的。然而咱們的要求是保持同步,固然包括一開始的時候。爲了得到正確的初始狀態,咱們能夠在進入主循環前添加如下代碼:ip

1 if (switch_status(SWITCH_0))
2     led_set(LED_GREEN, true);

但事實上,這個問題根本沒有那麼麻煩,甚至不須要 switch_changed 函數——每次循環讀取開關狀態,再把LED設置成相應狀態便可:get

 1 #include <ee1/led.h>
 2 #include <ee1/switch.h>
 3 #include <ee1/delay.h>
 4 
 5 int main()
 6 {
 7     led_init();
 8     switch_init(PIN_NULL, PIN_NULL);
 9     while (1)
10     {
11         led_set(LED_GREEN, switch_status(SWITCH_0));
12         delay(40);
13     }
14 }

你一開始有沒有想到這個簡單的方案?若是有,而且第一反應就是這個,那你得開始逐漸改變思路了。這種方案在這個例子中可用,是由於對 led_set 和 switch_status 的調用的成本是很低的,每次循環都調用也沒有問題。然而這並非放之四海而皆準的,有些函數經不起這樣頻繁的調用。在那樣的狀況下,檢測狀態改變,再讀取狀態,是一種更好的方案。同步

 

思考:在斷定按鍵動做的函數中,前一次狀態經過靜態變量存儲,其初值爲真,保證第一次調用時函數不會返回真;對於開關動做,相應靜態變量的初值應該是什麼?

做業:每一個開關控制一個LED,一個按鍵控制開關是否啓用;啓用時要讓LED與當前開關狀態對應,禁用時要關閉全部LED。

相關文章
相關標籤/搜索