2013年3月11日月曜日

LaunchPad UART,UART,UART,,,,

 Texas Instruments MSP430G2553のUART機能を試しました。しかし、ほんの些細なことに気付けず、お手上げ一歩手前、結構手こずりました。
 以下に、その顛末を記します。
 
UART機能を使う場合、Tx/Rxをクロス配線
1.Software UARTの検証
 もともと、MSP430LaunchPadには、UART機能の無い、MSP430G2231が付属していてデモプログラムはPCとの間でSoftUARTによる通信を実現していました。
 そこで、MCUをUART機能を持つMSP430G2553に置き換え、Software UARTを試すことにしました。
 1)CCS Ver4で新規プロジェクトを作成、
 作成時のProject Templatesで [Grace Examples/Hello world via software UART]を選択
 2)実行(Debug)
PCのターミナルソフト(ボーレート2400)で「Hello world.」を確認
2.UART機能の検証
 まずは、送信(TX)のみのプロジェクトを作成。
 1)新規プロジェクトを作成。
 作成時のProject Templatesで[Empty MSP430 Grace Project]を選択
 2)GraceでUART機能を設定
Grece Device OverViewで[USCI  A0 UART...]を選び、UARTの端子設定、ボーレート設定を行いました。
3)実行(Debug)
software UARTと同様にPCのターミナルソフトでMSP430からの通信を待つが音沙汰なし。
4)試行錯誤
 まず、P1.1、P1.2のピンの設定に問題があると思い、GraceでGPIOの設定を先に、その後UART設定を行う。Graceでの設定と、src/csl/GPIO_init.c等のソースコードの内容に祖語があると思いジタバタ、(プロジェクトのビルドでGraceの設定内容がソースコードに反映されることに気付くのは結構経ってから)
 UARTのボーレートが正しく設定されていないと思い、Basic Clock System(BCS)の設定を1、8、12、16MHzで試す
  等々、試行錯誤を繰り返す。

3.「え! こんなことが。。。」
 試行錯誤を散々繰り返した、もう、MSP430のUART機能はデータシートだけの機能とあきらめ、BaseBoadを作成、一応、UARTの入出力Pinを用意、LCD表示を確かめた後、だめ元で、UART機能をBaseBoad上で試す。すると、PCのターミナルソフトに「Hello world.」の表示が、、「え! なんで」と言う気持ちになりました。
   
 そこで、BaseBoad上のMSP430をLaunchPadに戻して、UARTの通信を確かめると、沈黙
Stellaris-MSP430 UART
つくづくLanchPadを眺めると、P1.1(TXD)、P1,2(RXD)の表記に目が留まりました。
「うそ!TX/RX 逆じゃないか!!」
つまり、LaunchPad MSP430 デモプログラムのSoftwareUARTのTX/RXピン構成が、MSP430G2553のUARTのTX/RXピン構成と逆になっているということです。
そこで、LaunchPad上のTX/RX配線をクロスさせ、試行錯誤で作成したプログラムを試すと殆どがUARTの機能が実現されていたことを確認しました。


4.Stallaris UART
 Stallaris LM4F120 のUART機能はさほどの苦労もなく試すことが出来ました。試したプログラムは SDカードのテキストファイルを読み込み、1行ごとにUART出力、これをMSP430で受けてLCD表示するといったものです。


Memo
1.MSP430のUART 受信(RX)は1バイト毎のRX割り込みで取り込み。
初め、RX(UCA0RXIFG)割り込みフラグクリアまで受信データを取り込む形で試しました。すると、受信データの最後の1バイトのみ取り込んだ結果になりました。
そこで、いろいろ試しているうちに、受信データのバイト数分RX割り込みが発生することがわかり、割り込み毎に1バイトづつ取り込むように修正、あとは、受信データの終わりの認識方法をどうするか、、、タイマを使い周期的に受信バイト数の監視を行い、増減なしで受信完了の処理を行うようにしました。
 

2013年2月6日水曜日

LPC1114 System Oscillator を試しました。

NXP LPC1114 のUART機能検証を続けています。まず、これまでに現れた不具合は、
・LPC1114のUSRT設定 
 LPC1114側のボーレート115200で PC側ターミナルソフトで文字化けが起こる。
 LPC1114側のボーレート9600で、PC側(115200)で正常な通信を確認。
