pic-lcd

last updata : 2013/05/12

pic-lcd 【LCD T361002とPIC16F1937-I/Pを繋いでみよう】

かき焼き
2013年の牡蛎

冬の味覚ですね。でも今年は少し出来が悪い?しょっぱかったです。

こんなものが

LCD T361002

左のLCDは、秋月電子通商で昔買った物です。(多分) 2013/02/17 時点でも取り扱いがあり超簡単なピン配置図等の資料が載っています。

上記資料から下図を起してみました。 それから見ると、スタティック仕様でcom-3,seg-47の様です。

専用のICを使って周波数カウンタに使用していたようですが、そのICは入手困難な様です。 (47segのスタティック仕様って新規に設計することはないでしょうから。)

現物があるので、使わないと勿体ない(結構高い)と言うことで調べてみました。

LCD T361002 表示 LCD T361002 配置

判ったことは、よく使われているLCDのSP521Pの二つあるcomは共通(繋がっている)のに対し、 T361002は独立して三つのcomがあるという事

もしかして、3comタイプのLCDとして動くのかなと思い始めました。

なら作って確かめようと。ついでにこの前残していたI2Cも実装しちゃえと。

構 想

3com/22seg

表示器配線

右の図のように、配線を考えました。

COM0とCOM3に、SEG(セグメント)が多く配置されているので22segまでしか減らせません。 これでも、制御線は半分の25本になります。(配線数は変わらないのですが。)

LCDドライバ

LCDドライバを持つPICマイコンを探してみます。 制御数が25本もありますので、40pinでないとセグメントが足りません。 それでも、PICなら複数使える物が見つかります。

その中で、秋月電子通商で入手が可能なPIC16F1937を選んでみました。

40pinで、4com-24segまで使えます。 価格も160円(2013/02/17現在)ですのでまぁ手頃かなと。

  :

後は懸念事項としては、スタティック専用でダイナミック点灯ではコントラスト不足 (表示が薄くて見えない)状態が起きること。 電圧は多分5Vだから何とかなるけど、此れだけはどうにもならないですから。

回路図

回路図

PIC16F1937-I/P

6SEG(18pin)と11SEG(23pin)は、I2C用に外してあります。 他には、特に変わった部分は無いと思います。

LCDの動作確認用だけなら、タクトスイッチや時計用発振子の実装は不要です。

電圧はVCCにしてあります。5Vから3V程度で動作すると思います。

LCD T361002

4-1/2桁LCDです。 各単位表示ができます。 時計表示には向かないですね。(コロンが無い)

秋月で売っているLCDです。 しかも1,500円もします。(2013/02/17現在)

ピン配置は、上の図を参照してください。

LCDの駆動方法

今回は、1/3 multiplex, 1/3 bias と言う方法を取ります。

簡単に説明すると、「3つの表示素子を重ねて4つ(0Vを含め)の電圧値を取る波形でLCDを駆動する」になります。

7segLED表示器のダイナミック点灯のLCD版になります。 LEDが直流駆動に対してLCDは、交流駆動と言う点が違います。

4つの電圧値を取るという事は、

  • COMMONが V0 で SEGMENTが V3 … 点灯 ⑧
  • COMMONが V0 で SEGMENTが V2
  • COMMONが V0 で SEGMENTが V1 … 消灯 ②
  • COMMONが V0 で SEGMENTが V0
  • COMMONが V1 で SEGMENTが V3
  • COMMONが V1 で SEGMENTが V2 … 消灯 ⑤
  • COMMONが V1 で SEGMENTが V1
  • COMMONが V1 で SEGMENTが V0 … 消灯 ③
  • COMMONが V2 で SEGMENTが V3 … 消灯 ④
  • COMMONが V2 で SEGMENTが V2
  • COMMONが V2 で SEGMENTが V1 … 消灯 ⑥
  • COMMONが V2 で SEGMENTが V0
  • COMMONが V3 で SEGMENTが V3
  • COMMONが V3 で SEGMENTが V2 … 消灯 ①
  • COMMONが V3 で SEGMENTが V1
  • COMMONが V3 で SEGMENTが V0 … 点灯 ⑦

の16値を持つ事になります。 ただし全ての値を使っているわけではなく、電位差が3の時が点灯して電位差が1つのとき消灯になります。 電位差が0や2は、使用しません。

