Pfad: Home => AVR-Übersicht => Anwendungen => Langzeit-Timer => Asm-Quellcode   This page in english: Flag EN
DCF77-Empfang Anwendungen von
AVR-Einchip-Prozessoren AT90S, ATtiny, ATmega und ATxmega
Quellcode für Langzeit-Timer
Logo

Assembler-Quellcode für den Langzeit-Timer mit einem ATtiny13

Den Quellcode im Assembler-Format gibt es hier.

;
; *************************************************
; * Programmierbarer Langzeit-Timer               *
; * ATtiny13 mit einer rot/gruenen Duo-LED, v1.0  *
; * (C)2021 by http://www.avr-asm-tutorial.net    *
; *************************************************
;
.nolist
.include "tn13adef.inc" ; Definiere Devicetyp ATtiny13A
.list
;
; Arbeitsweise: Senkt die Helligkeit einer Duo-LED in
;   rot bis auf Null ab und dann innerhalb von 5 Minuten
;   mit ansteigender Helligkeit in gruen. Die Intervall-
;   dauer kann mit den drei Jumpern vorgewaehlt werden:
;     Jumper:
;       0) Kein Jumper: 30 Minuten
;       1) Addiert 30 Minuten
;       2) Addiert 60 Minuten
;       3) Addiert 120 Minuten.
;     Intervalldauern:
;       0) 30 Minuten (25 min. rot + 5 min. gruen)
;       1) 60 Minuten (55 min. rot + 5 min. gruen)
;       2) 90 Minuten (85 min. rot + 5 min. gruen)
;       3) 120 Minuten (115 min. rot + 5 min. gruen)
;       4) 150 Minuten (145 min. rot + 5 min. gruen)
;       5) 180 Minuten (175 min. rot + 5 min. gruen)
;       6) 210 Minuten (205 min. rot + 5 min. gruen)
;       7) 240 Minuten (235 min. rot + 5 min. gruen)
;
; **********************************
;        H A R D W A R E
; **********************************
;
; Typ: ATtiny13A, Packung: 8-pin-PDIP_SOIC
;
;            _________
;         1 /         |8
; Reset o--|RESET  VCC|--o +V
;   Sw3 o--|PB3    PB2|--o Sw1
;   Sw2 o--|PB4    PB1|--o Anode rot
;    0V o--|GND    PB0|--o Anode gruen
;        4 |__________|5
;
; **********************************
;  P O R T S   U N D   P I N S
; **********************************
;
.equ pOutP = PORTB ; Ausgabeport
.equ pOutD = DDRB ; Richtungsport
.equ pOutI = PINB ; Eingabeport
.equ bAnGnP = PORTB0 ; Anode gruen Ausgabepin
.equ bAnRdP = PORTB1 ; Anode rot Ausgabepin
.equ bAnGnD = DDB0 ; Anode gruen Richtungspin
.equ bAnRdD = DDB1 ; Anode rot Richtungspin
.equ bSw1 = PORTB2 ; Jumper 1 Pin
.equ bSw2 = PORTB3 ; Jumper 2 Pin
.equ bSw3 = PORTB4 ; Jumper 3 Pin
;
; **********************************
;     E I N S T E L L U N G E N
; **********************************
;
.equ clock = 1200000 ; Taktrate Default in Hz
.equ cTimeBase = 30 ; Zeitslot in Minuten
.equ cTimeGrn = 5 ; Zeit fuer Gruenphase in Minuten
.equ cPresc = 64 ; Vorteiler, kann 1, 8 oder 64 sein
;
; **********************************
;  F E S T  &  A B G E L E I T E T
; **********************************
;
.equ fPwm = ((clock + 128) / 256 + cPresc/2) / cPresc ; PWM-Frequenz
.equ tPwm = (1000000*256*cPresc+clock/2)/clock ; PWM-Zyklusdauer in ms
.equ fColorChange = 1000*fPwm / 256 ; Farbwechsel in mHz
.equ tColorChange = (256 * tPwm +500) / 1000 ; Farbwechselzeit in ms
.equ cCntBase = ((cTimeBase*60*clock+cPresc/2)/cPresc+32768)/65536 ; Zaehler des Intervalls
.equ cCntGrn = ((cTimeGrn*60*clock+cPresc/2)/cPresc+32768)/65536 ; Zaehler der Gruenphase
.equ cCntRed = cCntBase - cCntGrn ; Zaehler der Rotphase
;
.if (cCntBase==0)||(cCntRed==0)||(cCntGrn==0)
  .error "Zaehlerwert auf Null, Vorteiler wenn moeglich erniedrigen"
  .endif
  ;
; **********************************
;       R E G I S T E R
; **********************************
;
; frei: R0 bis R15
.def rmp = R16 ; Vielzweckregister
.def rDelayL = R17 ; Verzoegerungswert, LSB
.def rDelayH = R18 ; dto., MSB
.def rCmp = R19 ; Phasenzaehler Farbintensitaet
; frei: R20 bis R23
.def rCntL = R24 ; 16-Bit-Zaehler, LSB
.def rCntH = R25 ; dto., MSB
; frei: R27:R26 = X
; frei: R29:R28 = Y
; benutzt: R31:R30 = Z fuer Berechnung
;
; **********************************
;           S R A M
; **********************************
;
.dseg
.org SRAM_START
; Kein SRAM in Benutzung
;
; **********************************
;         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-Vektor
	reti ; INT0
	reti ; PCI0
	rjmp Tc0OvfIsr ; OVF0
	reti ; ERDY
	reti ; ACI
	reti ; OC0A
	reti ; OC0B
	reti ; WDT
	reti ; ADCC
;
; **********************************
;  I N T - S E R V I C E   R O U T .
; **********************************
;
; TC0 Ueberlauf Interrupt-Service-Routine
Tc0OvfIsr:
  sbiw rCntL,1 ; Verzoegerungszaehler abwaerts
  brne Tc0OvfIsrRet ; Zeit noch nicht vorbei
  ; Erhoehe Farb-Intensitaet
  inc rCmp ; Naechste Farbe
  out OCR0A,rCmp ; in Compare A
  out OCR0B,rCmp ; und Compare B
  brne Tc0OvfIsrSetCnt ; Farbe <> Null?
  ; Farbe = Null
  brts Tc0OvfIsrG2Ra ; Rot nach gruen
  ; Gruen nach Rot-Umschaltung
  ldi rmp,(1<<COM0B1)|(1<<COM0B0)|(1<<WGM01)|(1<<WGM00) ; Fast PWM, OC0B invertiert
  out TCCR0A,rmp ; In TC0-Kontrollregister A
  set ; Naechste Umschaltung gruen nach rot
  ldi rDelayH,High(cCntRed) ; Beginne Zahlerwert mit Rotphasenwert, MSB
  ldi rDelayL,Low(cCntRed) ; dto., LSB
  ldi ZH,High(cCntBase) ; Lade Intervalldauer, MSB
  ldi ZL,Low(cCntBase) ; dto., LSB
  in rmp,pOutI ; Lese Jumper
  sbrc rmp,2 ; Jumper an Pin 2 gesetzt?
  rjmp Tc0OvfIsrSw2 ; Nein
  add rDelayL,ZL ; Addiere Intervalldauer, LSB
  adc rDelayH,ZH ; dto., MSB
  brcs Tc0OvfIsrClrRd ; Ueberlauf beim Addieren
Tc0OvfIsrSw2:
  lsl ZL ; Multipliziere Basisdauer mit 2, LSB
  rol ZH ; dto., MSB
  sbrc rmp,3 ; Jumper an Pin 3 gesetzt?
  rjmp Tc0OvfIsrSw3 ; nein
  add rDelayL,ZL ; Addiere zweifache Basisdauer, LSB
  adc rDelayH,ZH ; dto., MSB
  brcs Tc0OvfIsrClrRd ; Ueberlauf beim Addieren
Tc0OvfIsrSw3:
  lsl ZL ; Multipliziere Basisdauer mit 4, LSB
  rol ZH ; dto., MSB
  sbrc rmp,4 ; Jumper an Pin 4 gesetzt?
  rjmp Tc0OvfIsrSw4 ; Nein
  add rDelayL,ZL ; Addiere vierfache Basisdauer, LSB 
  adc rDelayH,ZH ; dto., MSB
  brcc Tc0OvfIsrSw4 ; Kein Ueberlauf