・Systick設定
 Systick割り込みインターバルが想定の1/2

 ということで、システムクロックの設定について何か問題でもあるのかとも思いました。
 もともとNXP他が提供するサンプルソースはSystem Osillator(外付けクリスタル)をクロックソースにしていて、これをIRC Oscillator にして機能検証を行っていました。

そこで、クロックソースをSystem Oscillatorに戻して、これまでの検証を繰り返しました。(手持ちの水晶発振子が8MHzだったのでそれを使用)

LPC1114各レジスタ設定値
<LPC1114 UART設定:ボーレート9600 Systick設定:480000>
    システムPLL制御レジスタ(SYSPLLCTRL)      0x25    MSEL:5 (M=6)  PSEL:4(P=4)             
   システムPLLステータスレジスタ(SYSPLLSTAT)   0x01    PLL はロック状態             
   システムオシレータ制御レジスタ(SYSOSCCTRL)   0x00    オシレータはバイパスされません。/周波数範囲1 ~ 20 MHz             
   システムPLLクロックソース選択レジスタ(SYSPLLCLKSEL) 0x01  システムオシレータを選択             
   メインクロックソース選択レジスタ(MAINCLKSEL)  0x03    システムPLL クロック出力を選択             
   システムAHBクロック分周器レジスタ(SYSAHBCLKDIV) 0x01    1 で分周             
   システムAHBクロック制御レジスタ(SYSAHBCLKCTRL) 0x1105F                 
  これらの設定でメインクロック48MHz稼働を確認しました。

   UARTクロック分周器(UARTCLKDIV)  0x01                          
   UARTライン制御レジスタ(U0LCR)  0x03   8 ビットの文字長/1 ストップビット/パリティなし/DLAB=0                       
   UART分数分周器レジスタ(U0FDR)  0x10   DIVADDVAL=0/MULVAL=1
   UARTボーレート分周器レジスタ(U0DLL)  0x00                        
   UARTボーレート分周器レジスタ(U0DLM)  0x05   DL=0x0500
  これらのUART設定では、ボーレートは2343となりそう。
        BaudRate = 48M/(16*0x0500) = 2343

   システムtick カウンタ校正レジスタ(SYSTCKCAL) 0x04   システムtick タイマ校正値0x04              
   システムタイマリロード値レジスタ(SYST_RVR)  0x752FF   RELOAD              
   システムタイマ校正値レジスタ(SYST_CALIB)  0x04    TENMS=0x04   default値
  これらのSystick設定では、Systick割り込み間隔は 20mSになりそう。
   Systick割り込み間隔 = 0x752FF/(48M*1/2 ) = 0.02 Sec.

計測内容
 ・UARTのTX信号を測定すると、ビット巾は約0.1mSであった。
、    実際のUARTのボーレートは、9600であった事が確かめられた。
     PC側のボーレート設定9600のターミナルソフトでUART通信を確認。
    (PC側ボーレート115200でもUART通信が成立してしまうことを確認、前回、LPC1114側でボーレートを9600に設定すると115200のボーレートになると考えたことは、誤り。)

 ・Systick割り込みでGPIOのHigh/Lowを出力すると、High、Lowそれぞれの巾は10mSであった。
  

その他、
  UARTでボーレートを115200にした場合やはり、PC側で文字化けを起こした。(前回と同じ)
  ボーレートは115200付近であろうと思われ、 UART分数分周器レジスタ(U0FDR)でボーレートの微調整を試しましたが、不調に終わりました。

  LPC111xのデータシートでは システムオシレータの範囲は1~25MHzでした、しかしユーザーマニュアルでは一部10MHz~25MHzの表記があります。ドキュメント内、ドキュメント間で整合性がとれていないのではと思います。

まとめ、
  サンプルコードを利用したUART設定でボーレートは正しく設定された。ただし、ユーザーマニュアルのレジストリ設定と実際のレジストリ設定で食い違いがあるように思える。
  また、Systick設定では、ユーザーマニュアルの「システムtick タイマクロックはシステムクロック1/2」という事は実際と異なると思われる。

  
 現時点でのLPC1114のアプリケーション開発はユーザーマニュアルより、NXP等から提供されるサンプルコードを優先して参考にしたほうがよさそうです。




                  

2013年2月4日月曜日

TI LaunchPad 電子温度計 その後

