Sim's blog

電子工作はじめてみました

ネギミクを大きくしてみました。

2008-10-29 23:26:54 | AVR
ATMega88でもネギミクの続きです。

前回までの絵のサイズは56x48でした。今回は128x109にしてみました。

56x48のはちゅね


128x109のはちゅね


前回と同じ方法で圧縮してみましたが、サイズは18kバイトくらいになってATMega168の16kには入りませんでした。そこで秘密兵器の登場です。秋月で売っている「シリアルI2C EEPROM 24LC512」(通販番号I-02524)を使いました。200円なのに64kバイト(8x64kバイト=512kビット)もデータをいれておけます。動画の部分(10kバイト)は高速アクセスしたいのでATMega168のROMに、最初の静止画の部分(8kバイト)だけを24LC512に格納しました。

24LC512です

8pinのDIPパッケージです。ピン機能です。

1 A0 A2~A0でI2Cのアドレスを決める
2 A1
3 A2
4 GND
5 SDA I2Cデータポート (2.2kΩでプルアップ)
6 SCL I2Cクロックポート、400kbps (2.2kΩでプルアップ)
7 WP ライトプロテクト(GND接続で書き込み可)
8 Vcc 2.5~5.5V

A2~A0でアドレスを変えれるので同じバス上に8個まで24LC512を接続することができます。書き込みはバイト単位とページ単位(128バイト)ができ、読み出しはランダム読み出しとシーケンシャル読み出しができます。ページ書き込みのときは、一旦バッファで受信してから書き込むので、データを送り終わったあと、ビジーの間待たないと次のコマンドを送ることができません。今回はまったところです。I2Cのstartを送るとNAKが返ってきて最初のブロックしか書き込めませんでした。startを送ってACKが返ってくるまで何度もstartを送ってビジーでなくなるのをポーリングして待ちます。

24LC512の書き込みのコードです。
// ATMega168のROMの内容を24LC512に書き込む
void flash_writep(uint16_t addr, const uint8_t *data, uint16_t size)
{
    uint8_t i, s;

    while(size >= 128){
        // 1ブロック書き込む
        i2c_start(LC512 | TW_WRITE);
        i2c_write(addr >> 8); // アドレス上位	
        i2c_write(addr);        // アドレス下位
        for(i = 0; i < 128; i++) i2c_write(pgm_read_byte(data++));
        i2c_stop();

        // ビジーウェイト
        while((s = i2c_startx(LC512 | TW_WRITE)) == TW_MT_SLA_NACK) ;
        if(s != TW_MT_SLA_ACK) i2c_error();
        i2c_stop();
        addr += 128;
        size -= 128;
    }

    // 最後のページを書き込む
    i2c_start(LC512 | TW_WRITE);
    i2c_write(addr >> 8); // アドレス上位
    i2c_write(addr);        // アドレス下位
    for(i = 0; i < size; i++) i2c_write(pgm_read_byte(data++));
//  for(i = size; i < 128; i++) i2c_write(0xff);
    i2c_stop();

    // ビジーウェイト
    while((s = i2c_startx(LC512 | TW_WRITE)) == TW_MT_SLA_NACK) ;
    if(s != TW_MT_SLA_ACK) i2c_error();
    i2c_stop();
}

最後のページは128バイト全部そろってなくても書き込めるみたいでした。その場合は、元々書いてあったデータがそのまま残っていました。

24LC512のシーケンシャルリード(連続読み出し)を使った画像解凍ルーチンです。最初にアドレスを贈っておけば、後は読み出すだけでアドレスが自動的に増えてくれるので、2度目以降はアドレスを送る必要がなく効率的です。
// 24LC512から読み出してNokia 6100液晶に解凍&表示する
void flash_unpack(uint16_t addr, uint16_t size)
{
    uint8_t c0, c1, n;

    i2c_start(LC512 | TW_WRITE);
    i2c_write(addr >> 8); // アドレス上位
    i2c_write(addr);        // アドレス下位
    i2c_start(LC512 | TW_READ);
    lcd_cmd(RAMWR);
    do {
        c0 = i2c_read_ack();
        n = c0 >> 4;
        c1 = i2c_read_ack();
        do {
            lcd_data(c0);
            lcd_data(c1);
        } while(n--);
    } while(--size);
    i2c_read_nak();     // NAKを送るためにダミーで読む
    i2c_stop();
}

高速化するには、今のデータを受け取っている間に一つ前のデータを表示することが考えられます。

実験の様子です。

Nokia 6100液晶はピンを立てればブレッドボードでも遊べるのでいいです。

ATMega16のROM使用サイズは10544バイトで6kバイトくらい空いています。圧縮しないと167,424バイト(= 6x128x109x2)だったのが18kバイトちょいに収まりました。もう少しがんばればATMega168単体でもいけたのかもしれません。外付けROMを試せたのでよしとします。

最新の画像もっと見る

2 コメント

コメント日が  古い順  |   新しい順
びっくりさいず (すん)
2008-10-30 16:39:35
画面いっぱいにネギ振りができるようになって、おめでとうございます。これだけ大きければ見ごたえあります。私も早くSDカードつけてアニメやってみたいと思います。
re:びっくりさいず (Sim)
2008-10-30 23:08:16
こんにちは、すんさん
ありがとうございます。思っていたほど、ちらつきはありませんでした。外付けROMは最高速が400kbpsのです。秋月には1Mbpsのものもあるので、そちらの方がよかったかもしれません。
SDカードだとインタフェースはSPIなので、速度を気にしないでいけそうですね。

コメントを投稿