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の書き込みのコードです。
最後のページは128バイト全部そろってなくても書き込めるみたいでした。その場合は、元々書いてあったデータがそのまま残っていました。
24LC512のシーケンシャルリード(連続読み出し)を使った画像解凍ルーチンです。最初にアドレスを贈っておけば、後は読み出すだけでアドレスが自動的に増えてくれるので、2度目以降はアドレスを送る必要がなく効率的です。
高速化するには、今のデータを受け取っている間に一つ前のデータを表示することが考えられます。
実験の様子です。
Nokia 6100液晶はピンを立てればブレッドボードでも遊べるのでいいです。
ATMega16のROM使用サイズは10544バイトで6kバイトくらい空いています。圧縮しないと167,424バイト(= 6x128x109x2)だったのが18kバイトちょいに収まりました。もう少しがんばればATMega168単体でもいけたのかもしれません。外付けROMを試せたのでよしとします。
前回までの絵のサイズは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を試せたのでよしとします。
ありがとうございます。思っていたほど、ちらつきはありませんでした。外付けROMは最高速が400kbpsのです。秋月には1Mbpsのものもあるので、そちらの方がよかったかもしれません。
SDカードだとインタフェースはSPIなので、速度を気にしないでいけそうですね。