以前作成した、TI Stellaris LaunchPad 電子温度計の動作確認を行いました。
まず準備したものは、観賞魚用小型水槽、ヒータ、水中ポンプ。 水8リットル(5℃)を水槽にいれ、そこに電子温度計につないだヒータ(300W)、循環用に水中ポンプを設置しました。
電子温度計に40℃の温度設定をすると、ヒータのスイッチが入り、徐々に水槽の水温が上昇しました。あとは、設定温度+αでスイッチが切れるのドキドキしながら待ちました。さて水温が40℃に到達、しばらくしてヒーターのスイッチが切れました。まず第一段階クリア。
ヒータのスイッチが切れた後、水温は惰性で若干上昇後、緩やかに下降を始めました。設定温度の40℃を切ったところで再度ヒーターのスイッチが入り所定の動作確認が出来ました。
●最初の設定
測定間隔5秒(目盛5分)、温度表示域30~46℃(目盛2℃) 
温度設定:40℃、動作:ヒーター、温度調整巾1℃(40.5℃でヒータースイッチOFF、39.5℃以下でヒータースイッチON)

水温は12~13分で上昇、下降を繰り返しました。水温は39.2℃~40.8℃の範囲で変化 

●温度調整巾 0.4に変更
(40.2でヒータスイッチOFF、39.8℃以下でスイッチON)

水温は7分で上昇、下降を繰り返しました。水温は39.5℃~40.5℃の範囲で変化。

今回テストした電子温度計は、まあ、観賞魚用の温度コントローラ並みの機能、しかしヒーターのスイッチにリレーを使用、その動作保障は10万回、つまり、7分サイクルの温度調節で8カ月でこの電子温度計の寿命を迎えることになります。

2013年2月3日日曜日

LPC1114 システムクロックについて(Systick)

LPC1114FN28のシステムクロック設定の検証を続けています。
今回はSystickタイマの動作を確認することでメインクロックの動作を確認しました。

Systickタイマのサンプルコードは「lpc11xx.keil-examples-CMSIS-update.zip」にあるプロジェクト「systick」のsysticktest.cのみを利用しました。

1.Systick割り込みでGPIOのHigh/Low出力を行い。出力周波数を計測。
  1)サンプルコード systicktest.c について
    以下のコードで 10mS でSystick割り込みを実現しています。
    #define SYSTICK_DELAY  (SystemCoreClock/100)
    SysTick_Config( SYSTICK_DELAY );
  2)割り込みで呼ばれる SysTick_Handler(void)にGPIO PIO1_4のHigh/Low出力を追加。
       void SysTick_Handler(void)
       {
         int i;
         TimeTick++;
         TimeTick &= 0x7fffffff;
          i = TimeTick & 0x01;
         GPIOSetValue( 1, 4, i );
       }
  3)GPIO出力周波数測定。
    測定された周波数は40~50Hz。(自作の周波数カウンタでの結果)
    Systickの設定を 10μS にして実行 測定周波数 49700Hz
       #define SYSTICK_DELAY  (SystemCoreClock/100000)

    また、メインクロックは48MHzであった。
  こkまでの結果をみると、Systick設定、システムクロックの設定で整合性はとれているおもわれる。    。。。。?
      
 

※ユーザーマニュアル17章「システムtick タイマ」の記載「システムクロックの周波数の半分に固定されています。」 で SysTick_Config()や、SystickのRELOADに設定される値はコーディング上二分の一される必要があると思われる。

LPC1114 UART及びメインクロックの確認

トラ技付録LPC1114でUARTの機能を以下の手順で検証しました。
メインクロックの表示


1.プログラムコードの入手
 NXPからサンプルコード「lpc11xx.keil-examples-CMSIS-update.zip」を入手し、以下のプログラムコードを抽出利用しました。
 ・uarttest.c フォルダUART
 ・uart.c、core_cm0.c フォルダCommon/src 
 ・uart.h、type.h フォルダCommon/inc
2.Keil uVision4で新規プロジェクトTestUART01を作成ビルド
 ・上記のサンプルコードファイルをプロジェクトTestUART01に追加
 ・system_LPC11xx.cは、GPIOを試したプロジェクトで使用したものをプロジェクトTestUART01に追加
