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.