Home ==> Inhaltsverzeichnis ==> 5-6-Zähler ==> Asm-Quellcode

Assembler-Quellcode für den Fünf/Sechs-Zähler

Der Quellcode im Assembler-Format ist hier, im Folgenden das Listing des Quellcodes.
  
;
; ***********************************
; * Fuenf/Sechs-Zaehler-Controller  *
; * mit ATtiny24(A), Version 1.0    *
; * (C)2022 by Gerhard Schmidt      *
; ***********************************
;
.nolist
.include "tn24adef.inc" ; Define device ATtiny24A
.list
;
; **********************************
;       H A R D W A R E
; **********************************
;
; Device: ATtiny24A, Package: 14-pin-PDIP_SOIC
;
;           _________
;        1 /         |14
;   +5Vo--|Vcc    Gnd|--o 0 V
;  Rel1o--|PB0    Pa0|--o L1/La
;  Rel2o--|PB1    Pa1|--o L2/Lb
; Reseto--|Reset  Pa2|--o L3/Lc
; Kont.o--|Int0   Pa3|--o L4/Ld
;    J1o--|Pa7    Pa4|--o L5/Le
; L7/Lgo--|Pa6    Pa5|--o L6/Lf
;       7 |__________|8
;
; **********************************
;      K O N S T A N T E N
; **********************************
;
; Verzoegerungswert bei der Einschaltanimation, 0..65535
  .equ cAnim = 30000 ; Je groesser desto langsamer
;
; Werte fuer die Relais-Schaltungs-Timer
  .equ cTc0Cmp = 221 ; CTC-Vergleichswert
  .equ cTc0Ctr = 22 ; Zaehler
  .equ cTc0Prsc = (1<<CS02)|(1<<CS00) ; Vorteiler-Bits
  .equ cTc1Cmp = 19530 ; CTC-Vergleichswert
  .equ cTc1Prsc = 1<<CS02 ; Vorteiler-Bits
;
; **********************************
;       R E G I S T E R S
; **********************************
;
.def rFuenf = R0 ; Die Fuenf-Erkennung
.def rSechs = R1 ; Die Sechs-Erkennung
; frei: R2 bis R15
.def rmp = R16 ; Definiere Vielzweck-Register
.def rTc0 = R17 ; Zaehler-Register fuer Relais 1
; frei: R18 bis R23
.def rCntL = R24 ; 16-Bit-Zaehler fuer Animation, LSB
.def rCntH = R25 ; dto., MSB
; frei: X und Y
; benutzt: R31:R30 = Z, Zeiger-Register fuer Anzeige
;
.cseg
.org 000000
;
; **********************************
; R E S E T  &  I N T - V E C T O R S
; **********************************
	rjmp Main ; Reset vector
	rjmp Int0Isr ; EXT_INT0
	reti ; PCI0
	reti ; PCI1
	reti ; WATCHDOG
	reti ; ICP1
	rjmp Oc1aIsr ; OC1A
	reti ; OC1B
	reti ; OVF1
	rjmp Oc0aIsr ; OC0A
	reti ; OC0B
	reti ; OVF0
	reti ; ACI
	reti ; ADCC
	reti ; ERDY
	reti ; USI_STR
	reti ; USI_OVF
;
; **********************************
;  I N T - S E R V I C E   R O U T .
; **********************************
;
Int0Isr:
  sbic PINB,PINB2 ; INT0-Eingang abfragen
  rjmp Int0High ; INT0-Eingang ist high
  ; INT0-Eingang ist low
  lpm rmp,Z+ ; Lese naechsten Status
  cpi rmp,0xC0 ; Teste auf Ende der Tabelle
  brne Int0Ausg ; Tabelle ist nicht am Ende
  ; Tabellenende erreicht, Neustart beim zweiten Eintrag
  sbic PINA,PINA7 ; Led oder 7-seg?
  rjmp Int0Led ; LEDs sind eingestellt
  ; Sieben-Segment-Anzeige
  ldi ZH,High(2*SiebenSegment+5)
  ldi ZL,Low(2*SiebenSegment+5)
  lpm rFuenf,Z+ ; Lese die Fuenf
  lpm rSechs,Z ; Lese die Sechs
  ldi ZH,High(2*SiebenSegment+1)
  ldi ZL,Low(2*SiebenSegment+1)
  rjmp Int0Lesen