1/3 multiplex 1/3 bias LCD駆動
PIC16F1937データシートより抜粋。(丸付き数字を追加 2013/02/12修正下段の①と②が逆だったため)

表示用の波形は、複数作ることが出来ます。 PIC16F1937の1/3 multiplex, 1/3 biasでは、A,Bの2種があります。 どちらが良いかは、LCD次第だと思います。

製作上の注意点

PIC16F1937の上にT361002を直付けしました。 部品配置(高さのあるもの)に気を付けないとT361002が取り付けできません。

配線量が少し多いので、確認しながら進めるのが良いです。 後から、間違えに気付くと外して直さないといけなくなることが多々有ります。

今回は半田面側にコネクタを付けるつもりでしたので、スルーホールのユニバーサル基板を使いました。 一度ハンダ付けすると先ず取れないので念には念を入れて制作を進めています。

ソフトウェア 2013/03/01

ダウンロード HI-TECH C版

PIC16F1937 用 ファームウェア Version 0.8 (hexファイル&ソースファイル) pic-t361002_080.zip

Ver0.8は、電圧表示と温度表示を入れました。 5V~3Vを加えると先ずPICに掛かっているVDD電圧を表示します。 SW1ボタンを押すと温度表示に代わります。

使い方

pic-lcd

タクトスイッチは、左から

  • SW1 ・・・ 電圧/温度切り替え
  • SW2 ・・・ 温度補正 入/切り (温度表示時)
  • SW3 ・・・ (未使用)
  • SW4 ・・・ 温度 + (温度補正時)
  • SW5 ・・・ 温度 - (温度補正時)

です。

スイッチを押して温度補正状態に入りましたら、表示が点滅します。 +,-スイッチを押して室温に近い数値に合わせます。 約0.5℃づつ変化します。

温度補正したら室温を見るぐらいに使えます。 (0~35℃で±1℃程度)

補正は、単純に計算後の値に加減算しているだけなので多少問題がでるようです。 PICのVDD電圧が変化すると誤差がでます。 本来の一点補正方法の基準になる電圧値(0.695)に補正を加えれば、この問題はありません。 (pic-rtcで実験済み) ただ、補正プログラムが複雑になるのと、固定電圧を加えるので単純な方法を使っています。

Ver0.5 の 結果は?

LCD表示

一応上手くいっているようです。

LCD専用のドライバだけあって機能満載ですね。 色々試していますが、3.3V電圧掛けて内部電圧でLCD表示が良さそうかな。

右の写真は、電圧を表示しているように見えますが単純に表示しているだけで計測とはしていません。 (数値を替えられるようにはなっていません。)

しかも、保護用の表面シートを剥がしていないので少し汚く見えます。 もう少しブログラムが進めば剥がしたいと思っています。

Vccに+5Vは 2013/02/25(訂正)

最新のPICでも+5Vで動くのですが、内部は3.6V(以下)で動いています。 ちょっと失敗しました。

A/D変換を使ってPIC16F1937に掛かっているVcc電圧を測定しようと思ったのですが…


float CheckVdd(void)
{
    FVRCONbits.FVREN = 1;           // FVR ON
    FVRCONbits.ADFVR = 1;           // ADCFVR 1.024V
    ADCON1 = 0b11010000;            // Right: Fosc/16: AVDD
    ADCON0bits.CHS = 0b11111;       // FVR 1.024V
    ADCON0bits.ADON = 1;            // ADC ON
    NOP();
    NOP();
    ADCON0bits.GO = 1;              // ADC GO
    while (ADCON0bits.nDONE) continue;
    ADCON0bits.ADON = 0;            // ADC OFF
    FVRCONbits.FVREN = 0;           // FVR OFF
    FVRCONbits.ADFVR = 0;           // ADCFVR OFF
    return (1047.552 / ADRES);      // (1.024V*1023)/adc
}

VDD 測定用関数

Vcc 5V 表示 Vcc 3V 表示

左は+5V 右は+3VをVccに加えました。

5Vを加えたとき見事に3.6Vになっています。 内部電源を計っているのかと、前回慌ててその様に書いてしまいましたが真相は違いました。

本当の原因は、ADC ONからADC GOまでの時間(ADアクイジション)が短かった為です。 PIC12F1822を扱ったときも短くして苦労したことがありますがすっかり失念していました。

