Pfad: Home => AVR overview => Applications => Dive with ATtiny13 => Software Assembler
Tumbling dice

Software for the tumbling dice with ATtiny13


;
; **********************************************
; * Animated tumbling dice with an ATtiny13    *
; * Version 1.0 as of February 2012            *
; * (C)2012 by http://www.avr-asm-tutorial.net *
; **********************************************
;
.nolist
.include "tn13def.inc"
.list
;
; =========================
;  Program characteristica
; =========================
;
; Timer 0: Prescaler = 64
;          Processor clock = 1.2 MHz
;          CTC-value = 6
;          OC0A-Interrupt: 3125 Hz, 320 us
;          16-Bit-Counter-Overflow: 21 s
;          8-Bit-Counter-Overflow: 82 ms
;          16-Bit-Counter-High for 2 Seconds: 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-Definitions
; ==================
; 
.equ bL17 = 1<<PortB1 ; Led 1 and 7
.equ bL26 = 1<<PortB3 ; Led 2 and 6
.equ bL35 = 1<<PortB2 ; Led 3 and 5
.equ bL4 = 1<<PortB0 ; Led 4
;
; ==========
;  Constant
; ==========
;
; Fixed values and calculation constants
;
.equ clock = 1200000
.equ cPresc = 64
.equ cCtcA = 5
;
; ===========
;  Registers
; ===========
;
.def rSreg = R15 ; SREG-interim storage
.def rmp = R16 ; Multipurpose Register outside Int
.def rFlag = R17 ; Flag register
  .equ bInp = 0 ; Input Signal set
  .equ bTmb = 1 ; Tumble aktice
  .equ bTOW = 2 ; wait for Timeout
  .equ bTO = 3 ; Time-Out is activated
  .equ bTmbEn = 4 ; Tumble enabled
  .equ bRpt = 5 ; Repeat pushbutton press
.def rTmb = R18 ; Number of tumbles
.def rCnt = R19 ; last value
.def rCtrL = R24 ; Counter for timing, LSB
.def rCtrH = R25 ; dto., MSB
;
; =================
;  Interrupt table
; =================
;
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 Routines
; ============================
;
; Pin Change
;
PinChg:
  in rSreg,SREG ; safe Status in register
  sbic PinB,PinB4 ; check negative edge
  rjmp PinChgRet
  sbr rFlag,1<<bInp ; set flag
PinChgRet:
  out SREG,rSreg ; restore status
  reti
;
; Timer 0 Compare A
;
Tc0CmpA:
  in rSreg,SREG ; safe status in register
  adiw rCtrL,1 ; upward counting
  brne Tc0CmpARet
  sbr rFlag,1<<bTO ; aktivate timeout
Tc0CmpARet:
  out SREG,rSreg ; restore status
  reti
;
; ===================
;  Main program Init
; ===================
;
Main:
  ldi rmp, LOW(RAMEND) ; init stack pointer
  out SPL,rmp
  ; Init port
  ldi rmp,0x0F ; lower portpins as output
  out DDRB,rmp
  ldi rmp,0x10 ; set PB4 high, all LEDs on
  out PORTB,rmp
  ; init pushbutton during startup
  ldi rmp,8 ; 3 seconds delay
Main0:
  ldi rCtrH,High(0) ; 65536 clock cycles delay
  ldi rCtrL,Low(0)
Main1:
  sbiw rCtrL,1 ; count down
  brne Main1 ; continue delay
  dec rmp
  brne Main0
  in rFlag,PINB ; set flags to zero
  cbr rFlag,0xEF ; clear anything but Bit 4
  ldi rmp,0x1F ; clear LEDs
  out PORTB,rmp
Main2:
  sbis PINB,4 ; wait until pushbutton not pushed any more
  rjmp Main2
  ; Init external interrupt
  ldi rmp,1<<PCINT4 ; external ints on PB4
  out PCMSK,rmp
  ldi rmp,1<<PCIE ; enable external ints
  out GIMSK,rmp
  ; Init Timer
  ldi rmp,5 ; Timer 0 CTC A to 6
  out OCR0A,rmp
  ldi rmp,1<<WGM01 ; CTC on 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
;
; ===================
;  Main program loop
; ===================
Loop:
  sleep
  nop
  sbrc rFlag,bTO
  rcall TimeOut
  sbrc rFlag,bTmb
  rjmp Tumble
  sbrc rFlag,bInp
  rcall Input
  rjmp Loop
;
; =============
;  Subroutines
; =============
;
; Timeout
;
Timeout:
 cbr rFlag,1<<bTO ; clear flag
 ldi rmp,0x1F ; all LEDs off
 out PORTB,rmp
 ret
;
; Tumble active
;
Tumble:
 tst rCtrL
 brne TumbleEnd
 mov rmp,rCtrH ; copy MSB counter
 andi rmp,0x03 ; four loops
 brne TumbleEnd
 inc rCnt ; next value
 cpi rCnt,6
 brcs TumbleNext
 clr rCnt
TumbleNext:
 ldi ZH,HIGH(2*Tabelle)
 ldi ZL,LOW(2*Tabelle)
 add ZL,rCnt ; Add table start
 ldi rmp,0
 adc ZH,rmp ; Add overflow
 lpm ; read byte from table
 out PORTB,R0
 dec rTmb ; another tumble?
 brne TumbleEnd
 cbr rFlag,1<<bTmb ; clear flag
TumbleEnd:
 rjmp Loop
;
; Input button activated
;
Input:
 cbr rFlag,1<<bInp ; clear flag
 sbrs rFlag,bRpt ; repetition blocked?
 rjmp Input1
 cpi rCtrH,10 ; done?
 brcc Input1
 ret
Input1:
    mov rTmb,ZL ; store tumble counter
 andi rTmb,0x03 ; max four tumbles
 inc rTmb ; in any case add two
 inc rTmb
 clr rCtrH ; clear timer counter
 clr rCtrL
 in rmp,TCNT0 ; read timer
 mov rCnt,rmp ; copy for tumbling
 ldi ZH,HIGH(2*Tabelle)
 ldi ZL,LOW(2*Tabelle)
 add ZL,rmp ; Add table start
 ldi rmp,0
 adc ZH,rmp ; Add overflow
 lpm ; read byte from table
 out PORTB,R0
 sbr rFlag,1<<bRpt ; set repetition flag
 sbrc rFlag,bTmbEn ; tumble flag?
 sbr rFlag,1<<bTmb
 ret
;
; =============================
;  Table with die combinations
; =============================
;
; Table values
;
.equ cL1 = bL4 ; 0 = Led 4
.equ cL2 = bL17 ; 1 = Led 1 and 7
.equ cL3 = bL17 | bL4 ; 2 = Led 1, 4 and 7
.equ cL4 = bL17 | bL35 ; 3 = Led 1, 3, 5 and 7
.equ cL5 = bL17 | bL35 | bL4 ; 4 = Led 1, 3, 4, 5 and 7
.equ cL6 = bL17 | bL26 | bL35 ; 5 = Led 1, 2, 3, 5, 6 and 7
;
; Die table
;
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