ATtiny1604でデジットの32x16LEDマトリックスに自作8x8フォントを表示してみた
大阪デジットの安価な32x16LEDマトリックスSP5004をATtiny1604で動かしています。・デジットの32x16ドットマトリックスLEDをATtiny1604で動かしてみた・32x16LEDマトリックスの表示をATtiny1604 のタイマー割り込みで試してみた今回LEDマトリックス用に8x8ドットのAsciiフォントを作ってみたので表示させてみました。・LEDドットマトリックスで使うビットマップフォントを画像データから作ってみた表示チェックプログラムを入れて動かしてみました。フォントデータはプログラム内に埋め込んでいます。動画も撮ってみました。映りは悪いですが,,ちらつかずに動いてくれていますV(^^)。せっかく動いたので,フォントデータの保存もかねてプログラムをメモしておきます。・ ダイナミック駆動のLEDなのでタイマー割り込みも使ってみていますが,特にこだわることは無いと思います。・フォントデータも含めても2Kバイトぐらいのプログラムなのでメモリが4KバイトのATtiny404でも表示器として使えそうです。・動画のスタート画面は急造りの0/1データです(^^;;;;;;// *** DIGIT 32x16LCD, ATtiny1604 (Arduino IDE) ***#define s1 A1 // COM(ROW 0-15)#define s2 A2 // A(Column 0-15) #define s3 A3 // B(Column 16-31)#define clk A4 // CLOCK(0->1)#define lat A5 // LATCH(0->1)#define _en A6 // _ENABLE(0:on)/** Ascii 0x20 -> 0x7F **/const byte font88[96][8]={{ 0, 0, 0, 0, 0, 0, 0, 0 }, // space (0x20) { 0, 32, 32, 32, 32, 32, 0, 32 }, // ! (0x21) { 0, 144, 72, 0, 0, 0, 0, 0 }, // " (0x22) { 0, 80, 248, 80, 80, 248, 80, 0 }, // # (0x23) { 0, 32, 112, 168, 48, 96, 168, 112 }, // $ (0x24) { 0, 132, 74, 42, 84, 168, 164, 66 }, // % (0x25) { 0, 32, 80, 48, 176, 104, 72, 176 }, // & (0x26) { 0, 48, 48, 32, 16, 0, 0, 0 }, // ' (0x27) { 0, 32, 16, 16, 16, 16, 16, 32 }, // ( (0x28) { 0, 16, 32, 32, 32, 32, 32, 16 }, // ) (0x29) { 0, 0, 0, 168, 112, 112, 168, 0 }, // * (0x2A) { 0, 0, 0, 32, 32, 248, 32, 32 }, // + (0x2B) { 0, 0, 0, 0, 48, 48, 32, 16 }, // , (0x2C) { 0, 0, 0, 0, 0, 120, 0, 0 }, // - (0x2D) { 0, 0, 0, 0, 0, 0, 48, 48 }, // . (0x2E) { 0, 0, 64, 32, 16, 8, 4, 2 }, // / (0x2F) { 0, 96, 144, 144, 144, 144, 144, 96 }, // 0 (0x30) { 0, 32, 48, 32, 32, 32, 32, 32 }, // 1 (0x31) { 0, 112, 136, 136, 96, 48, 8, 248 }, // 2 (0x32) { 0, 112, 136, 128, 112, 128, 136, 112 }, // 3 (0x33) { 0, 96, 80, 80, 72, 248, 64, 64 }, // 4 (0x34) { 0, 248, 8, 120, 136, 128, 136, 112 }, // 5 (0x35) { 0, 112, 136, 8, 120, 136, 136, 112 }, // 6 (0x36) { 0, 248, 128, 64, 32, 16, 16, 16 }, // 7 (0x37) { 0, 112, 136, 136, 112, 136, 136, 112 }, // 8 (0x38) { 0, 112, 136, 136, 240, 128, 136, 112 }, // 9 (0x39) { 0, 0, 48, 48, 0, 48, 48, 0 }, // : (0x3A) { 0, 0, 48, 48, 0, 48, 32, 16 }, // ; (0x3B) { 0, 0, 32, 16, 8, 16, 32, 0 }, // < (0x3C) { 0, 0, 0, 56, 0, 56, 0, 0 }, // = (0x3D) { 0, 0, 16, 32, 64, 32, 16, 0 }, // > (0x3E) { 0, 48, 72, 64, 32, 16, 0, 16 }, // ? (0x3F) { 0, 96, 144, 232, 168, 232, 16, 224 }, // @ (0x40) { 0, 32, 80, 136, 136, 248, 136, 136 }, // A (0x41) { 0, 120, 136, 136, 120, 136, 136, 120 }, // B (0x42) { 0, 112, 136, 8, 8, 8, 136, 112 }, // C (0x43) { 0, 120, 136, 136, 136, 136, 136, 120 }, // D (0x44) { 0, 248, 8, 8, 120, 8, 8, 248 }, // E (0x45) { 0, 248, 8, 8, 120, 8, 8, 8 }, // F (0x46) { 0, 112, 136, 8, 232, 136, 200, 176 }, // G (0x47) { 0, 136, 136, 136, 248, 136, 136, 136 }, // H (0x48) { 0, 112, 32, 32, 32, 32, 32, 112 }, // I (0x49) { 0, 224, 64, 64, 64, 72, 72, 48 }, // J (0x4A) { 0, 136, 72, 40, 24, 24, 40, 200 }, // K (0x4B) { 0, 8, 8, 8, 8, 8, 8, 248 }, // L (0x4C) { 0, 136, 216, 248, 168, 136, 136, 136 }, // M (0x4D) { 0, 136, 152, 152, 168, 200, 200, 136 }, // N (0x4E) { 0, 112, 136, 136, 136, 136, 136, 112 }, // O (0x4F) { 0, 120, 136, 136, 120, 8, 8, 8 }, // P (0x50) { 0, 112, 136, 136, 136, 168, 72, 176 }, // Q (0x51) { 0, 120, 136, 136, 120, 72, 200, 136 }, // R (0x52) { 0, 112, 136, 8, 112, 128, 136, 112 }, // S (0x53) { 0, 248, 32, 32, 32, 32, 32, 32 }, // T (0x54) { 0, 136, 136, 136, 136, 136, 136, 112 }, // U (0x55) { 0, 136, 136, 136, 80, 80, 32, 32 }, // V (0x56) { 0, 136, 136, 136, 168, 168, 80, 80 }, // W (0x57) { 0, 136, 136, 80, 32, 80, 136, 136 }, // X (0x58) { 0, 136, 136, 80, 80, 32, 32, 32 }, // Y (0x59) { 0, 248, 128, 64, 32, 16, 8, 248 }, // Z (0x5A) { 0, 48, 16, 16, 16, 16, 16, 48 }, // [ (0x5B) { 0, 136, 80, 32, 112, 32, 112, 32 }, // \ (0x5C) { 0, 48, 32, 32, 32, 32, 32, 48 }, // ] (0x5D) { 0, 32, 80, 136, 0, 0, 0, 0 }, // ^ (0x5E) { 0, 0, 0, 0, 0, 0, 0, 112 }, // _ (0x5F) { 0, 16, 32, 64, 0, 0, 0, 0 }, // ` (0x60) { 0, 0, 0, 48, 72, 112, 72, 176 }, // a (0x61) { 0, 0, 0, 16, 16, 112, 144, 112 }, // b (0x62) { 0, 0, 0, 48, 72, 8, 72, 48 }, // c (0x63) { 0, 0, 0, 64, 64, 112, 72, 112 }, // d (0x64) { 0, 0, 0, 48, 72, 120, 8, 48 }, // e (0x65) { 0, 0, 0, 64, 32, 112, 32, 16 }, // f (0x66) { 0, 0, 0, 48, 72, 112, 64, 48 }, // g (0x67) { 0, 0, 0, 16, 16, 112, 144, 144 }, // h (0x68) { 0, 0, 0, 32, 0, 32, 32, 32 }, // i (0x69) { 0, 0, 0, 32, 0, 32, 40, 16 }, // j (0x6A) { 0, 0, 0, 16, 80, 48, 48, 80 }, // k (0x6B) { 0, 0, 0, 32, 32, 32, 32, 32 }, // l (0x6C) { 0, 0, 0, 88, 168, 168, 168, 136 }, // m (0x6D) { 0, 0, 0, 112, 144, 144, 144, 144 }, // n (0x6E) { 0, 0, 0, 96, 144, 144, 144, 96 }, // o (0x6F) { 0, 0, 0, 112, 144, 112, 16, 16 }, // p (0x70) { 0, 0, 0, 48, 72, 112, 64, 192 }, // q (0x71) { 0, 0, 0, 32, 160, 96, 32, 32 }, // r (0x72) { 0, 0, 0, 112, 8, 48, 64, 56 }, // s (0x73) { 0, 0, 0, 32, 112, 32, 160, 64 }, // t (0x74) { 0, 0, 0, 144, 144, 144, 144, 96 }, // u (0x75) { 0, 0, 0, 136, 136, 80, 80, 32 }, // v (0x76) { 0, 0, 0, 136, 168, 168, 216, 80 }, // w (0x77) { 0, 0, 0, 136, 80, 32, 80, 136 }, // x (0x78) { 0, 0, 0, 136, 80, 32, 16, 8 }, // y (0x79) { 0, 0, 0, 248, 128, 96, 16, 248 }, // z (0x7A) { 0, 32, 16, 16, 24, 16, 16, 32 }, // { (0x7B) { 0, 32, 32, 32, 32, 32, 32, 32 }, // | (0x7C) { 0, 32, 64, 64, 192, 64, 64, 32 }, // } (0x7D) { 0, 0, 160, 80, 0, 0, 0, 0 }, // ~ (0x7E) { 0, 0, 0, 0, 0, 0, 0, 0 }} ;// (0x7F)unsigned long pBuf[16]; // Display_buffer (ROW:16, COLUMN 32bit)unsigned long Opening[16]={ // Opening screen 0b00000000000000000000000000000000, 0b01111110001110001110001101111110, 0b01100000110001101111001100011000, 0b01111110110001101101001100011000, 0b01100000110001101100101100011000, 0b01100000110001101100101100011000, 0b01100000110001101100011100011000, 0b01100000001110001100011100011000, 0b00000000000000000000000000000000, 0b00001111000000000000000011110000, 0b00010000100000000000000100001000, 0b00010000100000101000000100001000, 0b00001111000000010000000011110000, 0b00010000100000101000000100001000, 0b00010000100000000000000100001000, 0b00001111000000000000000011110000 }; void setup() { pinMode(s1,OUTPUT); pinMode(s2,OUTPUT); pinMode(s3,OUTPUT); pinMode(clk,OUTPUT); pinMode(lat,OUTPUT); pinMode(_en,OUTPUT); pinMode(A7,OUTPUT); digitalWrite(s1,LOW); digitalWrite(s2,LOW); digitalWrite(s3,LOW); digitalWrite(clk,LOW); digitalWrite(lat,LOW); digitalWrite(_en,LOW); TCB0.CCMP = 500; // TOP値の設定 TCB0.CTRLB = (TCB0_CTRLB & 0b10101000) + 0b00000000; //タイマーのGPIO出力ON、クロックソースを設定 TCB0.CTRLA = (TCB0_CTRLA & 0b11111000) + 0b00000101; //カウント周期を設定してカウントスタート TCB0.INTCTRL = 1; //割り込み許可} // setup endvoid loop() { for (byte i=0; i<16; i++){ // Openibg screen -> buffer for (byte j=0; j <32; j++){ bitWrite(pBuf[i], j,bitRead(Opening[i], 31-j)); } } delay(1500); for (byte i=0; i< 32; i++){ // shift left screen for (byte j=0; j<16; j++){ pBuf[j]=pBuf[j] >> 1; } delay(50); } for (byte i=0; i < 12; i++){ // 8 char x 12 page Clear_buffer(); for (byte j=0; j<4; j++){ // create 1 page for (byte k=0; k<8; k++){ // 16 line unsigned long f8=font88[8*i+j][k]; // upper 8 line f8=f8 << (8*j); pBuf[k]=pBuf[k] | f8; f8=font88[8*i+j+4][k]; // lower 8 line f8=f8 << (8*j); pBuf[k+8]=pBuf[k+8] | f8; } } for (byte i=0; i<16; i++){ pBuf[i]=pBuf[i] >> 1; } delay(800); } } // loop endvoid Clear_buffer(){ for (byte i=0; i<16; i++){ pBuf[i]=0; }}ISR(TCB0_INT_vect) { for (byte i=0;i<16;i++){ unsigned int Row=1 << i ; // Set Row unsigned int columnLow=pBuf[i] & 0x0000FFFF; // Set Low_16bit unsigned int columnHigh=pBuf[i] >> 16; // Set High_16bit for (byte j=16; j >0; j--){ // send dots of one line digitalWriteFast(s1,bitRead(Row,16-j)); digitalWriteFast(s2,bitRead(columnLow,j-1)); digitalWriteFast(s3,bitRead(columnHigh,j-1)); digitalWriteFast(clk,HIGH); // Clock 0->1->0 digitalWriteFast(clk,LOW); } // next dots digitalWriteFast(_en,HIGH); // Enable off, store one line digitalWriteFast(lat,HIGH); // Latch 0->1->0 digitalWriteFast(lat,LOW); digitalWriteFast(_en,LOW); // Enable on for (int k=0; k<20; k++){ digitalWrite(_en,LOW); // Waiting (Enable on) } digitalWrite(_en,HIGH); // Enable off } TCB0.INTFLAGS = 1; //割り込みフラグのクリア} // ISR end