米粒AVRでI2C通信を使ってLCD表示

公開日: 電子工作 | ,

米粒AVRでLCD表示

前の記事で紹介したI2Cライブラリを使った、LCDの表示のライブラリ的なもの

 

LCD

使っているLCDは、ストロベリーリナックスで販売されているミニI2C液晶モジュール(8x2行)[バックライト付] というもの。 同じコントローラーが使われているものなら大抵は使いまわしが効くと思います。

8x2 LCD 8x2 LCD

ブレッドボードで使う上で、ピンが沢山出ていて面倒くさいので、VDD,GND,SDA,SCLの4本にまとめています。

 

I2C接続

米粒AVRのPB0がSDA、PB1がSCLとなっています。

ストロベリーリナックスのLCDの説明書には、プルアップ抵抗は数十kΩ以上を利用するように勧められています。
数十kΩって大きすぎじゃ無いか?と思いながら、僕はとりあえず10kを使って動かしています。

米粒AVR soft-I2C 回路

 

ソース

tiny10softI2C_LCD.h

/*<br />
    tiny10softI2C_LCD.h<br />
    Software LCD Library for ATTiny10<br />
    http://s2jp.com/<br />
    <br />
    Copyright (c) 2012 Futaba. All Rights Reserved.<br />
*/<br />
<br />
#ifndef _S2_TINY10_SOFTI2C_LCD_H_<br />
#define _S2_TINY10_SOFTI2C_LCD_H_<br />
<br />
#include "tiny10softI2C.h"<br />
<br />
#define LCD_ADDR                    (0x3E)<br />
#define LCD_CONTRAST                (40)<br />
<br />
#define LCD_CONTRAST_H                (0x5c)<br />
// 5Vで動かす場合<br />
//#define LCD_CONTRAST_H            (0x58)<br />
<br />
#define LCD_CURSOR_CMD(x,y)        (0x80 | (y*0x40+x))<br />
<br />
void LCD_command(uint8_t data)<br />
{<br />
    I2C_start();<br />
    I2C_write(LCD_ADDR<<1);<br />
    I2C_write(0);<br />
    I2C_write(data);<br />
    I2C_stop();<br />
    <br />
    _delay_us(50);<br />
}<br />
<br />
void LCD_write(uint8_t data)<br />
{<br />
    I2C_start();<br />
    I2C_write(LCD_ADDR<<1);<br />
    I2C_write(0x40);<br />
    I2C_write(data);<br />
    I2C_stop();<br />
    <br />
    _delay_us(50);<br />
}<br />
<br />
inline static void LCD_init()<br />
{<br />
    I2C_init();<br />
    _delay_ms(50);<br />
    <br />
    LCD_command(0b00111000);    // ファンクション・セット<br />
    LCD_command(0b00111001);    // ファンクション・セット<br />
    LCD_command(0x14);            // カーソル移動・表示シフト<br />
    <br />
    // Contrast set<br />
    LCD_command(0x70 | (LCD_CONTRAST & 0xF));<br />
    LCD_command(LCD_CONTRAST_H | ((LCD_CONTRAST >> 4) & 0x3));<br />
<br />
    LCD_command(0b01101100);    // follower control<br />
    _delay_ms(300);<br />
<br />
    LCD_command(0b00111000);    // ファンクション・セット<br />
    LCD_command(0b00001100);    // ディスプレイON<br />
<br />
    LCD_command(0x01);            // LCD clear<br />
    _delay_ms(2);<br />
}<br />
<br />
#endif<br />

I2Cライブラリと同じく、ソースはヘッダーファイル用に作っています。
Atmel Studio 6で、tiny10softI2C_LCD.h として保存し、#inlude して利用することを想定してます。
他のコンパイラとかでは動かないかもしれません。

 

命令説明

void LCD_init();

LCDライブラリの初期化。

void LCD_command(uint8_t data);

LCDモジュールへコマンド送信。

void LCD_write(uint8_t data);

