PWMで音を出す
PWMで音を出すことに挑戦。簡単なはずだったが…
まずは、使用するピンを宣言。
PwmOut pwm21(p21);
ここまでは前回学習したところ。
PWMパラメータの指定。今回は単一周波数を出す。以下は最終形。
pwm21.period_ms(1); //周期の指定
pwm21.write(0.5f); //duty cycleの指定
周期はいいとして、duty cycleの指定がHandbookでは%で指定するように書かれているので、最初は50としていた。すると、コンパイルは通るが、実行時に様子がヘンだ。引数がfloatであることからヘンだと思い、ググッてプログラム例を探すと0.5fとか書いてある。これは%とは言わないと思うが、これもお作法と理解しよう。
学んだこと:
・PWMのduty cycle指定は周期に対する比(<1)で指定する。
DigitalOutのお作法
基板外のLEDをDitialOutでブリンクするようにHello Worldを変更してみたら、はまった。
Handbook(https://mbed.org/handbook/DigitalOut)には
DigitalOut (PinName pin)
と書いてあるので、そのまま書いてみた。
DigitalOut (Mypin21 pin21);
結果はコンパイル・エラー。正解は
DigitalOut Mypin21 (p21);
C/C++の初心者でmbed初心者には「書式どおりに書いたのに、なんで?」と謎。これも「お作法」なのだろうと考えておくことにします。そのうちに正解(理由)が分かるでしょう。
ここまでたどり着くのにあちこち参照した。
学んだこと:
・DigitalOutの書式は DigitalOut ピンの名前 (pinNN);
・mbedの外部ピン指定は p21とか。
参照先: https://mbed.org/handbook/DigitalIn
LED1とは?
Lチカのプログラム例でLEDを光らせる部分は次のように書いてある。
(正確には、どのLEDを使うかの宣言)
DigitalOut Myled(LED1)
このLED1が気になった。
通常なら以下のようにPin番号を宣言するのだけど、ここではLED1となっている。
DigitalOut (PinName pin)
コンパイラでこの部分(LED1)にマウスのカーソルを当てると、画面の右の方にHelpらしきものが表示され、その中にEnumとの単語が見えるので、LED1は予約語として特定のピンを示すと想像。
そこで、青mbedのピン・アサイン表(http://mbed.org/media//img/boardlogos/lpc1768/pinout.png)を見ると、LED1との表示が無い。
続いて青mbedの回路図(http://mbed.org/media/uploads/chris/mbed-005.1.pdf)を見てみる。ここで分かったことは
・LED1~LED4はMCUチップのピンに直接接続されていて、(恐らく)このピンはLED用に専用に使われている。
・他のピンにはDIPxxと書かれているものが多数ある。
なるほど。当然といえば当然だが、MCUピンがPinxxとして外部にアサインされいるのではなく、MCUピンから青mbedのヘッダ・ピンへ配線されて、そこがDIPxxとして青mbedの外部へのインタフェースとなっている。MCUピンから直接配線されているものもあれば、間に回路が入っているものもある。
mbedのコンパイラ上でPinxxと書くと、プラットフォームの情報をコンパイラが解釈して、相当するMCUのピンに命令を送る、という仕組みな訳だ。LEDxも同様で、LED1と書けば、そこを駆動するMCUピンに対して命令が出る、しかもLEDを光らせるのは外部ピンとは別、ということが分かった。
MCU出力をプログラム制御するのではなく、基板全体をブラックボックスと考え、この箱の外部インタフェースを使って入出力する、と理解した。その間にある回路は基板とコンパイラが面倒見てくれるので楽チンなんだな。
AnalogInのHello World
HandbookにあるAnalogInのHello Worldをコピペで実施。
コピペを失敗したのかコンパイル・エラーが出たが、エラー表示の中にFix Itと表示され簡単に対処できた。
ピン番号を変更したりして遊ぶ。この辺は参考書で習った範囲で理解できる。
さて、他の機能も見てみよう。
久々のHello world!
C言語の参考書を読んだので、次は実践。とりあえず、mbedをつないでHello world!(Lチカ)。
操作を思い出すのに少し手間取ったけど、ほぼ順調にLチカ達成。(というほどでもないか)
パラメータを変更して遊ぶ。
プログラムの先頭には # include mbed.h"。ふむ、mbed用のヘッダ・ファイルをインクルードしているのね、と納得。
mainはmain()とvoidが含まれていない。C++では省略できるのか?であれば、main(void)と書いてもいいはず。で試してみる。問題なくコンパイルでき、実行できる。
参考書のおかげで少し理解が進んだので満足。今日はここまで。
(memo: 昨夜書いたものの再投稿)
備忘録.C言語.2
・Cのプログラムは関数の集まり。(関数 = Functionの方がしっくりくる?)
・標準関数 printfとか。入出力関数、数学関数、文字列処理関数、など。
・void 関数が戻り値を持たない時。引数を持たない時。(アテとして置くのね)
・関数の中で宣言するとローカル変数。(グローバル変数の概念はあるのか?)
・変数の格納場所(アドレス)を明示的に扱えるのはオモシロイ。
・関数のプロトタイプ宣言(こういう名前、引数、戻り値で使うよ、と事前に宣言する)
・stdio.hなどのヘッダ・ファイルには関数のプロトタイプ宣言が書かれている。(だから先頭でインクルードする)
・ポインタ 変数のアドレスを記憶している変数。
・ヌル文字(¥0)文字列の終わりを判断するために使う。
・日本語の文字は1文字でも文字列。
・構造体 型の異なる変数を複数まとめたもの。(便利!)
備忘録.C言語.1
C言語の参考書からの備忘録。