LPC111xマイコンのピン機能設定の注意点

LPC111xマイコンのピン機能は基本的にはGPIOがデフォであり、IOCONFIGレジスタのFUNC=0がGPIOとなっているが、一部そうでないピンがある。特に下記(2)の場合が要注意である。

(1) RESET, SWCLK, SWDIO

RESET, SWCLK, SWDIOのピン(PIO0_0, PIO0_10, PIO1_3)は、こちらの機能がデフォ(FUNC=0)となっており、FUNC=1でGPIOになる。これはまあ当然のことである。

(2) FUNC=0が予約となっているピン

PIO0_11, PIO1_0, PIO1_1, PIO1_2はなぜかFUNC=0が「予約」となっており、FUNC=1でGPIOになる。

LPCXpressoでのコード例

    // PIO0_1 は FUNC=0 が GPIO
    Chip_IOCON_PinMuxSet(LPC_IOCON, IOCON_PIO0_1, (IOCON_FUNC0 | IOCON_MODE_INACT));
    
    // PIO1_0 は FUNC=1 が GPIO
    Chip_IOCON_PinMuxSet(LPC_IOCON, IOCON_PIO1_0, (IOCON_FUNC1 | IOCON_MODE_INACT));

ピンヘッダいろいろ

同じ2.54mmピッチのストレートピンヘッダにも、太さ・長さのちがうやつがあるので注意。
細いピンヘッダはブレッドボードに無理なくさせるのが利点だが、ふつうのピンソケットに挿すとスコスコになってしまう。

ふつうのピンヘッダ

  • 太さ: 0.64mm
  • 長さ: コンタクト6mm、スリーブ2.54mm、リード3mm 、全長11.54mm (概寸)

細いピンヘッダ

  • 太さ: 0.5mm
  • 長さ: コンタクト5.3mm、スリーブ2mm、リード1.8mm 、全長9.1mm (概寸)

ロープロファイルピンヘッダ (低いピンヘッダ)

  • 太さ: 0.64mm
  • 長さ(1): コンタクト3mm、スリーブ2.54mm、リード2.2mm 、全長7.7mm (概寸)
  • 長さ(2): コンタクト4.5mm、スリーブ2.54mm、リード2.5mm 、全長9.54mm (概寸)

デジトラのピン番号

ロームのデジトラ、見た目のピン配置は同じなのにパッケージによってピン番号の振り方が違うの、落とし穴すぎる。CADでライブラリを作成するときに要注意。

どうも、ペタ足のパッケージは左側が1番ピンで、ニョロ足のパッケージは右側が1番ピンの法則があるような気がする。どちらにしろ、左側がINで右側がGNDなのだけど。

f:id:licheng:20191008225556p:plain

ペタ足のパッケージ

ローム名称 一般名称 横幅[mm]
VMT3 SC-105AA 1.2
EMT3F SC-89 1.6
UMT3F SC-85 2.0

ニョロ足のパッケージ

ローム名称 一般名称 横幅[mm]
EMT3 SC-75A, SOT-416 1.6
UMT3 SC-70, SOT-323 2.0
SMT3 SC-59, SOT-346 2.9

特に、EMT3FとEMT3、UMT3FとUMT3は、フットプリントが同じような寸法でピン番号の振り方が異なるので紛らわしい。

EclipseでMbedでnRF52なローカル開発環境

(1) やりたいこと

※1 オンラインコンパイラはいざというときにサーバが落ちてるということが多々あったし、BLEのライブラリとかころころ仕様が変わって過去のソースのビルドが通らなくなるし、そのうち昔のMbed OS 2とかビルドできなくなるかもしれないおそれがあるし、いろいろ不安。

※2 Mbed StudioはMbed OS 5のみサポートし、Mbed OS 2はサポートしてないしする予定もないらしい。あと、クールすぎてオッサンにはとっつきにくい。

(2) 方針

GNU MCU Eclipseをインストールし、オンラインコンパイラから「GNU ARM Eclipse」向けにエクスポートしたプロジェクトをインポートするという方法を取ることにする。
gnu-mcu-eclipse.github.io

(3) GNU MCU Eclipseのインストール

少々面倒くさいが以下の手順でインストールする。

(3.1) Node.jsのインストール

nodejs.org

(3.2) xpm(xPack package manager)のインストール
npm install --global xpm
(3.3) xpmでいろいろインストール
xpm install --global @gnu-mcu-eclipse/arm-none-eabi-gcc
xpm install --global @gnu-mcu-eclipse/windows-build-tools
xpm install --global @gnu-mcu-eclipse/openocd
xpm install --global @gnu-mcu-eclipse/qemu
(3.4) Eclipse + CDT + GNU MCU Eclipseプラグインのインストール

自分で構築するのは面倒なので、CDTとGNU MCU Eclipseプラグインが入った状態のEclipseを下記からダウンロードし、適当な場所に展開して使用する。
github.com

Windowsで32ビット版のJavaがインストールされている場合「Java was started but returned with exit code=13」というエラーが発生する。その場合は64ビット版のJavaをインストールする。
www.java.com

(4) オンラインコンパイラからプロジェクトをインポート

Mbedのオンラインコンパイラでプロジェクトを選択して、右クリックメニューから「プログラムのエクスポート」を選択する。するとターゲットとツールチェインを選択するダイアログが出るので、ツールチェインの選択肢から「GNU ARM Eclipse」を選択して、zipファイルをダウンロードする。

Eclipseの [File] > [Import] > [General] > [Existing projects into Workspace] でzipファイルを選択し、インポートする。

(5) デバッガの設定