LCDモジュールへ文字書き込み。

LCD_CURSOR_CMD(x,y)

カーソル位置のコマンドを定義するマクロです。
LCD_commandと組み合わせて使います。

例)LCD_command(_LCD_CURSOR_CMD(2,1));
カーソル位置を横2:縦1の位置へ移動させます。

 

サンプル・プログラム

<br />
#define F_CPU 8000000UL<br />
<br />
#include <avr/io.h><br />
<br />
#include "tiny10softI2C.h"<br />
#include "tiny10softI2C_LCD.h"<br />
<br />
int main(void)<br />
{<br />
    CCP = 0xD8;<br />
    CLKMSR = 0x00;<br />
    CCP = 0xD8;<br />
    CLKPSR = 0b00000000;<br />
    <br />
    LCD_init();<br />
    <br />
    LCD_write('H');<br />
    LCD_write('e');<br />
    LCD_write('l');<br />
    LCD_write('l');<br />
    LCD_write('o');<br />
    <br />
    LCD_command(LCD_CURSOR_CMD(2,1));<br />
    <br />
    LCD_write('T');<br />
    LCD_write('i');<br />
    LCD_write('n');<br />
    LCD_write('y');<br />
    LCD_write('1');<br />
    LCD_write('0');<br />
<br />
    while(1)<br />
    {<br />
    }<br />
}<br />

 Hello Tiny10
このサンプルプログラムは、このように「Hello Tiny10」と表示されます。

 

関連記事

SDカード・マイクロSDカード

ArduinoでSDカード

電子工作で大量のデータを保存する方法を調べていると、 Arduinoでも比較的簡単にSDカードを

記事を読む

no image

Arduino + USBホストシールド で ADK を試す(その3)

「Arduino + USBホストシールド で ADK を試す(その1)」では、Android上のア

記事を読む

no image

オシロスコープを手に入れた

ついにオシロスコープを買っちゃいました。 と言っても、DSO QUADと言うポータブルタイプの

記事を読む

no image

S2 Resistor Color Code 公開しました。

このアプリは、抵抗のカラーコードから抵抗値を素早く見る為のAndroidアプリです。 4本帯と、5

記事を読む

Arduinoで温湿度データロガー

Arduinoで温湿度計 #2

今回は、前回作った温湿度計にRTCモジュールとSDカードアダプタを取り付けて温湿度データロガーを

記事を読む

Raspberry Pi - Ethernet

Raspberry Pi インターネット接続