3.プロジェクトTestUART01をデバッグ
 1)サンプルコードそのままで実行
    ・PCのターミナルソフトでUARTの通信は確認できなかった。
 2)ボーレートを遅くして実行
    ・UARTInit();によるボーレート指定を 115200から9600に変更した。
    ・最初、1)と同様にUARTは沈黙、、、いろいろもがくうちに、たまたま、PCのターミナルソフトのボーレートを115200で試すと、本来のUARTの動作が確認出来ました。


 LPC1114のボーレートが9600、PC側のボーレート115200でUARTの送受信が確認出来ました。
初めてUARTの動作確認
後は、LPC1114側のUART設定かメインクロックの設定の問題と思い、プログラムコードを点検しました。(特にメインクロックの設定はもともとクロックソースとしてシステムクロック(外部)であったのをIRCクロックに変更したので要注意)

 4.プログラムコードsystem_LPC11xx.cの確認
   1)システムPLL 制御レジスタ(SYSPLLCTRL)設定とメインクロック(SystemCoreClock)の計算に誤りと思われるコードがある。

  
 SYSPLLCTRLの設定値は0x00000023で分周比M=4 ポスト分周比P=2となりIRCクロック12MHzではメインクロックは24MHzとなるはず、
 しかしsystem_LPC11xx.cのSystemCoreClockUpdate()で計算されるメインクロックは48MHzとなりました。
 

 計算式
   SystemCoreClock = __IRC_OSC_CLK * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1);はレジスタSYSPLLCTRLのポスト分周比Pが考慮されていない。
 次のように修正した、
   SystemCoreClock = __IRC_OSC_CLK * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1) / (0x01 << ((SYSPLLCTRL_Val & 0x060) >> 5) );

5.system_LPC11xx.c修正の検証
 ひとまずメインクロックの計算式を修正した段階でUARTの検証を行った、当然、計算されるメインクロックは2分の1の 24MHz となるので LPC側のボーレートは2倍になります。PC 側のターミナルソフトのボーレートを230400に設定しました。

その結果は、文字化けが多発、一部の英数XYZ12345がエコーバックで表示出来ている。つまり、ボーレートに若干のずれがあると言うことでしょう。

6.UARTボーレートの調整
 LPC1114とPC側のボーレート設定の不一致は、ひとまず棚上げ、LPC1114のボーレートの調整を行いました。
 ユーザマニュアルでUART 分数分周器レジスタ(U0FDR)の設定でボーレートの調整が出来ることがわかり試しました。

文字化けがなかなか解消されない。
その結果は、DIVADDVALを1に、MULVALを12にした場合 最も文字化けが少なくなるが依然、使用に耐えるレベルにない。



 現時点で、システム周りのクロックは理解したつもりだが、まだ、その扱いがしっくりこない、

2013年2月2日土曜日

LPC1114FN28 GPIO でジタバタ

 数か月遅れで、トラ技(2012年10月号)付録マイコンLPC1114を試しています。付録DVDにあったサンプルプログラム「MDK_sample」を修正して、各機能のチェックを行おうと思いました。
 

 第一歩GPIOを確かめてみました。
 これが不幸の始まり。

 
 まず、トラ技の記事の「端子配置/機能」(P60、P61)を眺め、パラレルデータインターフェース用に8ビットまたは4ビットのデータポートを確保しようと思いました。
 当然、PIO0_0~PIO0_7(ポート0)または、PIO1_0~PIO1_7(ポート1)のいずれかを使うことになります。しかし、PIO0_0、PIO0_1はRESETとISPへの切り替え用となっているので、ポート0はデータポートしては使えないと判断、またPIO1_6、PIO1_7はUART用に使われます、ポート1も使えない、、、、、、、(強引にPIO0_4~PIO0_11で8ビットのデータポートを確保するしかないのかと思いました。)

 8ビットデータインターフェースは諦め、一まず、次のように、4ビット(PIO1_0~PIO1_3)のデータポートを実現しようとしました。
