; ********************************************************* ; * Angeschlossener Taster macht Toene, Tonhoehe mit Poti * ; * (C)2005 by info@avr-asm-tutorial.net * ; ********************************************************* ; .INCLUDE "tn13def.inc" ; ; Schaltbild: ; ATMEL ATtiny13 ; ___ ____ ; ___ 1/ |_| |8 ;+5 Volt O--|___|----|Res Vcc|----O + 5 Volt ; | | ; +0..5 Volt O-------|ADC3 PB2| ___ ; / 3| |6 \_/ ; 0 Volt O--O O--|PB4 PB1|---|_|--O + 5 Volt ; 4| | LSP ; 0 Volt O----|Gnd PB0| ; |__________| ; ; Register Definitionen ; .DEF rTonA = R14 ; Tonhoehe = TC0 Compare Match A .DEF rTonB = R15 ; halbe Tonhoehe = TC0 Compare Match B .DEF rmp = R16 ; Multipurpose register .DEF rimp = R17 ; Interrupt multipurpose register ; ; 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 rjmp intadc ; 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 Befehl wenn PB4=Null rjmp intpcint1 ; springe weil PB4 = Eins out OCR0A,rTonA ; Tonhoehe einstellen out OCR0B,rTonB ldi rimp,0b01010010 ; CTC, Ausg. A und B bei out TCCR0A,rimp ; compare match auf toggle (NF an) ldi rimp,0b00000010 ; Vorteiler 1024, Timer start out TCCR0B,rimp reti ; Kehre vom Interrupt zurueck intpcint1: ldi rimp,0b11110010 ; CTC, Ausgaenge A und B bei out TCCR0A,rmp ; Compare Match auf 1 stellen (NF aus) reti ; Kehre vom Interrupt zurueck ; ; AD-Wandler hat einen Wert gewandelt, abholen und speichern ; intadc: in rTonA,ADCL ; Lese ADC-Wert, niedriges Byte in rTonB,ADCH ; Lese ADC-Wert, hohes Byte lsr rTonB ; durch 2 teilen ror rTonA lsr rTonB ; durch 4 teilen ror rTonA mov rTonB,rTonA ; Ergebnis kopieren lsr rTonB ; durch zwei teilen reti ; fertig und zureck ; ; 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-Pin als Ausgang definieren cbi DDRB,4 ; Taster-Eingang als Eingang definieren sbi PORTB,4 ; Internen Pull-Up-Widerstand einschalten ; ; AD-Wandler starten ; ldi rmp,0b00001000 ; PB3 Treiber aus, spart Strom out DIDR0,rmp ldi rmp,0b00000011 ; Referenzspannung UB, ADC3 waehlen out ADMUX,rmp ldi rmp,0b00000000 ; Freilauf waehlen (startet selbst) out ADCSRB,rmp ldi rmp,0b11101111 ; ADC starten, Autostart, out ADCSRA,rmp ; Int Enable, Teiler auf 128 ; ; 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 ; Start erfolgt erst bei PCINT-Interrupt ; ldi rmp,75 ; Setze Compare A auf 147 (Ende Zaehler) mov rTonA,rmp ; speichere in Register ldi rmp,38 ; Setze Compare B auf halben Timer-Wert mov rTonB,rmp ; speichere in Register ; ; 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 ; Schlafmodus auf 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 ;