2011年7月5日 星期二

2.1) Blink part 2

用 _BV() 巨集把程式變得清晰易讀

前一篇的程式,如果用 _BV() 巨集改寫的話,會變得比較清晰易讀:

BV 是 Bit Value 的縮寫。_BV() 巨集的定義為:

所以 _BV(5) 就是 bit 5,由此我們馬上可以聯想到,DDRB |= _BV(5) 這行代表的是「把 PB5 這支腳位設置設 OUTPUT」(註: 1 是 OUTPUT,0 是 INPUT)。

位元遮罩

我們可以把前面的程式稍微改良一下:

利用 bit mask (位元遮罩) 的概念,把 _BV(5) 定義成 bitMask 巨集,這麼一來,當 LED 接到別支腳位,不再是 PB5 時,程式只需要調整 bitMask 巨集,其它地方都不用修改。

Arduino 腳位的位元遮罩對照表

利用位元遮罩的概念,我們可以進一步這樣做:

在這個範例中,我們建了一個 Arduino digital pin 的位元遮罩對照表 digital_pin_to_bit_mask。我們知道, pin 13 就是 PB5,有了這張對照表,就可以很容易算出 pin 13 的位元遮罩,像這樣:

這會得到 _BV(5),也就是 PB5 的位元遮罩,亦即 pin 13 的位元遮罩。

動動腦

雖然上面的程式可以算出 Arduino digital pin 的位元遮罩,但是如果進一步思考會發現一個問題:因為 setup() 和 loop() 已經固定使用 PORTB,所以即便算出其它腳位的位元遮罩,比如座落在 PD2 的 pin 2 (位元遮罩是 _BV(2) ),到時真正受影響的卻還是 PB2。因此,如果你想控制 pin 2,除了改 ledPin 外,你還得修改 setup() 和 loop() 把其中的 DDRB 換成 DDRD,而 PORTB 換成 PORTD,這樣才行。

想想看,這個問題要怎麼解決才好呢?

延伸閱讀

0 意見: