Timer-Musik

timer-musik.luna
'**************************************************************************
'* Name        : Timer-Musik
'* Function    : First Steps Example
'* Hardware    : aTeVaL Evaluation Board - http://www.ehajo.de
'**************************************************************************
'* Compiler    : lunaAVR 2013.r4 (or newer)
'**************************************************************************
'* Author      : rgf, avr@myluna.de
'* Date/Version: 16.08.2013
'* www         : http://avr.myluna.de
'**************************************************************************
' µC-Belegung am Beispiel Atmega328p
' Summer:  PortD.7 !Die Lötbrücke "SPKR" auf der Lötseite muss geschlossen sein!
'**************************************************************************
 
avr.device = atmega328p		'Controller-Typ festlegen
avr.clock = 8000000			'Dem Compiler mitteilen mit welcher Taktrate der Controller läuft
avr.stack = 64				'Den Programmstack einstellen
 
'Den Port-Pin des Summers mit einem Bezeichner
'versehen. Dies zur besseren Lesbarkeit im Quelltext
#define SUMMER as PortD.7
 
'Diese Werte berechnen sich aus "8MHz / Frequenz des Tones / 2"
'Sollte ein anderer CPU-Takt verwendet werden muessen
'die Werte neu berechnet werden.
#define TON_C		as 15152
#define TON_CIS		as 14545
#define TON_D		as 13468
#define TON_ES		as 12618
#define TON_E		as 12121
#define TON_F		as 11364
#define TON_FIS		as 10899
#define TON_G		as 10101
#define TON_GIS		as 9479
#define TON_A		as 9091
#define TON_B		as 8421
#define TON_H		as 8081
#define TON_CC		as 7576
#define TON_CCIS	as 7273
#define TON_DD		as 6734
#define TON_EES		as 6309
#define TON_EE		as 6061
#define TON_FF		as 5682
#define TON_FFIS	as 5450
#define TON_GG		as 5051
#define TON_GGIS	as 4740
#define TON_AA		as 4546
#define TON_BB		as 4211
#define TON_HH		as 4041
 
SUMMER.mode	= output,low	'Summer als Ausgang
 
'Den Timer1 Konfigurieren
'Taktteiler des Timers einstellen auf 1:1 (8 Mhz)
Timer1.Clock = 1
'Compare-Interrupt aktivieren
Timer1.CmpA.Isr = timer1_compare
'CTC-Mode aktivieren (Zähler setzt sich selbsttätig zurück)
Timer1.CmpA.Clear.enable
 
' Outputcompare-Register setzen, Ton A
Timer1.CmpA.Value = TON_C
 
' globale Variablen
dim i as byte	'Laufvariable
 
'Globale Interrupts einschalten
Avr.Interrupts.Enable
 
for i=0 to 37
  ' Fuer alle Noten im Datensatz
  ' Compare-Wert entsprechend Eintrag setzen
  Timer1.CmpA.Value = tonleiter.WordValue(melodie.ByteValue(i)*2)
 
  'Timer einschalten
  Timer1.CmpA.Enable
 
  ' Warten damit die Note klingen kann...
  waitms dauer.ByteValue(i)*300 ' *300 klingt ganz gut bei dem Lied
 
  ' Timer kurz aus- und wieder einschalten damit gleiche Noten
  ' hintereinander unterschieden werden koennen
  Timer1.CmpA.Disable
  waitms 2
next
 
'Lied ende, Timer ausschalten
Timer1.CmpA.Disable
 
 
'Hauptschleife
do
  'nix...
loop
 
isr timer1_compare
  SUMMER.toggle
endisr
 
' In diesem Datensatz stehen die Werte fuer den CTC-Counter
' Jeder Eintrag ist Wortbreit (16 Bit), daher müssen wir den Index * 2
' nehmen wenn wir einen Eintrag mit tonleiter.WordValue() lesen wollen
data tonleiter
  .dw TON_C		//  0
  .dw TON_CIS	//  1
  .dw TON_D		//  2
  .dw TON_ES	//  3
  .dw TON_E		//  4
  .dw TON_F		//  5
  .dw TON_FIS	//  6
  .dw TON_G		//  7
  .dw TON_GIS	//  8
  .dw TON_A		//  9
  .dw TON_B		// 10
  .dw TON_H		// 11
  .dw TON_CC	// 12
  .dw TON_CCIS	// 13
  .dw TON_DD	// 14
  .dw TON_EES	// 15
  .dw TON_EE	// 16
  .dw TON_FF	// 17
  .dw TON_FFIS	// 18
  .dw TON_GG	// 19
  .dw TON_GGIS	// 20
  .dw TON_AA	// 21
  .dw TON_BB	// 22
  .dw TON_HH	// 23
enddata
' Melodie definieren, in diesem Fall 
data melodie
  .db 14	// Sand-
  .db 14	// mann
  .db 11	// lie-
  .db 12	// ber
  .db 14	// Sand-
  .db 14	// mann
  .db 11	// es
  .db 11	// ist
  .db 12	// noch
  .db 9		// nicht
  .db 11	// so
  .db 7		// weit!
  .db 7		// Wir
  .db 9		// sen-
  .db 11	// den
  .db 9		// erst
  .db 11	// den
  .db 7		// A-
  .db 4		// bend-
  .db 6		// ...
  .db 7		// gruß,
  .db 9		// eh
  .db 7		// ...
  .db 6		// je-
  .db 9		// des
  .db 7		// Kind
  .db 9		// ins
  .db 11	// Bett-
  .db 12	// chen
  .db 14	// muss.
  .db 11	// Du
  .db 12	// ...
  .db 9		// hast
  .db 7		// ge-
  .db 9		// wiss
  .db 4		// noch
  .db 6		// ...
  .db 7		// Zeit.
enddata
' Die Dauer der Noten definieren, 1 = 1/8-Note, 2 = 1/4 usw.
data dauer
  .db 2,2,1,1,2,2,2,3,1,1,1,4,2,3,1,1,1,2,1,1,4,1,1,1,1,1,1,1,1,4,1,1,1,1,2,1,1,6
enddata