1.I/O設定(MDK_sample main.c)
 1)LPC_IOCON->PIO1_1 = 0xd0;を追加するがコンパイルエラーが発生次の通り修正
    LPC_IOCON->R_PIO1_0 = 0xd1;
    LPC_IOCON->R_PIO1_1 = 0xd1;
    LPC_IOCON->R_PIO1_2= 0xd1;
    LPC_IOCON->SWDIO_PIO1_3 = 0xd1;
 2)LPC1114に書き込めど、動かず、
    LPC_IOCON->PIOx_yで設定できるGPIOは動作確認できるが、それ以外のGPIOは不能となる。

 LPC_IOCON->R_PIOx_yについて、ユーザーマニュアル 6章「I/O設定」を繰り返し読む、レジスタの説明で[R機能]が優先、しかし[R機能]の意味が解らない、、、
 LPC_IOCON->SWDIO_PIO1_3について はシリアルワイヤデバッグ(SWD)のピンが優先、したがって、SWDの機能を無効にすればPIO1_3が使えるようになると思いました。
 しかし、ユーザマニュアルにSWDを無効にする方法もレジスタの表記も無い。NXPの他のドキュメントを繰るとCRP(Code Read Protection)の機能でSWDを無効に出来そうだと、、、、、


2.CRPの設定
 1)アドレス0x000002FCに値0x12345678を書き込む。
   startup_LPC11xx.sを以下の用に修正

        ・・・・・・・・・・・・・・・・・・
                IF      :LNOT::DEF:NO_CRP
                AREA    |.ARM.__at_0x02FC|, CODE, READONLY
CRP_Key         DCD     0xFFFFFFFF
                ENDIF

CRP_Key DCD 0xFFFFFFFF を CRP_Key DCD  0x12345678 に変更
 2)FlashMagicでCRP1の設定を確認
   FlashMagic ISP/Read Security....でCRP1を確認(通常はCRP is disable)
 3)GPIO PIO1_3の出力を調べるが、不調
   依然として、High/Lowの出力が出来ない。
 4)プログラムのフラッシュの書き込み不能に。
   CRPに関するドキュメントでは、CRP1ではプログラムの書き込みは可能なはず、しかしFlashMagicでのプログラム書き込みは不能。またセクタ0の消去は不能(ドキュメント通り)
そこで全消去をしようと思ったが、FlashMagicではそのような機能は無いようです。
 5)LPC1114 一つ廃棄
   LPC1114を試して1週間、最初の石は不能に、、、

 
LPC1114について、ネットを調べまくると、多くのソースコードでLPC_IOCON->R_PIO1_0 の設定があります。LPC1114自体 PIO1_0はCRPなどの面倒な設定なしで普通に使えるはず。。。。
問題は「Keil uVision4」でしょうか?「Keil uVision4」でR機能、SWD機能を前提にする環境があるのか、もしかしてGNU GCCを使えば このGPIOの問題は解決か。。。。

3.GCCによる開発
  以前LPC2388のプロジェクトをひな形に、付録DVDのサンプルプロジェクトを参考に
  1)プログラムソース
    main.c
    cr_startup_lpc11.c (Rev.01 2011.04.17 Munetomo Maruyama)
    system_LPC11xx.c (17. November 2009 by ARM)
  2)memory.def
     ROM0000.ld(created from nxp_lpc13_c.ld (v3.1.4 (200912230917)) )をリネイム
  3)Makefile
    コンパイルオプション COMPILE_OPTS = -c  -mcpu=cortex-m0  -mthumb
    ライブラリディレクトリ LIBRARY_DIRS = -L /usr/local/arm-tools/arm-elf/lib/thumb  -L /usr/local/arm-tools/lib/gcc/arm-elf/4.6.3/thumb (GCCのインストールにより適宜に修正)
  4)動作確認
    今まで沈黙していたPIO1_0につないだLEDが点滅

よし、GCCでのプログラム開発でLPC1114の全てのGPIO入出力に目途がたったと思いました。
しかし、いままで集めたサンプルプロジェクト中から、使えそうなものを修正し、動作の検証を行ったところ、前述の「Keil uVision4」と同じGPIOの不調が起きました。その不調の原因を調べると、どうも使っていたsystem_LPC11xx.cが異なっていたことに気づきました。
 実際2つのsystem_LPC11xx.cを比較しても、GPIOの不調が起こるコーディングは見つけ出せない(現在)

 さてそうなると、前述の「Keil uVision4」が原因で起こるGPIO不調に疑問、、そこでプロジェクトのsystem_LPC11xx.cを見ると、GPIO不調のGCCプロジェクトのsystem_LPC11xx.cと同じでした。
 そこで、system_LPC11xx.cを置き換え、検証すると「Keil uVision4」のGPIOの不調は解消。


