; ************************************************
; * Angeschlossener Taster macht Toene           *
; * (C)2005 by info@avr-asm-tutorial.net         *
; ************************************************
;
.INCLUDE "tn13def.inc"
;
; Schaltbild:
;                   ATMEL ATtiny13
;                     ___   ____
;            ___    1/   |_|    |8
;+5 Volt O--|___|----|Res    Vcc|----O + 5 Volt
;                    |          |
;                    |PB3    PB2|   ___
;                /  3|          |6  \_/
;     0 Volt O--O O--|PB4    PB1|---|_|--O + 5 Volt
;                   4|          |   LSP
;        0 Volt O----|Gnd    PB0|
;                    |__________|
;
; Register Definitionen
;
.DEF rmp = R16 ; Multipurpose register
.DEF rimp = R17 ; Interrupt multipurpose register
;
; Constants
;
;
; Reset- und Interrupt Vektoren
;
.CSEG ; Assembliere in den Programm-Flash-Speicher
.ORG $0000 ; beginne mit Adresse 0
;
; Sprungvektoren fuer Reset und Interrupts
;
	rjmp main ; Reset vector
	reti ; Int0 interrupt vector
	rjmp intpcint ; PCINT0 vector
	reti ; TC0 overflow vector
	reti ; Eeprom ready vector
	reti ; Analog comparator int vector
	reti ; TC0 CompA vector
	reti ; TC0 CompB vector
	reti ; WDT vector
	reti ; ADC conversion complete vector
;
; PCINT0 Service Routine
;   wird jedes Mal ausgefuehrt, wenn sich der Pegel am
;   Pin 3 (=PB4) aendert 
;
intpcint:
	sbic PINB,4 ; Ueberspringe 1 Befehl wenn PB4 Null
	rjmp intpcint1 ; springe weil PB4 = Eins
	ldi rmp,0b00010010 ; CTC, Ausgang B bei Cmp Match auf Toggle
	out TCCR0A,rmp
	reti ; Kehre vom Interrupt zurueck
intpcint1:
	ldi rmp,0b00110010 ; CTC, Ausgang B bei Cmp Match auf 1
	out TCCR0A,rmp
	reti ; Kehre vom Interrupt zurueck
;
; Main program start
;
main:
;
; Stapelzeiger setzen fuer Rueckkehr-Adressen vom Interrupt
;
	ldi rmp,LOW(RAMEND) ; Stapelzeiger auf Ende SRAM
	out SPL,rmp
;
; Angeschlossene Hardware initiieren
;
	sbi DDRB,1 ; Lautsprecher-Ausgang als Ausgang definieren
	cbi DDRB,4 ; Taster-Eingang als Eingang definieren
	sbi PORTB,4 ; Internen Pull-Up-Widerstand einschalten
;
; Tonerzeugung mit Timer TC0
; 8-Bit-Timer mit 1,2 MHz Prozessortakt mit Vorteiler durch 8
; 1,2 MHz / 8 = 150 kHz, / 75 = 2000 Hz, /2 = 1000 Hz
;
	ldi rmp,55 ; Setze Compare A auf 147 (Ende Zaehler)
	out OCR0A,rmp
	ldi rmp,38 ; Setze Compare B auf halben Timer-Wert
	out OCR0B,rmp
	ldi rmp,0b11110010 ; CTC, Ausg. A + B bei Cmp Match auf 1
	out TCCR0A,rmp
	ldi rmp,0b00000010 ; Vorteiler durch 1024, Timer starten
	out TCCR0B,rmp
;
; Pin-Change-Interrupt fuer Taste aktivieren
;
	ldi rmp,0b00010000 ; Maskieren der aktiven Eingaenge
	out PCMSK,rmp
	ldi rmp,0b00100000 ; PCINT0-Interrupts ermoeglichen
	out GIMSK,rmp
;
; Interrupts generell einschalten
;
	sei ; Setze Interrupt Flagge
;
; Schlafmodus der CPU einstellen
;
	ldi rmp,0b00100000 ; Schlafen ermoeglichen, Modus Idle
	out MCUCR,rmp
;
; Loop mit Interrupt
;
loop:
	sleep ; Prozessor schlafen legen
	nop ; Tue nichts nach dem Aufwachen
	rjmp loop ; Prozessor wieder schlafen legen
;
; Ende Quellcode
;