[[lbed]] #contents 2013/08/11からのアクセス回数 &counter; ** LPC1343学習基板に戻って [#dfe6450c] cortex-m3の勉強のために買った「ARMマイコンパーフェクト学習基板の使い方」をlbedを使うとどのくらい簡単に なるかを試してみます。 実験に使用するのは、以下の3つです。 - ARMマイコンパーフェクト学習基板 - LPC-LINK - Star Orangeボードと3.3Vで動作するLCD ** 汎用入出力GPIOの使い方編 [#i15ae2a5] lbedにはまだ汎用入力クラスがありませんので、この機会に作成しました。 詳しくは、[[lbed/08a-ARM学習基板用追加クラス]]を参照してください。 *** 実験開始 [#be68aa6f] ジャンパP4の3と4、31と32にジャンパーをセットし、タッチエリアに触れるとLEDが点灯するテストプログラムを作ります。 タッチセンサーPCF8883の出力オープン・ドレインHigth ((ON時にHightレベルが出力され、OFF時にはハイ・インピーダンスになります)) なので、LPC1343の入力ピンは、プルダウンモードにセットする必要があります。 ((あるいは、プルダウン抵抗を付ける方法もあります)) &ref(TouchSensor.png); テストプログラムTestSwitch.cppは、以下の様になります。 タッチセンサーに触れるとLEDが点灯し、離すとLEDが消えれば成功です。 #pre{{ #include <cr_section_macros.h> #include <NXP/crp.h> // Variable to store CRP value in. Will be placed automatically // by the linker when "Enable Code Read Protect" selected. // See crp.h header for more information __CRP extern const unsigned int CRP_WORD = CRP_NO_CRP ; #include "lbed.h" int main(void) { wait_init(); DigitalOut myled(LED2); DigitalIn sw(P2_4); sw.mode(PullDown); while(1) { myled = sw; } } }} ** USB仮想シリアルポートを使う [#p96d779c] LPC1343では、USBをサポートしており、例題にもCDC(USB仮想シリアルポート) を使っています。 そこで、SerialクラスのサブクラスとしてSerialCDCを作ってUSB CDCを使えるように しました。 ((詳しくは、[[lbed/08a-ARM学習基板用追加クラス]]を参照してください。)) *** USBの実験にはトランジスタが必要 [#f870441a] 当初、ARM学習基板のトランジスタを付けないでUSB CDCのテストをしたら、 上手く動作しませんでした。本を調べて見るとUSB D+ラインのプルアップ制御に トランジスタ2SA1015が必要だと分かり、急遽取り付けました。 &ref(Add_TRG.png); *** テスト用のソース [#od04912d] テスト用のプログラムとしてTestCDC.cppを以下の様に作成しました。 USB CDCが認識されるまで、少し時間がかかるため、最初にキー入力 を待つことにしました。 ((コンパイルには、ForSerialCDC_usbhw.cをTestCDC.cppと同じディレクトリ入れて下さい)) #pre{{ #include <cr_section_macros.h> #include <NXP/crp.h> // Variable to store CRP value in. Will be placed automatically // by the linker when "Enable Code Read Protect" selected. // See crp.h header for more information __CRP extern const unsigned int CRP_WORD = CRP_NO_CRP ; #include "lbed.h" int main(void) { wait_init(); DigitalOut myled( LED2); SerialCDC pc(USBTX, USBRX); pc.baud(9600); // キー入力を待つ pc.read(); pc.println("Hello"); while (1) { char c = pc.read(); pc.write(c + 1); myled = !myled; } return 0; } }} Arduinoのシリアルモニターに出力した様子を以下に示します。 &ref(CDC_Screen.png); ** アナログ入力を試す [#z0651bc6] アナログ入力クラスAnalogInも追加しました。 ((詳しくは、[[lbed/08a-ARM学習基板用追加クラス]]を参照してください。)) *** ジャンパ線の設定 [#c44d4f43] ARM学習基板は、いろんなチップのてんこ盛りなので、実験をするにはジャンパ線で 接続しなくてはなりません。 ((その分、各チップを別の実験に使うことができるようにCPUと切り離されています)) 本の8章、図1からピンの設定の図を引用します。 &ref(Fig8_1.png); P3には、U2から取った基準電圧1.25Vと電圧測定用のOPアンプU3を使って、電圧が供給されています。 - P3の3は、AD6(PIO1_10) - P3の4は、AD7(PIO1_11) - P3の5は、AD3(PIO1_2) に接続されています。 次に、P3とLPC1343の接続について、本の8章、図2を引用します。 OPアンプは、非反転増幅回路となっており、ゲインGは、 \( G_{NI} = \frac{R_1 + R_2}{R_1}\) となることから、P3のCh6, Ch7に入力された電圧は、AGNDとの差が 11倍に増幅された値にAGNDを加算された値がADコンバータの入力電圧 となります。 ((トラ技2013/8号のエレキ数式も便利です)) &ref(Fig8_2.png); *** アナログ回路の動作確認 [#w55a20d9] P3の3番ピンCh6に安定電源1.8Vを半固定抵抗で1.308Vに減圧して入力としました。 $$ V = (1.308 - 1.25)*11 + 1.25 = 1.888 $$ が、Ch6の予想結果です。 &ref(ADC_Test.png); テストプログラムTestADC.cppは、Printクラスの#if文を有効にして使いました。((サイズが大きくなりますので、注意してください)) #pre{{ #include <cr_section_macros.h> #include <NXP/crp.h> // Variable to store CRP value in. Will be placed automatically // by the linker when "Enable Code Read Protect" selected. // See crp.h header for more information __CRP extern const unsigned int CRP_WORD = CRP_NO_CRP ; #include "lbed.h" int main(void) { wait_init(); DigitalOut myled(LED2); SerialCDC pc(USBTX, USBRX); pc.baud(9600); // キー入力を待つ pc.read(); AnalogIn agnd(P1_2); AnalogIn dc(P1_10); while(1) { int d0 = agnd.read_u16(); int v0 = 1250*1024/d0; int d1 = dc.read_u16(); int v1 = v0*d1/1024; pc.printf("Ch3:%04d[VDD=%04dmV] Ch6:%04d[%04dmV]\n", d0, v0, d1, v1); myled = ! myled; wait_ms(1000); } } }} 出力結果は、以下の様になっています。1.896mVと予想と近い結果が出ています。 &ref(ADC_Screen.png); ** 温度センサーIC LM75Bを使ってみる [#teb5224a] ARM学習基板には、I2Cのテストをするために温度センサーLM75Bが付いています。 これを使って、温度を取得してみます。 LM75Bのアドレスは、A2, A1, A0の接続によってユーザが変えることができるようになっています。 (( '1001 + A2, A1, A0がアドレスになります。)) 本の11章の図4は、大きなミスプリがあります。 &ref(Fig11_4.png);&ref(Fig0_2.png); 右がプロローグの図2から引用したものです。この図からLM75Bのアドレスは、1001001(0x49)となります。 *** LM75Bクラス [#a6a6324b] 次にLM75BのクラスをLBED_LPC13xx_USERLIB/src/LM75B.cppに実装します。 本当に驚くくらい簡単でしょう! #pre{{ #include "lbed.h" #include "LM75B.h" LM75B::LM75B(PinName sda, PinName scl) : i2c(sda, scl) { char cmd[2]; // LM73設定 cmd[0] = 0x00; // register 0 cmd[1] = 0x28; // 温度レジスタを選択 i2c.write( LM75_ADDR, cmd, 2); } LM75B::~LM75B() { } float LM75B::read() { char cmd[2]; i2c.read( LM75_ADDR, cmd, 2); // Send command string unsigned int int_val = cmd[0] <<3 | cmd[1]>>5; return float(int_val*125/1000.0); } }} *** LCDとの接続 [#tc6cf18e] アナログ入力の例では、USB CDCを使ったので、今回はLCDを使います。 ARM学習基板のP4とStar OrangeボードのPinとLPC1343ボードピンの対応は、以下の様になります。 | P4 | StarOrange | PC1343 | 機能 |h | 1 | p1 | p1 | GND | | 39 | p40 | p40 | 3.3V | | 33 | p24 | p26 | rs | | 31 | p26 | p22 | e | | 23 | p27 | p14 | d4 | | 21 | p28 | p6 | d5 | | 19 | p29 | p5 | d6 | | 17 | p30 | p25 | d7 | &ref(LM75B.png); *** テストプログラムと結果 [#xd0dbefc] テストプログラムTestLM75B.cppは、以下の様になります。 #pre{{ #include<cr_section_macros.h> #include<NXP/crp.h> __CRP extern const unsigned int CRP_WORD = CRP_NO_CRP; #include"lbed.h" #include "TextLCD.h" #include "LM75B.h" int main(void) { wait_init(); DigitalOut myled(LED2); TextLCD lcd(p26, p22, p14, p6, p5, p25); // rs, e, d4-7 LM75B lm75b(p28, p27); lcd.print("Hello World"); while (1) { float t = lm75b.read(); lcd.locate(0, 1); lcd.print("Temp:"); lcd.print(t); myled = !myled; wait_ms(1000); } return 0; } }} 時計に付いてきた温度計を結果を比べてみました。時計が27.0度、LM75Bが27.50度でした。 &ref(Temp.png); ** まだ途中です! [#t45303f7] ** コメント [#r9e6c373] #comment_kcaptcha