まとめ
 ●LPC1114で R機能、SWD機能の共有ピンの GPIO動作不調はsystem_LPC11xx.cによる。
※「MDK_sample」のsystem_LPC11xx.c に System AHB clock 制御レジスタ (SYSAHBCLKCTRL)の設定を追加するとGPIO は正常に。
追加コード
  #define AHBCLKCTRL_Val        0x0001FFFF
  LPC_SYSCON->SYSAHBCLKCTRL = AHBCLKCTRL_Val; ....(2013/2/3)

 
 ●GCCでのビルド(make)では、コンパイルオプション -mcpu=cortex-m0 -mthumb が必須
またリンクするライブラリ(libc.a等)は thumb配下のライブラリを指定。
(LPC2388ではARM・thumbどちらでも可、LPC1114はthumbのみ可)

 ●CRP(Code Read Protection)設定 CRP1は現時点で設定しない方がよい。



    
 

2013年1月24日木曜日

トラ技(2012-10)付録 LPC1114を試しました。

 遅ればせながら、CQ出版 トランジスタ技術 2012年10月号 付録の NXP LPC1114を試しました。

 昨年 同誌をとりあえず購入、3か月余り書棚にしまいこんだままでした。しまいこんだ割には、その付録が気になっていました。付録は他の雑誌付録と違ってLPC1114単体、「一体どうやって使うのだろう?」 4KバイトのRAM、32KバイトのフラッシュROM、記事の通り「チョコット試す」にはもったいないようなスペック。
 今日、改めて記事を眺めてみました。すると、LPC1114を試すには、USB シリアル(RS232C、UART)のIFドライバIC、電源レギュレータ―等諸々、が必要であることが分かりました。
  入手できそうなIFドライバはFT231X(ICパッケージはSSOP-20)、電源レギュレータは手持ちかあるが結構手間取ることになりそう。
 ふと、傍らのTIのLaunchPad パッケージに目が止まりました。LunchPadを使えば、「USB-UART(Rx Tx)変換が簡単に利用出来そう!」「Vddの出力もある!」「USBドライバーのインストール不要!」 早速LPC1114のプログラミングに挑戦。以下にその顛末を述べます。    
 
まず、開発環境の整備
 
1.MDK-ARMのインストール(不要)
Interface誌付属 FM3基板を試したときインストールしたKeil uVision4の機能を確かめる。
 新規プロジェクト作成で対応CPUをみると
LPC1114/201  ~ LPC1114/323 が対応していました。
そこで LPC1114/102 用にデバイスデータベースをインストールしました。
 1)付録CDで立ち上がるIE HTMLページでMDK-ARM_NXP_LPCxxxx.exeを実行
 2)Keil uVision4を再度立ち上げ新規プロジェクト作成
   Select a CPU Data Base Fileで「NXP LPC Family Device Database」が選択可能になり そこに登録されているLPC1114/102でプロジェクト作成が可能になりました。
2.MyARM_sampleのインストール
   サンプルプログラムを入手するためインストールしました。
3.Flash Magicのインストール
サンプルプログラムによる、プログラム開発の実施
  
  
  
  
4.LPC1114の周辺回路の構築
   ・電源 Vdd、Vss    必須
   ・UART Rx、Tx    必須
   ・スイッチ SW1 (PIO0_1)  SW2(Reset) 必須(ブートローダでISPを起動させるため・・・後述)
   ・LED  LED1(PIO0_7) LED2(PIO1_5)  適宜
5.サンプルプログラムMDK-sampleをビルド/プログラム書き込み/実行
 

メモ
●Flash Magicでのプログラム書き込み。
  FlashMagic側) Baud Rateを115200に指定 InterfaceをNone(ISP)に
  PC側) デバイスマネージャでCOMポート ボーレートを1152000 に設定
●書き込み失敗時
  SW1(PIO0_1) SW2(RESET)同時 Push後 再度書き込む。
   (CPUリセット時 PIO0_1がLowの場合 ISPが起動、UARTによるプログラムの書き込みが可能になります。)

●トラ技2012-10号 P62 の図1の回路図でRXD/TXDの配線間違いがあるので注意
(Flash Magicで、てこずった原因)

2013年1月15日火曜日