Int0Led:
  ; LED-Ausgabe ist ausgewaehlt
  ldi ZH,High(2*SiebenLeds+5)
  ldi ZL,Low(2*SiebenLeds+5)
  lpm rFuenf,Z+ ; Lese die Fuenf
  lpm rSechs,Z ; Lese die Sechs
  ldi ZH,High(2*SiebenLeds+1)
  ldi ZL,Low(2*SiebenLeds+1)
Int0Lesen:
  lpm rmp,Z+
Int0Ausg:
  out PORTA,rmp
  cp rmp,rFuenf ; Fuenfter Impuls?
  breq Int0Rel1 ; Schalte Relais 1 an
  cp rmp,rSechs ; Sechster Impuls?
  breq Int0Rel2 ; Schalte Relais 2 an
  reti
Int0High: ; Eingang war high
  sbic PINA,PINA7 ; LED-Ausgabe?
  cbi PORTA,PORTA6 ; Ja: mache L7 aus
  reti
; Schalte Relais 1 an
Int0Rel1:
  sbi PORTB,PORTB0 ; Schalte Relais 1 an
  ldi rTc0,cTc0Ctr ; Starte Zaehler
  ldi rmp,cTc0Cmp ; Lade CTC-Vergleichswert
  out OCR0A,rmp ; in Vergleichsregister A
  ldi rmp,1<<WGM01 ; CTC-Modus
  out TCCR0A,rmp ; in Kontrollregister A
  ldi rmp,cTc0Prsc ; Vorteilerwert
  out TCCR0B,rmp ; in Kontrollregister B
  ldi rmp,1<<OCIE0A ; Interrupt bei Compare A
  out TIMSK0,rmp ; in Timer Interrupt-Maske
  reti
; Schalte Relais 2 an
Int0Rel2:
  sbi PORTB,PORTB1 ; Relais 2 anschalten
  ldi rmp,High(cTc1Cmp) ; Lade Vergleichswert, MSB
  out OCR1AH,rmp ; in Vergleichsregister A
  ldi rmp,Low(cTc1Cmp) ; dto., LSB
  out OCR1AL,rmp ; dto., LSB
  ldi rmp,(1<<WGM12)|cTc1Prsc ; CTC-Modus, Vorteiler-Wert
  out TCCR1B,rmp ; in Kontrollregister B
  ldi rmp,1<<OCIE1A ; Interrupt bei Compare A
  out TIMSK1,rmp
  reti
;
; OC0A-Interrupt: zaehlen und Relais 1 aus
Oc0aIsr: ; Stoppt Relais 1 und TC0
  dec rTc0 ; Abwaerts zaehlen
  brne Oc0aReti ; Noch nicht Null, weiter
  cbi PORTB,PORTB0 ; Timer ausschalten
  clr rmp ; Null in Register
  out TIMSK0,rmp ; Interrupts aus
  out TCCR0B,rmp ; Timer aus
  out TCNT0,rmp ; Timer auf Null
Oc0aReti:
  reti
; OC1A-Interrupt: Relais 2 ausschalten
Oc1aIsr: ; Stoppt Relais 2 und TC1
  cbi PORTB,PORTB1 ; Relais aus
  clr rmp
  out TIMSK1,rmp ; Interrupts aus
  out TCCR1B,rmp ; Timer aus
  out TCNT1H,rmp ; Timer auf Null, MSB
  out TCNT1L,rmp ; dto., LSB
  reti
;
; **********************************
; H A U P T P R O G R A M M  I N I T
; **********************************
;
Main:
.ifdef SPH ; Wenn es SPH gibt
  ldi rmp,High(RAMEND) ; Stapel-Init, MSB
  out SPH,rmp
  .endif
	ldi rmp,Low(RAMEND) ; Stapel-Init, LSB
	out SPL,rmp ; Init LSB stack pointer
  ; Relais-Ports auf Ausgang
  cbi PORTB,PORTB0 ; Relais 1 aus
  sbi DDRB,DDB0 ; PB0 als Ausgang
  cbi PORTB,PORTB1 ; Relais 2 aus
  sbi DDRB,DDB1 ; PB1 als Ausgang
  ; INT0-Portpin als Eingang
  cbi DDRB,DDB2 ; Pin als Eingang
  sbi PORTB,PORTB2 ; Mit Pull-Up-Widerstand
  ; LEDs und Siebensegment-Ausgaenge
  ldi rmp,0xC0 ; Alle LED-Ausgaenge aus, Pull-Up von PA7 und gruene LED an
  out PORTA,rmp ; auf die Ausgangstreiber
  ldi rmp,0x7F ; Alle LED-Ausgange als Ausgang, PA7 als Eingang
  out DDRA,rmp ; in Richtungsregister
  ; Z als Zeiger auf Tabelle inititiieren
  sbic PINA,PINA7 ; Siebensegment oder LED?
  rjmp LedInit ; LEDs gewaehlt
  ldi ZH,High(2*SiebenSegment+5) ; Z auf fuenftes Byte, MSB
  ldi ZL,Low(2*SiebenSegment+5) ; dto., LSB
  lpm rFuenf,Z+ ; der Fuenfer-Wert
  lpm rSechs,Z ; und der Sechser-Wert
  ldi ZH,High(2*SiebenSegment) ; Z auf 7-Segment-Tabelle, MSB
  ldi ZL,Low(2*SiebenSegment) ; dto., LSB
  rjmp LedAusgabe
