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;

FOREVER

END.

 

Back