.nolist .include "tn13adef.inc" ; Define device ATtiny13A .list ; Hinweise ; Verwendet den internen 128KHz-Oszillator ; ; ; Device: ATtiny13A, Package: 8-pin-PDIP_SOIC ; ; _________ ; 1 / |8 ; o--|RESET VCC|--o--\ ; o--|PB3 PB2|--o | ; Taster--------o--|PB4 PB1|--o--^-------[5K]-- >|- LED---Gnd ; | 100n--o--|GND PB0|--o--^-------[5K]-- >|- LED---Gnd ; | | 4 |__________|5 | ;Gnd | | ; \-------------------------/ ; ********************************** ; F I X & D E R I V. C O N S T ; ********************************** .equ F_CPU=128000 ; interner 128KHz-Oszillator .equ LED1 = PB0 ; physischer PWM-Port .equ LED2 = PB1 ; nur die zweit-LED .equ LEDPORT = PORTB .equ TASTER = PINB4 .equ TASTERPORT = PINB .equ PROGRAMMAX = 5 ; Programmanzahl plus eins .equ COUNTERVALUE=30 ; ca. zwei Sekunden bei Watchdog .equ MINIMUM=40 ; minimum für zufallszahl -> mindest-LED-Helligkeit .equ FAKTOR=80 ; Zeitfaktor für die Morsegeschwindigkeit. Je höher desto langsamer. .equ COUNTERDIT=80 ; Dauer eines Morse-Dit .equ COUNTERDAH=3*COUNTERDIT ; üblicherweise drei mal dit .equ STEPMAX=15 ; Bitmaske für step = fading-Geschwindigkeit .equ COUNTERMAX=800 ; für 16-Bit-counter r24 und r25 .equ P3STEP=20 .equ SAVE_COUNTER=200 ; ca. 20 Sekunden .equ COUNTERISZERO=0 .equ PROGRAMHASCHANGED=1 .equ SAVENEEDED=2 ; ********************************** ; R E G I S T E R S ; ********************************** .def zufallszahl = r0 .def zero=r1 ; immer Null .def rueckf1=r2 .def rueckf2=r3 .def sollwert=r4 ; Für die mindest-LED-Helligkeit .def rueckf4=r5 .def eins=r6 .def number1 = r7 ; 32-Bit-LFSR .def number2 = r8 .def number3 = r9 .def number4 = r10 .def eeprombyte = r11 ; ein Byte als Zwischenspeicher .def eepromcounter=r12 ; Zähler für den Z-Pointer .def countermaxlow=r13 .def countermaxhigh=r14 .def rSreg = r15 ; Save/Restore status port .def rmp = r16 ; Define multipurpose register .def rmp2 = r17 .def statusbits=r18 ; einzelne Bits: Bit 0 = ist "1", wenn Entprell-counter_=_0 (Watchdog-ISR) ; Bit 1 = ist "1", wenn Programmnummer sich geändert hat ; Bit 2 = ist "1" wenn Programmnummer neu gespeichert wird (nach Ablauf von ca. 13 Sekunden nach einem Tastendruck automatisch) .def step = r19 .def counter=r20 .def letter=r21 .def dreibit=r22 .def programmnummer=r23 ; Nummer aktuelles Programm, derzeit 0 bis 4 .def lowbyte=r24 .def highbyte=r25 .def savecounter=r26 ; ; ********************************** ; S R A M ; ********************************** ; .dseg .org SRAM_START .eseg .org 0 textdaten: .db "ein kleiner " .db "testtext " .db 0 eepromadresse: .db 1 ; ********************************** ; C O D E ; ********************************** .cseg .org 000000 ; ********************************** ; R E S E T & I N T - V E C T O R S ; ********************************** rjmp Main ; Reset vector reti ; INT0 reti ; PCI0 rjmp isr_timeroverflow ; OVF0 reti ; ERDY reti ; ACI rjmp isr_comparematch ; OC0A reti ; OC0B rjmp isr_watchdog ; WDT reti ; ADCC ; ********************************** ; I N T - S E R V I C E R O U T . ; ********************************** isr_timeroverflow: push rmp push rmp2 in rsReg,SREG add lowbyte, eins adc highbyte, zero cp lowbyte,countermaxlow cpc highbyte, countermaxhigh brne keinreset clr lowbyte clr highbyte keinreset: cpi programmnummer, 2 ; flackern breq continue rjmp isr_ende2 continue: cbi PORTB, LED2 in rmp, OCR0A cp zufallszahl, rmp breq neuezahl cp zufallszahl, rmp brlo abwaerts ; OCR0A ist größer als Zahl -> runter zur Zahl zählen aufwaerts: ; zufallszahl ist groesser als OCR0A ; rmp2 = zufallszahl mov rmp2, zufallszahl ;inc rmp2 ; für den Fall Differenz - step = 0 sub rmp2, rmp ; zufallszahl - OCR0A cpc rmp2, step brlo neuezahl add rmp, step rjmp isr_ende abwaerts: ;OCR0A ist groesser als zufallszahl ; Differenz zufannszahl und OCR0a groesser als step? ; rmp2 = OCR0A, davon zufallszahl abziehen ; wenn Ergebnis kleiner als step: neue Zahl (carry?) mov rmp2, rmp sub rmp2, zufallszahl cpc rmp2, step brlo neuezahl sub rmp, step rjmp isr_ende neuezahl: rcall zufallszahl32 mov step, number2 andi step,STEPMAX cp step, zero brne isr_ende inc step isr_ende: out OCR0A, rmp isr_ende2: out SREG, rSreg pop rmp2 pop rmp reti isr_comparematch: push rmp in rSreg, SREG cpi programmnummer, 2 ; flackern breq cmp_weiter rjmp compareende cmp_weiter: sbi PORTB, LED2 compareende: out SREG, rSreg pop rmp reti isr_watchdog: in rSreg, SREG cp savecounter, zero breq isr_weiter dec savecounter cp savecounter, zero brne isr_weiter sbr statusbits,(1< Anzahl an Symbolen morsezeichen: sbi PORTB,LED1 lsr letter brcs sendedah sendedit: ldi rmp, COUNTERDIT rcall beep rjmp symbolende sendedah: ldi rmp, COUNTERDAH rcall beep symbolende: cbi PORTB,LED1 ldi rmp, COUNTERDIT rcall beep dec dreibit brne morsezeichen rjmp pause langepause: ; zwischen zwei Buchstaben cbi PORTB,LED1 ldi rmp, COUNTERDIT rcall beep rcall beep rcall beep rcall beep rcall beep pause: rcall beep rcall beep rjmp loopsleep programm3: ldi rmp, LOW(P3STEP) ldi rmp2, HIGH(P3STEP) cp lowbyte, rmp cpc highbyte, rmp2 breq p3_ledan ldi rmp, LOW(2*P3STEP) ldi rmp2, HIGH(2*P3STEP) cp lowbyte, rmp cpc highbyte, rmp2 breq p3_ledaus ldi rmp, LOW(3*P3STEP) ldi rmp2, HIGH(3*P3STEP) cp lowbyte, rmp cpc highbyte, rmp2 breq p3_ledan ldi rmp, LOW(4*P3STEP) ldi rmp2, HIGH(4*P3STEP) cp lowbyte, rmp cpc highbyte, rmp2 breq p3_ledaus ldi rmp, LOW(5*P3STEP) ldi rmp2, HIGH(5*P3STEP) cp lowbyte, rmp cpc highbyte, rmp2 breq p3_ledan ldi rmp, LOW(6*P3STEP) ldi rmp2, HIGH(6*P3STEP) cp lowbyte, rmp cpc highbyte, rmp2 breq p3_ledaus rjmp loopsleep p3_ledan: sbi LEDPORT, LED1 rjmp p3_ende p3_ledaus: cbi LEDPORT, LED1 p3_ende: rjmp loopsleep beep: ldi rmp2,FAKTOR beep1: dec rmp2 brne beep1 beep2: ldi rmp2, FAKTOR dec rmp brne beep1 ldi rmp, COUNTERDIT ret case: push rmp ldi ZL,LOW(sprungtabelle) ldi ZH,HIGH(sprungtabelle) add ZL, programmnummer adc ZH, zero ijmp sprungtabelle: rjmp case0 rjmp case1 rjmp case2 rjmp case3 rjmp case4 case0: ; Blinker rcall cleartimer0 ldi rmp, (1<