Music Jingle Generator
Photograph
of the prototype hardware:
N.B. the
grey ‘dongle’ in the background is the In-System Programmer.
Circuit
diagram:
Controlling
program:
(*$c 4 clock=4MHz*)
(*$d 2313 *)
PROGRAM Music;
(* Play a tune stored in
EEPROM variables *)
USES
LCDdisp2, ToneGen2; (* edit ToneGen2 for output on PB0 *)
CONST
rest = 0; A = #1; As = #2; B = #3; C = #4; Cs = #5; D = #6;
Ds = #7; E = #8; F = #9; Fs = #10; G = #11; Gs = #12;
semiQ = #1; quaver = #2; crochet = #4; minim = #8;
TYPE
TmusArray = array[0..71]
of byte;
TmsgArray = array[0..1]
of string;
VAR
(* initialized array
variables in EEPROM *)
music : TmusArray | EEPROM = (*note, octave, duration*)
[A, #3,semiQ,
Gs,#2,semiQ, A, #3,semiQ,
rest,#0,semiQ, E, #2,semiQ, rest,#0,semiQ,
Cs,#2,semiQ,
rest,#0,semiQ, E, #2,semiQ,
rest,#0,semiQ, A, #2,semiQ, B, #2,semiQ,
A, #2,semiQ,
Gs,#1,semiQ, A, #2,semiQ,
rest,#0,semiQ, E, #1,semiQ, rest,#0,semiQ,
Cs,#1,semiQ,
rest,#0,semiQ, E, #1,semiQ,
rest,#0,semiQ, A, #1,minim, #15,#0,#0];
(* initialized simple
variables *)
intro1 : string | EEPROM
= "Music Player V1";
intro2 : string | EEPROM
= "Press button...";
(* simple vars. in SRAM *)
note, octave, duration : byte;
i : word;
(* library subroutines *)
(* LCDdisp2 *)
PROCEDURE InitLCD;
LIBRARY;
PROCEDURE
WriteCh(ch:BYTE); LIBRARY;
PROCEDURE
WriteStr(str:STRING); LIBRARY;
PROCEDURE
CursorAt(posn:BYTE); LIBRARY;
PROCEDURE ClearLCD;
LIBRARY;
(* ToneGen2: change this
module to output on PB0 first *)
PROCEDURE InitTones;
LIBRARY;
PROCEDURE
SoundTone(pitch,octave,duration: BYTE); LIBRARY;
(* global procedures *)
PROCEDURE InitSwitch;
(* set up a press-switch
on port D, line 0 *)
BEGIN
ASM
cbi ddrD,0 ; declare this an input
sbi portD,0 ; switch on pull-up resistor
END;
END;
PROCEDURE
WaitForSwitchPress;
(* wait for switch on Pin
D.0 to be pressed *)
BEGIN
ASM (* do this in assembler *)
wait:sbic pinD,0
rjmp wait
END;
END;
BEGIN
(* set up hardware *)
InitLCD;
InitTones;
InitSwitch;
REPEAT
(* display intro. message *)
ClearLCD;
CursorAt(#0); WriteStr(intro1);
CursorAt(#16); WriteStr(intro2);
WaitForSwitchPress;
(* display title *)
ClearLCD;
CursorAt(#0); WriteStr("A bit of Bach..");
i:=0; (* start of music in array *)
note := music[i]; octave := music[i+1]; duration := music[i+2];
WHILE note <> #15 DO BEGIN
SoundTone(note, octave, duration);
i := i + 3; (* move to next group *)
note := music[i]; octave := music[i+1]; duration :=
music[i+2];
END;
END.