Arduino UNO

発表されるやすぐに国内でも販売が始まるというリンゴ屋さんのようなマーケティングでやられました。

[以下の話はArduino-0020だけに該当し、Arduino-0021では解決されています]
twitter上でFadeが動かないという話が流れてきましたが、すぐに解決したのはtwitterらしい展開でした。
自分でも調べてみました。
PWMが使えるのはdigitalの3,5,6,9,10,11の6ピンです。
問題はこのうち9と10が点滅しないという症状です。

ピン番号 ポート Arduino タイマレジスタ
5 PD3 d3 OC2B
11 PD5 d5 OC0B
12 PD6 d6 OC0A
15 PB1 d9 OC1A
16 PB2 d10 OC1B
17 PB3 d11 OC2A

これらのピンをPWMで使うときは、analogWrite(pin, val)を使うだけでよく、
AVR-GCCで書くのに比べて非常に簡単になっています。
ソースはwiring_analog.cで石による場合分けがありますが
pinの値がdigitalPinToTimer(pin)によって、TIMERnxとの比較で上の6個のどれかを判別しています。
問題の9,10ピンはどれかというとOC1A,OC1Bに相当し、
TIMER1A,TIMER1Bの部分を見ればよいことがわかります。
やっていることは

TCCR1A |= (1<<COM1A1);
OCR1A = val;

で、他のピンと同じなのでこの辺は関係ないようです。
PWMを動かすためにはモード設定とかプリスケーラの設定がその前に必要なので、それをどこでやっているか探します。
wiring.cで

TCCR1B |= (1<<CS11)|(1<<CS10);
TCCR1A |= (1<<WGM10);

となっていて、プリスケーラは64でphase correct PWMモードに設定していることがわかりました。
Duemilanoveでは問題なく、UNOだけで問題ということなので、
ブートローダが問題があるだろうということで、optiboot.cを見ると

TCCR1B |= (1<<CS12) |(1<<CS10);

というのがあり、電源が入るとブートローダがまず実行されるので、
このレジスタに先程の設定が加わることになります。
すると
TCCR1BはCS12,CS11,CS10のビットが立っているので、データシートによれば
“external clock source on T1 pin. Clock on rising edge.”
の状態にあり、外部クロックがないと動かない状態であることがわかりました。

悪さをしているのは
CS12ですから、

TCCR1B &= ~(1<<CS12);

とすればよいことになります。
デバッグの方法として、

Serial.print(TCCR1B, HEX);

とすれば、レジスタの中身を見ることもできます。
こういうトラブルシューティングをすると、ブラックボックスになっている部分もちゃんとデータシートに書いてあるレジスタが基本なのだということがわかります。パソコンも結局はそうですが、8ビットマイコンはレジスタで動いていることがわかりやすいので初心者には楽しいと思います。
ARMが安くなってきましたが、全貌を理解するのはなかなか大変で私にはまだ先が長そうです。

広告
カテゴリー: Arduino

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

カテゴリー
2010年10月
« 9月   11月 »
 123
45678910
11121314151617
18192021222324
25262728293031
%d人のブロガーが「いいね」をつけました。