Pfad: Home => AVR-Übersicht => Anwendungen => Würfel mit ATtiny13 => Software Assembler
Würfel

Software für den Würfel mit ATtiny13


;
; **********************************************
; * Animierter Wuerfel mit einem ATtiny13      *
; * Version 1.0 vom Februar 2012               *
; * (C)2012 by http://www.avr-asm-tutorial.net *
; **********************************************
;
.nolist
.include "tn13def.inc"
.list
;
; ================
;  Programmablauf
; ================
;
; Timer 0: Prescaler = 64
;          Prozessortakt = 1,2 MHz
;          CTC-Wert = 6
;          OC0A-Interrupt: 3125 Hz, 320 us
;          16-Bit-Counter-Ueberlauf: 21 s
;          8-Bit-Counter-Ueberlauf: 82 ms
;          16-Bit-Counter-High fuer 2 Sekunden: 24
;
; ==========
;  Hardware
; ==========
;            _____  ______
;           /1    \/     8|
; RESET O--|RES        VCC|--O VCC +3V
;          |      AT      |
; L2/L6 O--|PB3        PB2|--O L3/L5
;          |     tiny     |
; Taste O--|PB4        PB1|--O L1/L7
;          |      13      |
;   GND O--|GND        PB0|--O L4
;          |______________|
;
;  ________________
; |                |
; |  L1        L5  |
; |                |
; |                |
; |  L2   L4   L6  |
; |                |
; |                |
; |  L3        L7  |
; |________________|
;
; ==================
;  Bit-Definitionen
; ==================
; 
.equ bL17 = 1<<PortB1 ; Led 1 und 7
.equ bL26 = 1<<PortB3 ; Led 2 und 6
.equ bL35 = 1<<PortB2 ; Led 3 und 5
.equ bL4 = 1<<PortB0 ; Led 4
;
; ============
;  Konstanten
; ============
;
; Festkonstanten und Rechenwerte
;
.equ clock = 1200000
.equ cPresc = 64
.equ cCtcA = 5
;
; ==========
;  Register
; ==========
;
.def rSreg = R15 ; SREG-Zwischenspeicher
.def rmp = R16 ; Multipurpose Register ausserhalb Int
.def rFlag = R17 ; Flaggenregister
  .equ bInp = 0 ; Input Signal gesetzt
  .equ bTmb = 1 ; Taumeln aktiv
  .equ bTOW = 2 ; warten auf Timeout
  .equ bTO = 3 ; Time-Out ist aktiviert
  .equ bTmbEn = 4 ; Taumeln ermoeglicht
  .equ bRpt = 5 ; Wiederholter Tastendruck
.def rTmb = R18 ; Anzahl Taumler
.def rCnt = R19 ; letzter Wuerfel
.def rCtrL = R24 ; Zaehler fuer Zeiten, LSB
.def rCtrH = R25 ; dto., MSB
;
; ==================
;  Interrupttabelle
; ==================
;
Start:
  rjmp Main
  reti ; INT0
  rjmp PinChg ; PCINT0
  reti ; TIM0_OVF
  reti ; EE_RDY
  reti ; ANA_COMP
  rjmp Tc0CmpA ; TIM0_COMPA
  reti ; TIM0_COMPB
  reti ; WDT
  reti ; ADC
;
; ============================
;  Interrupt Service Routinen
; ============================
;
; Pin Change
;
PinChg:
  in rSreg,SREG ; sichere Status-Register
  sbic PinB,PinB4 ; check absteigende Flanke
  rjmp PinChgRet
  sbr rFlag,1<<bInp ; setze Flagge
PinChgRet:
  out SREG,rSreg ; stelle Status wieder her
  reti
;
; Timer 0 Compare A
;
Tc0CmpA:
  in rSreg,SREG ; sichere Status-Register
  adiw rCtrL,1 ; aufwaerts zaehlen
  brne Tc0CmpARet
  sbr rFlag,1<<bTO ; aktiviere Timeout
Tc0CmpARet:
  out SREG,rSreg ; stelle Status wieder her
  reti
;
; ===========================
;  Hauptprogramm Initiierung
; ===========================
;
Main:
  ldi rmp, LOW(RAMEND) ; Setze Stapelzeiger
  out SPL,rmp
  ; Init port
  ldi rmp,0x0F ; untere Portpins als Ausgang
  out DDRB,rmp
  ldi rmp,0x10 ; Setze PB4 high, alle LED an
  out PORTB,rmp
  ; init Taster beim Einschalten
  ldi rmp,8 ; 3 Sekunden Verzoegerung
Main0:
  ldi rCtrH,High(0) ; 65536 Takte Verzoegerung
  ldi rCtrL,Low(0)
Main1:
  sbiw rCtrL,1 ; herabzaehlen
  brne Main1 ; weiter verzoegern
  dec rmp
  brne Main0
  in rFlag,PINB ; setze Flaggen auf Null
  cbr rFlag,0xEF ; loesche alles ausser Bit 4
  ldi rmp,0x1F ; loesche Lampen
  out PORTB,rmp
