// 易占回路 for ATtiny2313 (AVR GCC) // (C)2007-2008 by Takumi Funada, Musashinodenpa #define F_CPU 1000000 #include #include #include #include #define Button1_Down ((PINA & 0b00000001) == 0) #define Button2_Down ((PINA & 0b00000010) == 0) #define EEPROM_Log (0x10) // 得卦を保存するEEPROMアドレス #define BLANK (255) #define LED_Delay (127) // ビットマップ unsigned char matrix[7] = {0,0,0,0,0,0,0}; unsigned char matrix_num[7] = {0,0,0,0,0,0,0}; unsigned char matrix_kou[7] = {0,0,0,0,0,0,0}; unsigned char left_prompt[2][7] = { // プロンプト(2フレーム) {0, 0, 0, 0, 20, 8, 0}, {0, 0, 0, 0, 0, 20, 8} }; const prog_uint8_t Number_Font[11][3] PROGMEM = { {31, 17, 31}, {0, 31, 0}, {29, 21, 23}, {21, 21, 31}, {7, 4, 31}, {23, 21, 29}, {31, 21, 29}, {1, 1, 31}, {31, 21, 31}, {23, 21, 31}, {0, 0, 0} // Space }; // 変換テーブル(ビットパターン→易経での順番) const prog_uint8_t Ka_Table[64] PROGMEM = { 2, 46, 7, 19, 15, 36, 46, 11, 16, 51, 40, 54, 62, 55, 32, 34, 8, 3, 29, 60, 39, 63, 48, 5, 45, 17, 47, 58, 31, 49, 28, 43, 23, 27, 4, 41, 52, 22, 18, 26, 35, 21, 64, 38, 56, 30, 50, 14, 20, 42, 59, 61, 53, 37, 57, 9, 12, 25, 6, 10, 33, 13, 44, 1 }; // ビットマップの単純コピー void cp(unsigned char a[7], unsigned char b[7]) { unsigned char i; for(i = 0; i < 7; i++) { b[i] = a[i]; } } // 2桁の数字を生成 void draw_number(unsigned char d10, unsigned char d1, unsigned char b[7]) { b[0] = pgm_read_byte(Number_Font[d10]); b[1] = pgm_read_byte(Number_Font[d10]+1); b[2] = pgm_read_byte(Number_Font[d10]+2); b[3] = 0; b[4] = pgm_read_byte(Number_Font[d1]); b[5] = pgm_read_byte(Number_Font[d1]+1); b[6] = pgm_read_byte(Number_Font[d1]+2); } // LEDをリフレッシュ void bitblt(unsigned char p[7]) { unsigned char i; for(i = 0; i < 7; i++) { PORTD = 0b01111111 & ~(1<>(5-i)) & 0b00000001)<<2); } matrix[6] = 0; // 卦の番号(1-64)を得る ka = pgm_read_byte(Ka_Table + ka); draw_number((ka/10)%10, ka%10, matrix_num); // 爻の位置のドットを反転し別のビットマップとして保存 cp(matrix, matrix_kou); matrix_kou[kou] ^= 0b00000100; } int main() { unsigned char pattern = 0, count = 0; unsigned char count_ka = 0, count_kou = 0; unsigned char ka = BLANK, kou = BLANK; DDRA = 0b00000000; // PA0-1 = buttons PORTA= 0b00000011; // PA0-1 = pull up DDRB = 0b11111111; // PB0-4 = anode1-5 (PB5-7 = NC) PORTB= 0b00000000; DDRD = 0b01111111; // PD0-6 = cathodeA-G PORTD= 0b01111111; // button1を押した状態で起動すると、前回の得卦の表示 if(Button1_Down) { ka = eeprom_read_byte((void *)EEPROM_Log); kou = eeprom_read_byte((void *)EEPROM_Log + 1); render(ka, kou); } // 乱数を得るためcount_ka、count_kouを加算しながらループ for(;;) { if(ka == BLANK && count++ > 100) { cp(left_prompt[pattern++ % 2], matrix); count = 0; } bitblt(matrix); ++count_ka; if(++count_kou == 252) count_kou = 0; // 6の剰余が偏らないように if(Button1_Down && ka == BLANK) { _delay_ms(32); while(Button1_Down) { // button upを待つ ++count_ka; ++count_kou; } ka = count_ka % 64; // 卦を生成 eeprom_write_byte((void *)EEPROM_Log, ka); render(ka, 0); } else if(Button1_Down && ka != BLANK) { while(Button1_Down) { bitblt(matrix_num); } } else if(Button2_Down && ka != BLANK) { if(kou == BLANK) { kou = count_kou % 6; // 爻を生成 eeprom_write_byte((void *)EEPROM_Log + 1, kou); render(ka, kou); } while(Button2_Down) { bitblt(matrix_kou); } } else { // ボタンは押されていなかった } } }