/* FUSES: Low Fuse: 0x62 Default 0xC0 External Oscillator, BOD (write lfuse 0 0xC0) 0xF7 Full Swing Crystal Oscillator (write lfuse 0 0xF7) 0xFF Low Power Crystal Oscillator (untested) High Fuse 0xDF Default 0xDC BOD enabled (4.3V) 0xCF watchdog enabled 0xCC BOD enabled (4.3V) and watchdog enabled Extended Fuse 0x01 Default avrdude -c stk500 -P /dev/ttyS0 -p atmega88 -U flash:w:bha_l2_frontleds.srec avrdude -c usbasp -p atmega168p -U flash:w:bha_l2_frontleds.srec avrdude -c stk500 -P /dev/ttyS0 -p atmega88 -t avrdude -c usbasp -p atmega168p -t dump lfuse 0 1 write lfuse 0 PINS: AVR Conn Functions Usage 1 P10-3 PD3 OC2B 2 P4-13 PD4 3 GND 4 VCC 5 GND 6 VCC 7 PB6 XTAL1 crystal 8 PB7 XTAL2 crystal 9 P8-3 PD5 OC0B 10 P6-3 PD6 OC0A 11 P4-14 PD7 AIN1 12 P2-6 PB0 ICP1 bell switch 13 P2-4 PB1 OC1A speaker 14 P2-5 PB2 OC1B 15 P1-4 PB3 MOSI/OC2A ISP 16 P1-1 PB4 MISO ISP 17 P1-3 PB5 SCK ISP 18 AVCC 19 P4-4 ADC6 20 P4-5 AREF 21 GND 22 P4-6 ADC7 23 P4-7 PC0 ADC0 24 P4-8 PC1 ADC1 25 P4-9 PC2 ADC2 26 P4-10 PC3 ADC3 27 P4-11 PC4 ADC4 28 P4-12 PC5 ADC5 29 P1-5 PC6 /RESET ISP 30 PD0 RXD RS485 RX 31 PD1 TXD RS485 TX 32 PD2 RS485 driver enable https://en.wikipedia.org/wiki/Piano_key_frequencies notes = ( "C", "CIS", "D", "DIS", "E", "F", "FIS", "G", "GIS", "A", "AIS", "H" ) nlist = [] for i in range( 28, 120 ): f = 2**((i-49)/12.) * 440 icp = int(18.432e6 / 2 / f - 0.5) n = notes[(i-28)%12] o = (i+8)/12 if icp < 65536 and f < 15e3: nlist.append( ( i, f, icp, n, o ) ) for i, f, icp, n, o in nlist: print "\t%s%d," % ( n, o ) for i, f, icp, n, o in nlist: print "\t%d, // %s%d %gHz" % ( icp, n, o, f ) */ #include #include #include enum { PAUSE = 0, D3, DIS3, E3, F3, FIS3, G3, GIS3, A3, AIS3, H3, C4, CIS4, D4, DIS4, E4, F4, FIS4, G4, GIS4, A4, AIS4, H4, C5, CIS5, D5, DIS5, E5, F5, FIS5, G5, GIS5, A5, AIS5, H5, C6, CIS6, D6, DIS6, E6, F6, FIS6, G6, GIS6, A6, AIS6, H6, C7, CIS7, D7, DIS7, E7, F7, FIS7, G7, GIS7, A7, AIS7, H7, C8, CIS8, D8, DIS8, E8, F8, FIS8, G8, GIS8, A8, AIS8, H8, C9, CIS9, D9, DIS9, E9, F9, FIS9, G9, GIS9, A9, AIS9 }; const uint16_t notes[] PROGMEM = { 62764, // D3 146.832Hz 59242, // DIS3 155.563Hz 55917, // E3 164.814Hz 52778, // F3 174.614Hz 49816, // FIS3 184.997Hz 47020, // G3 195.998Hz 44381, // GIS3 207.652Hz 41890, // A3 220Hz 39539, // AIS3 233.082Hz 37320, // H3 246.942Hz 35225, // C4 261.626Hz 33248, // CIS4 277.183Hz 31382, // D4 293.665Hz 29620, // DIS4 311.127Hz 27958, // E4 329.628Hz 26389, // F4 349.228Hz 24907, // FIS4 369.994Hz 23509, // G4 391.995Hz 22190, // GIS4 415.305Hz 20944, // A4 440Hz 19769, // AIS4 466.164Hz 18659, // H4 493.883Hz 17612, // C5 523.251Hz 16623, // CIS5 554.365Hz 15690, // D5 587.33Hz 14810, // DIS5 622.254Hz 13978, // E5 659.255Hz 13194, // F5 698.456Hz 12453, // FIS5 739.989Hz 11754, // G5 783.991Hz 11094, // GIS5 830.609Hz 10472, // A5 880Hz 9884, // AIS5 932.328Hz 9329, // H5 987.767Hz 8805, // C6 1046.5Hz 8311, // CIS6 1108.73Hz 7845, // D6 1174.66Hz 7404, // DIS6 1244.51Hz 6989, // E6 1318.51Hz 6596, // F6 1396.91Hz 6226, // FIS6 1479.98Hz 5877, // G6 1567.98Hz 5547, // GIS6 1661.22Hz 5235, // A6 1760Hz 4941, // AIS6 1864.66Hz 4664, // H6 1975.53Hz 4402, // C7 2093Hz 4155, // CIS7 2217.46Hz 3922, // D7 2349.32Hz 3702, // DIS7 2489.02Hz 3494, // E7 2637.02Hz 3298, // F7 2793.83Hz 3113, // FIS7 2959.96Hz 2938, // G7 3135.96Hz 2773, // GIS7 3322.44Hz 2617, // A7 3520Hz 2470, // AIS7 3729.31Hz 2332, // H7 3951.07Hz 2201, // C8 4186.01Hz 2077, // CIS8 4434.92Hz 1960, // D8 4698.64Hz 1850, // DIS8 4978.03Hz 1746, // E8 5274.04Hz 1648, // F8 5587.65Hz 1556, // FIS8 5919.91Hz 1468, // G8 6271.93Hz 1386, // GIS8 6644.88Hz 1308, // A8 7040Hz 1235, // AIS8 7458.62Hz 1165, // H8 7902.13Hz 1100, // C9 8372.02Hz 1038, // CIS9 8869.84Hz 980, // D9 9397.27Hz 925, // DIS9 9956.06Hz 873, // E9 10548.1Hz 824, // F9 11175.3Hz 777, // FIS9 11839.8Hz 734, // G9 12543.9Hz 692, // GIS9 13289.8Hz 654, // A9 14080Hz 617 // AIS9 14917.2Hz }; typedef struct { uint8_t note; uint8_t time; } note_time_t; const note_time_t tune_1[] PROGMEM = { #if 0 { C4, 5 }, { CIS4, 5 }, { D4, 5 }, { DIS4, 5 }, { E4, 5 }, { F4, 5 }, { FIS4, 5 }, { G4, 5 }, { GIS4, 5 }, { A4, 5 }, { AIS4, 5 }, { H4, 5 }, { C5, 25 }, { PAUSE, 50 }, #endif #if 0 { E4, 15 }, { D4, 15 }, { C4, 15 }, { D4, 15 }, { E4, 15 }, { E4, 15 }, { E4, 30 }, { D4, 15 }, { D4, 15 }, { D4, 30 }, { E4, 15 }, { E4, 15 }, { E4, 30 }, { E4, 15 }, { D4, 15 }, { C4, 15 }, { D4, 15 }, { E4, 15 }, { E4, 15 }, { E4, 30 }, { E4, 15 }, { D4, 15 }, { D4, 15 }, { E4, 15 }, { D4, 15 }, { C4, 30 }, #endif #if 0 { G3, 10 }, { C4, 10 }, { D4, 10 }, { E4, 20 }, { E4, 20 }, { PAUSE, 10 }, { E4, 10 }, { D4, 10 }, { E4, 10 }, { C4, 20 }, { C4, 20 }, { PAUSE, 10 }, { C4, 10 }, { D4, 10 }, { E4, 10 }, { F4, 20 }, { A4, 20 }, { PAUSE, 10 }, { A4, 10 }, { G4, 10 }, { F4, 10 }, { E4, 20 }, { PAUSE, 10 }, { C4, 10 }, { D4, 10 }, { E4, 10 }, { F4, 20 }, { A4, 20 }, { PAUSE, 10 }, { A4, 10 }, { G4, 10 }, { F4, 10 }, { E4, 20 }, { C4, 20 }, { PAUSE, 10 }, { C4, 10 }, { D4, 10 }, { E4, 10 }, { F4, 10 }, { D4, 10 }, { D4, 10 }, { E4, 10 }, { C4, 20 }, { PAUSE, 10 }, #endif #if 0 { A5, 5*1 }, { G5, 5*1 }, { A5, 5*6 }, { PAUSE, 5*3 }, { G5, 5*1 }, { F5, 5*1 }, { E5, 5*1 }, { D5, 5*1 }, { CIS5, 5*2 }, { D5, 5*2 }, { PAUSE, 5*6 }, { A4, 5*1 }, { G4, 5*1 }, { A4, 5*6 }, { PAUSE, 5*3 }, { E4, 5*1 }, { F4, 5*1 }, { CIS4, 5*1 }, { D4, 5*2 }, { PAUSE, 5*3 }, #endif #if 1 #define FFF 5 { A6, FFF*1 }, { G6, FFF*1 }, { A6, FFF*6 }, { PAUSE, FFF*3 }, { G6, FFF*1 }, { F6, FFF*1 }, { E6, FFF*1 }, { D6, FFF*1 }, { CIS6, FFF*2 }, { D6, FFF*2 }, { PAUSE, FFF*6 }, { A5, FFF*1 }, { G5, FFF*1 }, { A5, FFF*6 }, { PAUSE, FFF*3 }, { E5, FFF*1 }, { F5, FFF*1 }, { CIS5, FFF*1 }, { D5, FFF*2 }, { PAUSE, FFF*6 }, { A4, FFF*1 }, { G4, FFF*1 }, { A4, FFF*6 }, { PAUSE, FFF*3 }, { G4, FFF*1 }, { F4, FFF*1 }, { E4, FFF*1 }, { D4, FFF*1 }, { CIS4, FFF*2 }, { D4, FFF*2 }, { PAUSE, FFF*6 }, #endif { PAUSE, 0 } }; typedef struct { uint8_t button_state; uint8_t button_pressed; uint8_t button_shift_bits; } data_t; static data_t data; void initialize() { data.button_state = 0; data.button_pressed = 0; data.button_shift_bits = 0; // timer 1: CTC Top=ICR1, clock/1, toggle OC1A TCCR1A = (1< 0 ) { if( nt.note != 0 ) { ICR1 = pgm_read_word( ¬es[nt.note-1] ); DDRB |= 1<