外部アナログ入力は、インピーダンスを低くすることにより短いADアクイジョン時間でADCをGOさせることが出来ます。 が内部の信号ソース(今回はFVR)は、かなりインピーダンスが高い様で長いADアクイジョン時間を必要とします。


int _GoADC13(int vref, int ch)
{
    int i, t, gie;
    long int adc = 0;
    ADCON1 = 0b11010000;                // Right: Fosc/16
    ADCON1bits.ADPREF = vref;           // VF_VDD or VF_PREF or VF_FVR
    ADCON0bits.CHS = ch;                // ADC Channel Select
    for (i=0; i<64; i++) {
        gie = INTCONbits.GIE;           // Disable Interrput
        INTCONbits.GIE = 0;
        ADCON0bits.ADON = 1;            // ADC ON
        for (t=0; t<200; t++){ NOP(); }
        ADCON0bits.GO = 1;              // ADC GO
        INTCONbits.GIE = gie;           // Restart Interrput
        while (ADCON0bits.nDONE) continue;
        ADCON0bits.ADON = 0;            // ADC OFF
        adc += ADRES;
    }
    return (int)(adc>>3);
}

float CheckVdd(void)
{
    int i, adc;
    FVRCONbits.FVREN = 1;               // FVR ON
    FVRCONbits.ADFVR = 1;               // ADCFVR 1.024V
    adc = _GoADC13(VF_VDD, AN_FVR);     // ADC Vref:VDD ch:FVR
    FVRCONbits.FVREN = 0;               // FVR OFF
    FVRCONbits.ADFVR = 0;               // ADCFVR OFF
   return (8387.584/adc);               // (1.024V*8191)/adc
}

VDD 測定用関数 (新)

Vcc 5V 表示

これで+5Vがしっかり測定できました。

今回のADC関数は、温度測定と共用するために13bit化しています。 64回測定加算して3bitシフトしているだけですが。

一応タイマ0割り込み使う予定なので、割り込み禁止をしてあります。 ADアクイジョン時間がずれると多少測定に誤差がでますので。

マイクロチップのデータシートには、+5Vで動作させるとき外部にコンデンサを付けるのを推奨していますので、 このアプリケーションでは、3.3Vで動作させるのが良いと思います。

温度測定 2013/02/25

測定の前に…

PIC12F1822でPIC内部の温度センサを扱いました。 その時は、整数(固定小数点演算)しましたが今回は実数(浮動小数点演算)でと思っていたのですが… 今回使用したHI-TECH Cの単精度(float)で演算させたら、整数演算との結果と合いません。

マイクロチップのアプリケーションマニュアルの AN1333 Use and Calibration of the Internal Temperature Indicator のEquation 3とEquation 4の定数0.00132が一桁間違って0.0132になってますね。 それ見て定数入れたようです。 それにしても落とし穴が多いですね。

温度測定


float CheckTemp(void)
{
    int i;
    float dat;
    FVRCONbits.TSEN = 1;                // Temp ON
    FVRCONbits.TSRNG = 0;               // Temp Low Range
    dat = _GoADC13(VF_VDD, AN_TEMP);    // ADC Vref:VDD ch:TEMP
    FVRCONbits.TSEN = 0;                // Temp OFF
    dat = 1.000 - (dat / 8191.0);
    dat = 0.659 - (dat*(CheckVdd()/2.0));
    dat = (dat/0.00132)-40.0;
    return (dat+78.0);
}

換算式は下記の通り

温度(℃) = ((0.659-(VDD/mode)*(1-(ADC値/(2n-1))))/0.00132)-40
  High-Range mode = 4
  Low-Range mode = 2
  nはADCのビット数

今回は、ADCを13bit化していますので213=8192になります。

温度表示

    return (dat+78.0);

ってありますが、+78.0は、補正(calibration)値です。

まだ、スイッチを使って外部から設定できる様にプログラムしていないので仮に入れています。 しかし実際より78℃も低くでてます。かなりずれているので少し心配ですけど。 (一応温度に対応して動作しています。)

次は… 2013/03/01

残りはI2C表示器化ですね。 プログラム領域も残ってるし行けるかな?

あっ別なのも作り始めたしどうなるかな?

免 責

情報は出来るだけ正確に書くつもりです。ただこの記事を見て作ると思ったときは、 個人の責任において作業を行なってください。 データの喪失や機器の損傷が有っても、一切の責任は取れません。