[Run] > [Debug Configurations] で [DGB SEGGER J-Link Debugging] を選択し、[Debugger]タブの [Device Name] に「nRF52832_xxAA」などと入力する。デバイス名については下記ページを参照。

いまさらOPアンプの入出力特性

いまどきのRail-to-Rail(フルスイング)なOPアンプならあまり気にしないことですが、昔のOPアンプを5Vや3.3Vの単電源で使うとわりと思った通りになりません。このあたり、アナログ回路やってる人には当たり前の話でしょうが、僕はいままで実測して確かめたことがありませんでした。

そこでいまさらですが手持ちのOPアンプの入出力特性を測定してみました。OPアンプでボルテージフォロワ回路を組み、出力は無負荷とし、5Vおよび3.3Vの単電源で入力電圧に対する出力電圧を測定しました。

LM6142 (Rail-to-Rail OPアンプ)

f:id:licheng:20190923194942p:plain

じつに理想的な特性です。5V単電源の場合、0V~5Vの全範囲でリニアに見えます。

手持ちのOPアンプでは他にLMC6482も類似の特性を示しました。

RC4558 (両電源OPアンプ)

f:id:licheng:20190923195000p:plain

昔から定番の両電源OPアンプ「4558」です。今回はTI製のRC4558を使いました。

奇妙な特性ですね。5V単電源の場合、リニアな特性が得られるのはせいぜい1.5V~4.4Vの範囲です。両電源OPアンプはV-付近およびV+付近で出力が飽和します。さらに4558の場合、0.7Vあたりを境にとつぜん出力が反転します。この現象については下記の記事が参考になりました。

誤解の無いように言っておきますが、べつに4558をディスってるわけではありません。使い道を間違えてはいけないというだけのことです。

手持ちのOPアンプでは他にLF412CNも類似の特性を示しました。

LM358N (単電源OPアンプ)

f:id:licheng:20190923195016p:plain

昔から定番の単電源OPアンプ「358」です。今回はSTマイクロ製のLM358Nを使いました。

5V単電源の場合、リニアな特性が得られるのはおよそ0V~3.9Vの範囲です。Rail-to-Railでない単電源OPアンプはV-付近では飽和せずリニアな特性が得られますが、V+付近では飽和します。

手持ちのOPアンプでは他にNJM2902も類似の特性を示しました。

結論

マイコン回路への/からのアナログ信号には、Rail-to-RailなOPアンプを使うのが無難でしょう。

LPC1114のA/Dコンバータ

LPC1114のA/Dコンバータでちょっとつまづいたのでメモ。
LPC1114のA/Dコンバータには以下の2つのモードがある。

(1) ソフトウェア制御モード

A/D制御レジスタ(AD0CR)のBURST=0とするとこのモードとなる。
AD0CRのSELでチャンネルを選択し、AD0CRのSTART=001で変換を開始する。

注意すべきは、AD0CRのSELで選べるチャンネルは一つだけであり、二つ以上のビットをセットしてもいちばん若いビットのチャンネルのみがA/D変換される。

/***** LPCOpenでのコード例(抜粋) *****/

// ソフトウェア制御モードに設定
Chip_ADC_SetBurstCmd(LPC_ADC, DISABLE);

// チャンネル選択
Chip_ADC_EnableChannel(LPC_ADC, ADC_CH0, ENABLE);
// 変換開始
Chip_ADC_SetStartMode(LPC_ADC, ADC_START_NOW, ADC_TRIGGERMODE_RISING);
// 変換完了待ち
while (Chip_ADC_ReadStatus(LPC_ADC, ADC_CH0, ADC_DR_DONE_STAT) != SET) {}
// 変換値取得
uint16_t data;
Chip_ADC_ReadValue(LPC_ADC, ADC_CH0, &data);
(2) ハードウェアスキャンモード

A/D制御レジスタ(AD0CR)のBURST=1とするとこのモードとなる。
ソフトウェア制御モードと異なり、AD0CRのSELで複数のチャンネルを選択できる。
以降はハードウェアが選択されたチャンネルを順次A/D変換し続けてくれる。

注意すべきは、AD0CRのSTARTは必ず000に設定しなければならない。このことは『LPC111x/LPC11C1x User manual』のAD0CRの項に明記されているが、日本語版は訳がおかしい。英語読めという話である。

/***** LPCOpenでのコード例(抜粋) *****/

// チャンネル選択
Chip_ADC_EnableChannel(LPC_ADC, ADC_CH0, ENABLE);
Chip_ADC_EnableChannel(LPC_ADC, ADC_CH1, ENABLE);
Chip_ADC_EnableChannel(LPC_ADC, ADC_CH2, ENABLE);

// ハードウェアスキャンモードに設定
Chip_ADC_SetBurstCmd(LPC_ADC, ENABLE);
// ハードウェアスキャンモードのときはSTART=000にする
Chip_ADC_SetStartMode(LPC_ADC, ADC_NO_START, ADC_TRIGGERMODE_RISING);
	
// 変換値取得
uint16_t data[3];
Chip_ADC_ReadValue(LPC_ADC, ADC_CH0, &data[0]);
Chip_ADC_ReadValue(LPC_ADC, ADC_CH1, &data[1]);
Chip_ADC_ReadValue(LPC_ADC, ADC_CH2, &data[2]);


以上のことは、すべて『LPC111x/LPC11C1x User manual』に書かれている。ググる前にちゃんとマニュアル読めという話である。

SELで複数チャンネルを選択しておいてSTART=001としたタイミングで連続変換できるようなモードがあったら便利なのだけどそんなものはないようだ。