NHD-C12864でチャート表示を試しました。

  TI Stellaris LaunchPadで作成した電子温度計の表示をSUNLIKE社SG12864aの他、Newhaven Display NHD-C12864でも試しました。
 SG12864のデータインターフェースはパラレル、一方NHD-C12864はシリアル、当初、SG12864の方が、表示能力に勝ると思われたのですが、最小限の表示プログラム改造でNHD-C12864を稼働させると、遜色ない結果になりました。逆に、SG12864で起こる表示の乱れがNHD-C12864で起こらない満足いく結果になりました。
 
 
NHD-C12864による温度チャート表示

SG12864による温度チャート表示
SG12864では頻繁に表示の乱れが起こり、各信号のタイミング調整でなんとか、対応しようとしています。











  NHD-C12864は、マイコンとのIFは5本(GPIO4本 /RES1本)、さらに、LCDドライバICが1つで、これがSG12864に較べ扱いやすいLCDとなっていると思われます。



 





グラフィックLCD NHD-C12864A1Zを試しました。

Newhaven Display International社 グラフィックLCD NHD-C12864A1Z-FSB-FBWを試しました。
 これまではTI Stellaris LaunchPadでSUNLIKE社グラフィックLED SG12864 を使用していました。SG12864ではGPIOピンを13本占有するので、開発アプリケーションが自ずと制限されます。
 そこで、データインターフェースがシリアルのLCDを探したところ、DigiKeyでNHD-C12864A1Zを見つけ、早速に入手しました。

NHD-C12864A1Zは、
 ・マイコンとのインターフェースはGPIOピン4本でOK
 ・0.1インチ(2.54mm)ピッチの12本のピン (6×2)
 ・3.3V駆動 (No.9ピン H+ ヒータ用の12Vの給電があるが、いまいち不明?)


最初、シリアルのデータインターフェースはSPI(SSI)やI2Cを使うと予想していたのですが、ドキュメントに記載された、初期化コードをみると、単純にGPIOのHi/Low出力でSCLとSI(SDA、Tx)を実現しているようで以下のコーディングを行いました。

  * シリアルによるデータ出力 1バイトの出力データ siout を シフトさせながら1ビットづつ出力

     for(i=0;i<8;i++)
     {
      lcd_SCL_low();          //SCL:Low
      if(siout & _10000000B)
      {
        GPIOPinWrite(LCD_PORT_BASE, LCD_PIN_SI, LCD_PIN_SI);  //SI:High
      }
      else
      {
        GPIOPinWrite(LCD_PORT_BASE, LCD_PIN_SI, 0);      //SI:Low
      }
      lcd_SCL_high();        //SCL:High
      siout = siout <<1;       //1ビットのシフト
     }


*感想 
  ・表示内容により、濃淡のムラがある。
  ・比較的簡単に表示が実現。
   (SG12864では、各信号の出力タイミングの調整が必要でしたが、今回は簡単に表示が確認出来ました。)

2013年1月12日土曜日

.Net (VC++) Chartクラスを使ってグラフを表示


先日作成した電子温度計(Stellaris LM4F120)とPCとの連携を行いたいと思い、測定データをPCに取り込み、データのグラフ表示を試しました。
以前VC++でグラフ表示を行った時 System::Drawing::Graphics等の Drawing配下のクラスを利用しましたが、今回は、Chartクラスを使ったグラフ表示を試しました。
 
===================================================================
1.概要
     電子温度計 [UART] ==(USB)== [COMポート]  PC
                      測定温度

  デザイン
   VC++でWindowsフォームアプリケーションでプロジェクトを作成する。
   Form1にChart、SerialPort オブジェクトを追加 設定する。

  初期処理
   Chart/Seriseに1024個のDataPointを値0で登録する。
  メイン処理  
   シリアルポート受信イベントで電子温度計が出力する温度データを取り込む。
   取り込んだ温度データを順次 Chart/Serise/DataPointオブジェクトに設定する。

