2013/08/11からのアクセス回数 7022
cortex-m3の勉強のために買った「ARMマイコンパーフェクト学習基板の使い方」をlbedを使うとどのくらい簡単に なるかを試してみます。
実験に使用するのは、以下の3つです。
lbedにはまだ汎用入力クラスがありませんので、この機会に作成しました。 詳しくは、lbed/08a-ARM学習基板用追加クラスを参照してください。
ジャンパP4の3と4、31と32にジャンパーをセットし、タッチエリアに触れるとLEDが点灯するテストプログラムを作ります。
タッチセンサーPCF8883の出力オープン・ドレインHigth *1 なので、LPC1343の入力ピンは、プルダウンモードにセットする必要があります。 *2
テストプログラムTestSwitch.cppは、以下の様になります。 タッチセンサーに触れるとLEDが点灯し、離すとLEDが消えれば成功です。
#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;
}
}
LPC1343では、USBをサポートしており、例題にもCDC(USB仮想シリアルポート) を使っています。
そこで、SerialクラスのサブクラスとしてSerialCDCを作ってUSB CDCを使えるように しました。 *3
当初、ARM学習基板のトランジスタを付けないでUSB CDCのテストをしたら、 上手く動作しませんでした。本を調べて見るとUSB D+ラインのプルアップ制御に トランジスタ2SA1015が必要だと分かり、急遽取り付けました。
テスト用のプログラムとしてTestCDC.cppを以下の様に作成しました。 USB CDCが認識されるまで、少し時間がかかるため、最初にキー入力 を待つことにしました。 *4
#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(): File not found: "CDC_Screen.png" at page "lbed/08-ARM学習基板で実験";
アナログ入力クラスAnalogInも追加しました。 *5
ARM学習基板は、いろんなチップのてんこ盛りなので、実験をするにはジャンパ線で 接続しなくてはなりません。 *6
本の8章、図1からピンの設定の図を引用します。
P3には、U2から取った基準電圧1.25Vと電圧測定用のOPアンプU3を使って、電圧が供給されています。
に接続されています。
次に、P3とLPC1343の接続について、本の8章、図2を引用します。 OPアンプは、非反転増幅回路となっており、ゲインGは、 \( G_{NI} = \frac{R_1 + R_2}{R_1}\) となることから、P3のCh6, Ch7に入力された電圧は、AGNDとの差が 11倍に増幅された値にAGNDを加算された値がADコンバータの入力電圧 となります。 *7
P3の3番ピンCh6に安定電源1.8Vを半固定抵抗で1.308Vに減圧して入力としました。 $$ V = (1.308 - 1.25)*11 + 1.25 = 1.888 $$ が、Ch6の予想結果です。
テストプログラムTestADC.cppは、Printクラスの#if文を有効にして使いました。*8
#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と予想と近い結果が出ています。
ARM学習基板には、I2Cのテストをするために温度センサーLM75Bが付いています。 これを使って、温度を取得してみます。
LM75Bのアドレスは、A2, A1, A0の接続によってユーザが変えることができるようになっています。 *9
本の11章の図4は、大きなミスプリがあります。
右がプロローグの図2から引用したものです。この図からLM75Bのアドレスは、1001001(0x49)となります。
次にLM75BのクラスをLBED_LPC13xx_USERLIB/src/LM75B.cppに実装します。
本当に驚くくらい簡単でしょう!
#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);
}
アナログ入力の例では、USB CDCを使ったので、今回はLCDを使います。
ARM学習基板のP4とStar OrangeボードのPinとLPC1343ボードピンの対応は、以下の様になります。
| P4 | StarOrange | PC1343 | 機能 |
| 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 |
テストプログラムTestLM75B.cppは、以下の様になります。
#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度でした。