Main2:
  sbis PINB,4 ; warte bis Taste losgelassen
  rjmp Main2
  ; Init external interrupt
  ldi rmp,1<<PCINT4 ; external ints an PB4
  out PCMSK,rmp
  ldi rmp,1<<PCIE ; enable externe ints
  out GIMSK,rmp
  ; Init Timer
  ldi rmp,5 ; Timer 0 CTC A auf 6
  out OCR0A,rmp
  ldi rmp,1<<WGM01 ; CTC OCR0A
  out TCCR0A,rmp
  ldi rmp,(1<<CS01)|(1<<CS00) ; Prescaler = 64, start timer
  out TCCR0B,rmp
  ldi rmp,1<<OCIE0A ; Compare match interrupt
  out TIMSK0,rmp
  ; Sleep mode
  ldi rmp,1<<SE
  out MCUCR,rmp
  sei
;
; ========================
;  Hauptprogramm Schleife
; ========================
Loop:
  sleep
  nop
  sbrc rFlag,bTO
  rcall TimeOut
  sbrc rFlag,bTmb
  rjmp Tumble
  sbrc rFlag,bInp
  rcall Input
  rjmp Loop
;
;   .equ bInp = 0 ; Input Signal gesetzt
;   .equ bTmb = 1 ; Taumeln aktiv
;   .equ bTOW = 2 ; warten auf Timeout
;   .equ bTO = 3 ; Time-Out ist aktiviert
;   .equ bTOn = 4 ; Taumeln ermoeglicht

;
; ================
;  Unterprogramme
; ================
;
; Timeout
;
Timeout:
	cbr rFlag,1<<bTO ; loesche Flagge
	ldi rmp,0x1F ; alle Lampen aus
	out PORTB,rmp
	ret
;
; Taumeln aktiviert
;
Tumble:
	tst rCtrL
	brne TumbleEnd
	mov rmp,rCtrH ; kopiere MSB Zaehler
	andi rmp,0x03 ; 4 Durchlaeufe
	brne TumbleEnd
	inc rCnt ; naechster Wuerfel
	cpi rCnt,6
	brcs TumbleNext
	clr rCnt
TumbleNext:
	ldi ZH,HIGH(2*Tabelle)
	ldi ZL,LOW(2*Tabelle)
	add ZL,rCnt ; Addiere Tabellenanfang
	ldi rmp,0
	adc ZH,rmp ; Addiere Ueberlauf
	lpm ; lese Byte aus Tabelle
	out PORTB,R0
	dec rTmb ; noch ein Taumler?
	brne TumbleEnd
	cbr rFlag,1<<bTmb ; loesche Flagge
TumbleEnd:
	rjmp Loop
;
; Input-Taste aktiviert
;
Input:
	cbr rFlag,1<<bInp ; loesche Flagge
	sbrs rFlag,bRpt ; Wiederholung blockiert?
	rjmp Input1
	cpi rCtrH,10 ; abgelaufen?
	brcc Input1
	ret
Input1:
    mov rTmb,ZL ; speichere Taumelzaehler
	andi rTmb,0x03 ; maximal vier Taumler
	inc rTmb ; auf jeden Fall zwei
	inc rTmb
	clr rCtrH ; loesche Timer
	clr rCtrL
	in rmp,TCNT0 ; Lese Timer
	mov rCnt,rmp ; kopiere fuer Taumeln
	ldi ZH,HIGH(2*Tabelle)
	ldi ZL,LOW(2*Tabelle)
	add ZL,rmp ; Addiere Tabellenanfang
	ldi rmp,0
	adc ZH,rmp ; Addiere Ueberlauf
	lpm ; lese Byte aus Tabelle
	out PORTB,R0
	sbr rFlag,1<<bRpt ; setze Wiederholflagge
	sbrc rFlag,bTmbEn ; Taumelflagge?
	sbr rFlag,1<<bTmb
	ret
;
; ======================================
;  Tabelle mit den Wuerfelkombinationen
; ======================================
;
; Tabellenwerte
;
.equ cL1 = bL4 ; 0 = Led 4
.equ cL2 = bL17 ; 1 = Led 1 und 7
.equ cL3 = bL17 | bL4 ; 2 = Led 1, 4 und 7
.equ cL4 = bL17 | bL35 ; 3 = Led 1, 3, 5 und 7
.equ cL5 = bL17 | bL35 | bL4 ; 4 = Led 1, 3, 4, 5 und 7
.equ cL6 = bL17 | bL26 | bL35 ; 5 = Led 1, 2, 3, 5, 6 und 7
;
; Wuerfeltabelle
;
Tabelle:
.db 0b11111-cL1,0b11111-cL4
.db 0b11111-cL5,0b11111-cL2
.db 0b11111-cL6,0b11111-cL3
.db 0b10000
;




©2012 by http://www.avr-asm-tutorial.net