===================================================================
2.VC++プロジェクト作成<<非時系列チャート>>
 1)Chart設定
   Form1にChartオブジェクト chart1 を作成
     プロパティ設定 Seriseコレクション(ChartType:Line)
 2)SerialPort設定
   Form1にSerialPortオブジェクト serialPort1を作成
     プロパティ設定 BaudRate と PortNameを設定
   
   
 3)コーディング コンストラクタ Form1(void)
   ①Charting/Seriesオブジェクト series1tをローカル宣言
     System::Windows::Forms::DataVisualization::Charting::Series^  series1t;
   ②chart1のSeries1を①で宣言したseries1tに読みだす。
     series1t = this->chart1->Series["Series1"];
   ③Charting/DataPointオブジェクトを初期値で作成。
     
     System::Windows:・・・:Charting::DataPoint^  tmppoint
      = (gcnew System::Windows::・・・::Charting::DataPoint(i,0));
   
   ④Charting/DataPointオブジェクトを①で宣言したseries1tに登録する。
     series1t->Points->Add(tmppoint);
   *③④を繰り返し1024のDataPointオブジェクトをseries1t(chart1/Series1)に登録する。

   ⑤シリアルポートをOpenする。
     this->serialPort1->Open();

 4)コーディング シリアルポート受信イベント処理 (serialPort1_DataReceived)
   ①Charting/Series、Pointsオブジェクト series1t、tmppoint をローカル宣言
   ②DateTime型で現在時刻を取得する。
     DateTime timesp =   System::DateTime::Now;
   ③シリアルポート受信データを取り込み、温度データを抽出する。
     strreceive = this->serialPort1->ReadLine();   [[strreceive:String]]
     strvalue = strreceive->Substring(7,6);  [[strvalue:String 温度データ位置:7]]
   ④取得した温度データでSeries1のDataPointを更新する。
     (インデックス指定で、一旦Series1のDataPointを削除して、取得した温度データでDataPointオブジェクトを作成し登録し直す。)
     series1t = this->chart1->Series["Series1"];
     tmppoint = series1t->Points[IntPointIndex];    [[IntPointIndex:DataPointインデックス]]
     series1t->Points->Remove(tmppoint);
     System::Windows:・・・:Charting::DataPoint^  tmppoint1
      = (gcnew System::Windows::Forms::DataVisualization::Charting::DataPoint(IntPointIndex,System::Convert::ToDouble(strvalue)));
     series1t->Points->Insert(IntPointIndex,tmppoint1);

  5)エラー対処
    このコーディングでプログラムを実行すると、不定期のタイミングで「InvalidOperationException ”コレクションが変更されました。実行されない可能性があります。” エラー」が発生します。
    ①原因の予想
      チャート表示処理中にチャート情報の更新が重なったため起きたエラーと思われます。
    ②対処
      Serise1/DataPointオブジェクトの削除、挿入処理はChartを一旦非表示にして実行する。
         this->chart1->Visible = false;       


===================================================================
3.VC++プロジェクト作成 <<時系列チャート>>

 1)Chart設定
     プロパティ設定 Seriseコレクション(ChartType:Line  XValueType:Time
 2)SerialPort設定
   
   
 3)コーディング コンストラクタ Form1(void)
   ①シリアルポートをOpenする。

 4)コーディング シリアルポート受信イベント処理 (serialPort1_DataReceived)
   ①Charting/Seriesオブジェクト series1tをローカル宣言
   ②DateTime型で現在時刻を取得する。
   ③シリアルポート受信データを取り込み、温度データを抽出する。
   ④取得した温度データでDataPointを作成し Series1に登録する。
         System::Windows:・・・:Charting::DataPoint^  tmppoint2
          = (gcnew System:・・・:Charting::DataPoint(timesp.ToOADate(),System::Convert::ToDouble(strvalue)));
      series1t->Points->Add(tmppoint2);
   ⑤Series1に登録されたDataPointオブジェクトが1024を超えた場合。先頭のDataPointオブジェクトを削除する。
      series1t->Points->RemoveAt(0);

===================================================================
※メモ
 ●DataPointの設定
 DateTime値をDataPointのX値に設定する場合 ToOADate()メソッドを使用する。
●チャートデータの更新処理の工夫
 データDataPointコレクションの更新時 Chatオブジェクトは非表示にする。 (前述)

※気になる点
●MicroSoftのmsdnオンラインドキュメントの不備
ChartクラスのSystem名前空間からの継承階層はSystem::Windows::Forms::DataVisualization::Charting::Chartですが、オンライドキュメントでSystem名前空間から繰るとSystem::Windows::Forms名前空間 止まりでした。また、DataVisualization名前空間配下の Series等のクラスではドキュメントの繰り方で、内容の無いページが現れます。
 とにかく、Chartクラスを使うのには情報が少ない。