LedInit:
  ldi ZH,High(2*SiebenLeds+5) ; Z auf fuenftes Byte, MSB
  ldi ZL,Low(2*SiebenLeds+5) ; dto., LSB
  lpm rFuenf,Z+ ; der Fuenfer-Wert
  lpm rSechs,Z ; und der Sechser-Wert
  ldi ZH,High(2*SiebenLeds) ; Z auf 7-Led-Tabelle, MSB
  ldi ZL,Low(2*SiebenLeds) ; dto., LSB
LedAusgabe:
  push ZH ; Sichern der Adresse, MSB
  push ZL ; dto., LSB
LedAnimation:
  lpm rmp,Z+ ; Lese Tabellenwert
  cpi rmp,0x01 ; Ende der Animation?
  breq LedAnimEnd ; Ja
  out PORTA,rmp ; Schreibe Wert in Port
  ldi rCntH,High(cAnim) ; Verzoegerungszaehler setzen, MSB
  ldi rCntL,Low(cAnim) ; dto., LSB
LedAnimWarten:
  sbiw rCntL,1 ; rCntH:rCntL abwaerts
  brne LedAnimWarten ; Weiter abwarten
  rjmp LedAnimation ; Noch nicht, weiter mit Tabelle
LedAnimEnd:
  pop ZL ; Wiederherstellen der Adresse, LSB
  pop ZH ; dito., MSB
  lpm rmp,Z+ ; Lese Byte vom Null-Zustand
  out PORTA,rmp ; Schreibe in Port A
  ; INT0 initiieren
  ldi rmp,(1<<ISC00)|(1<<SE) ; Interrupt bei High-Low und Low-High, Sleep-Modus Idle
  out MCUCR,rmp ; In Master Control
  ldi rmp,1<<INT0 ; INT0-Interrupt ein
  out GIMSK,rmp ; in INT-Maske
; Interrupt enable
	sei ; Enable interrupts
;
; **********************************
;    P R O G R A M   L O O P
; **********************************
;
Loop:
  sleep ; Schlafen legen
	rjmp loop ; Und wieder schlafen legen
;
; Sieben LEDs Tabelle
;   Bit 6 (Betriebsspannungsanzeige) und
;   Bit 7 (Jumper-Pull-Up ist immer Eins
SiebenLeds:
  .db 0xC0,0x81,0x82,0x84,0x88,0x90,0xA0,0xC0
  .db 0xA0,0x90,0x88,0x84,0x82,0x81,0x80,0x01
SiebenSegment:
;     --a--  PA0
;    |     |
;PA5 f     b PA1
;    |     |
;PA6  --g--
;    |     |
;PA4 e     c PA2
;    |     |
;     --d--  PA3
  .db 0b10111111,0b10000110 ; 0 und 1
  .db 0b11011011,0b11001111 ; 2 und 3
  .db 0b11100110,0b11101101 ; 4 und 5
  .db 0b11111101,0b11000000 ; 6 und Rueckkehr
  .db 0b10000001,0b10000010 ; a, b
  .db 0b10000100,0b10001000 ; c, d
  .db 0b10010000,0b10100000 ; e, f
  .db 0b11000000,0b00000001 ; g und Ende der Animation
;
; End of source code
;
; Copyright information
  .db "(C)2022 by Gerhard Schmidt  " ; Source code readable
  .db "C(2)20 2ybG reahdrS hcimtd  " ; Machine code format
;

  
©2022 by Gerhard Schmidt