Tc0OvfIsrClrRd:
  clr rDelayH ; Ueberlauf beim Addieren, setze Hoechstwert, MSB
  clr rDelayL ; dto., LSB
Tc0OvfIsrSw4:
  cbi pOutP,bAnGnP ; Gruene Anode auf Low
  rjmp Tc0OvfIsrSetCnt ; Starte Zaehler
Tc0OvfIsrG2Ra:
  ; Schalte von rot auf gruen
  ldi rmp,(1<<COM0A1)|(1<<WGM01)|(1<<WGM00) ; Fast PWM, OC0A nicht-invertiert
  out TCCR0A,rmp ; In TC0-Kontrollregister A
  clt ; Naechste Umschaltung auf rot
  ldi rDelayH,High(cCntGrn) ; Dauerzaehler Gruenphase, MSB
  ldi rDelayL,Low(cCntGrn) ; dto., LSB
  cbi pOutP,bAnRdP ; Rote Anode auf Low
Tc0OvfIsrSetCnt:
  mov rCntH,rDelayH ; Lade Verzoegerungszaehler neu, MSB
  mov rCntL,rDelayL ; dto., LSB
Tc0OvfIsrRet:
  reti ; Fertig
;
; *************************************
;  H A U P T P R O G R A M M   I N I T
; *************************************
;
Main:
  ldi rmp,Low(RAMEND) ; Stapel einrichten fuer Interrupt
  out SPL,rmp ; Init LSB Stapelzeiger
  ; Init Portpins
  sbi pOutD,bAnGnD ; Richtung Ausgang, gruene LED-Anode
  sbi pOutD,bAnRdD ; dto., rote LED-Anode
  sbi pOutP,bSw1 ; Pull-Up-Widerstand hoch, Jumper 1
  sbi pOutP,bSw2 ; Pull-Up-Widerstand hoch, Jumper 2
  sbi pOutP,bSw3 ; Pull-Up-Widerstand hoch, Jumper 3
  ; Sete erste Verzoegerung auf Minimum
  ldi rDelayH,0 ; MSB
  ldi rDelayL,1 ; dto., LSB
  ldi rCntH,0 ; Dito Verzoegerung, MSB
  ldi rCntL,1 ; dto., LSB
  clt ; Starte mit roter LED
  ; Init TC0 im Fast-PWM-Modus
  ldi rCmp,0xFF ; Start mit der hoechsten PWM-Stufe
  out OCR0A,rCmp ; und in den Comparewert A
  out OCR0B,rCmp ; dto., B
  ldi rmp,(1<<WGM01)|(1<<WGM00) ; Fast-PWM-Modus, ohne OC-Pins
  out TCCR0A,rmp ; in TC0-Kontrollregister A
  ; Setze Vorteilerwert
.if cPresc == 1
    ldi rmp,(1<<CS00) ; Prescaler = 1
  .endif
.if cPresc == 8
    ldi rmp,1<<CS01 ; Prescaler = 8
  .endif
.if cPresc == 64
    ldi rmp,(1<<CS01)|(1<<CS00) ; Prescaler = 64
  .endif
  out TCCR0B,rmp ; In TC0-Kontrollregister B
  ldi rmp,1<<TOIE0 ; Enable Ueberlauf-Interrupt
  out TIMSK0,rmp
; Schlafmodus enable
  ldi rmp,1<<SE
  out MCUCR,rmp
	sei ; Enable Interrupts
;
; **********************************
;  P R O G R A M M S C H L E I F E
; **********************************
;
Loop:
  sleep ; Schlafen legen
  nop ; Aufgewacht
	rjmp loop ; Wieder schlafen legen
;
; Ende Quellcode
;
; Copyright information
 .db "(C)2021 by Gerhard Schmidt  " ; Quellcode lesbar
 .db "C(2)20 1ybG reahdrS hcimtd  " ; Machinencode lesbar
;



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