Raspberry Piをインターネットに接続してみた。 有線で接続(Ethern

記事を読む

no image

USBホストケーブルとUSBケーブルの違い

USBホストケーブル(OTGケーブル)と普通のUSBケーブルの違いは、USBホストケーブルとして振る

記事を読む

no image

Android + Bluetoothドングル + PIC24F

@hrdakinori さんと言う方が、PIC24FとBluetoothドングルを使って、Andro

記事を読む

no image

米粒AVRでシリアル通信(ただし送信だけ)

米粒AVR(ATtiny10)にUART機能は搭載されていないので、シリアル通信を行う為には自前

記事を読む

no image

Android Open Accessory開発時のWiFiデバッグ

Android Open Accessory開発時のデバッグは、ADBをWiFiで接続しろと、USB

記事を読む

Comment (36件)

  1. kawana

    質問を取り下げます。LPS331APの1枚の説明書良く見たら書いて有りました。自分で理解して行かなければいけない問題と反省しております。
    ストロベリ-リナックスの8文字2行LCDは5V、3Vでも使用できるらしいのですが、3V VDDの
    場合digital contrast 調整では、リニアに変化しない事が分りました。
    センサ-がVDDが3Vで、AVR,LCD VDDが5V動作の場合、抵抗と、ダイオ-ドでI/Fするのが
    良いと思いました。
    ATTINY85、LPS331AP,LCD AQM0802A+ボタン電池(CR2032) 3Vで気圧計が出来ました。
    3.3V I2C LCD(ACM1602NI)の表示testをしたいと思います。

    1. kawana

      futabaさんのLCD Programを勉強して、
      ようやくACM1602NI-FLW-FBW-M01(i2c-LCD 16ch x 2L)に
      表示出来るように成りました。ありがとうございました。
      苦労したところは、ATMEGA168Pを8MHzで動作させていましたが、
      clockが早すぎるのではと思い1MHzにDownさせたら、一発で動きました。
      質問なのですが、i2c.hのI2C_read(uint8_t ACK)が未使用なのですが、clockをdownさせた事と
      関係有りますか?

      1. Futaba

        >kawana様
        申し訳ないですが、公開しているのは米粒AVR(tiny10)向けなので、ATmega168での動作については、ちょっと分かりません。
        ちなみにmega168はハードウェアでi2cに対応しているので、そちらを利用することをお勧めします。

        また、I2C_readはi2c機器からデータを受信する為の命令で、LCDで利用する限りはI2C_readは利用されません。
        i2c.hの詳細については米粒AVRでI2C通信(マスター)をご覧下さい。

  2. kawana

    私のi2c LCD(ACM1602I)のトラブル検討にFu tabaさんのi2c LCD programを参考にさせて
    頂ました。program は、clockの生成などsoftでやられているので、i2c の理解に大変参考に
    成りました。
    programは、Strawberry Linuxのsample programを変更して動作させる事を考えましたが
    必要変更点のみ変更では動作しませんでした。clockを1/8に落とす事で、不完全ながら表示
    出来ている事が確認出来ました。(Futabaさんのproguramでも表示出来る事を確認)、
    前の命令が完全に終了していない時に次の命令を送信した時に起こると思い、_delay_ms(1)
    を、i2c_write(addr, maddr,db);のdb送出後に入れる事で、無事表示出来ました。
    おかげさまで、i2cが少し理解出来ました。ありがとうございました。

  3. matushige

    futaba様初めまして。
    そこのkawanaという者ですが数々の電子工作系の掲示板やブログを
    荒らしまわっている非常に悪質な荒らしです。

    無視をしてもそのように意味不明の文字列をどんどん書き込んできますので
    アクセス禁止等を行い書き込ませない&書き込んできたら即削除を実施するといった
    断固たる措置をよろしくお願いいたします。

  4. kawana

    Futabaさんのi2c LCD Program 勉強の後、futabaさんの勧めでm168系でHard i2cを勉強しました。勉強と言っても
    Strawberry LinuxさんのLCD SB1602WGのSample Programをいじっていただけですが、
    wait_us(50);の位置を変更するだけで、ACM1602NI(i2c LCD)に文字表示が出来ました事の報告です。
    記載不都合が有れば、記載しないで下さい。この結果を得るに当たり、futabaさんのi2c LCD Program(i2c hardを使わずc言語で記述されているprogramを勉強する事で、i2cの理解を深める事が出来た事、改めて感謝する次第です。
    //——————————————–
    i2c_write(adr, eeadr, dat)
    {
    .
    .
      TWDR = dat;
      TWCR = _BV(TWINT) | _BV(TWEN);
      switch(wait_stat()){
        case TW_MT_DATA_ACK:
        break;
        case TW_MT_ARB_LOST:
        goto begin;
        case TW_MT_DATA_NACK:
        default:
        goto quit;
    }
        wait_us(50);// (2)*****

       rv = 1;
    quit:
       i2c_stop();
    //   wait_us(50);// (1)*****1命令毎に余裕を見て50us waitさせる。
        return rv;
    }
    まとめて言うと
    (1)をやめて、(2)とする事で、ACM1602NIにも対応出来ました。サイト汚しでしたら済みません。

    1. kawana

      Futaba さんのProgramを下記の様に変更してLCD ACM1602NIに表示出来ました。
      変更箇所は、LCD_cmd、LCD_writeに_delay_us(50); // (1) ******を入れる。
      //******************************
      void LCD_write(uint8_t data)
      {
        I2C_start();
        I2C_write(LCD_ADR<<1); // (101 0000)7 (1010 0000)8
        I2C_write(0×80); //data 0×80

        I2C_write(data);
          _delay_us(50); // (1)*****

        I2C_stop();
         //_delay_us(50);
      }
      i2cの基本を理解出来た様なのでFutabaさんの気圧Programをcopyして、動作確認して見ようと思います。
      多分、すぐに動作させる事が出来ると思います。   感謝。

  5. kawana

    tn45V(8Pin)でFutabaさんのi2c Programを勉強しました。Pinを見ると
          GND 4    5 PB0(MOSI/SDA) —SDA
          PB4 3    6 PB1(MISO/D0)
          PB3 2    7 PB2(SCK/SCL) —–SCL
    *RESET/PB5 1    8 VCC
    SDA,SCLが有るので、i2c functionは使えるのでしょうか?m168用をtn45Vに置き換えた時に該当registerが
    見つかりませんでした。
    fullのdata sheetの目次にi2cが有るかもう一度見てみます。

    1. kawana

      P108-P118に、USIとして有りました。
      Two-wire Synchronous, Three-wire Synchronousが有るが、i2cと似ているんは、どれか、
      研究(勉強)してみよう。出来るかな。?

  6. kawana

    文字列を連続送信を追加してみました。

    //— 文字列を連続送信します。—–
    void i2c_puts(unsigned char *s)
    {
       while(*s)
       {
       LCD_write(*s++);
       }
    }
    表示codeは
    i2c_puts(“1234567890ABCDEZ”);// 16digit

    1. kawana

      USI通信を行う場合、MaserとしてATTINY45、SlaveとしてATTINY45が必要なのか。
      すると、LCD表示する場合、i2c LCDを使用するのがベタ-ではないかと思った。

  7. kawana

    文章の書き方が悪いので主旨を理解出来ないと思われますので修正します。
    tn45でTWIの機能が有りますが、これを用いて、i2c LCDを表示する事を考えています。
    一見すると出来そうに見えるのですが、かなり難しいのでしょうか?の意味です。

  8. kawana

    futabaさんの、開発された、soft i2cのメリットが分かるような気がします。でも
    TWIによるi2c controlは、不可能なのでしょうか?

  9. Futaba

    >kawana様
    tiny45は触ったことが無いので良く分かりません。
    申し訳ありませんが、触ったことが無いチップやプログラム等は、質問されても答えられません。

  10. kawana

    丁寧な返信ありがとうございます。そうですね触った事が無ければ
    (検討、研究した事が無ければ)比較的詳細を語る事は出来ない
    ですね。私の場合、何でもすぐ聞いてしまう癖が有るので質問させて
    頂きました。皆さんも、いろいろ検討、実験、吟味して理解されている
    のですね。みなさんは、直ぐに理解されてしまうのかなと考えていました。
    TWIが有るのだから出来るのではと考え、自分でやってみます。
    多分、50%、50%だと思っています。丁寧な返信感謝致します。

Arduinoで温湿度データロガー
Arduinoで温湿度計 #2

今回は、前回作った温湿度計にRTCモジュールとSDカードアダプタを

Arduinoで温湿度計
Arduinoで温湿度計

秋月電子の温湿度モジュールを使って、温湿度計を作ってみました。 以前

SDカード・マイクロSDカード
ArduinoでSDカード

電子工作で大量のデータを保存する方法を調べていると、 Arduin

秋月電子 リアルタイムクロック(RTC)モジュール
秋月のリアルタイムクロック(RTC)モジュール

今回は秋月電子のI2C接続のリアルタイムクロック(RTC)モジュールを

秋月電子 キャラクタLCD
秋月の小型キャラクタLCD

今回秋月電子で売られている小型のキャラクター液晶2種を買ったので、

PAGE TOP ↑