Pfad: Home => AVR-DE => Anwendungen => Puppenhaus tn13 => Assembler Code
Puppenhaus-Beleuchtung klein AVR-Anwendungen

Puppenhausbeleuchtung mit ATtiny13
Assembler Quellcode Puppenhausleuchte
Logo

Assembler-Quellcode für die Puppenhausleuchte

Die Originalsoftware im asm-Format gibt es hier.

;
; *********************************
; * Puppenhausleuchte ATtiny13    *
; * Version 1 Januar 2019         *
; * (C)2019 avr-asm-tutorial.net  *
; *********************************
;
.nolist
.include "tn13adef.inc" ; Define device ATtiny13A
.list
;
; **********************************
;         D E B U G
; **********************************
;
.equ Yes = 1
.equ No = 0
;
; Do not alter PWM value
.equ Debug_pwm = No
;
; Only trim and opto ADC debugging
.equ Debug_trim = Yes
.equ Debug_opto = No
;
; Simulate the first value on start-up
.equ cTrim1 = 64*1023 ; Sum value trimmer
.equ cOpto1 = 64*512 ; Sum value fototransistor
;
; **********************************
;        H A R D W A R E
; **********************************
;
; Device: ATtiny13A, Package: 8-pin-PDIP_SOIC
;
;           _________
;        1 /         |8
;  Res o--|RESET  VCC|--o +5V
; Foto o--|PB3    PB2|--o
;  Pot o--|PB4    PB1|--o
;   0V o--|GND    PB0|--o LEDs
;       4 |__________|5
;
;
; **********************************
;  P O R T S   A N D   P I N S
; **********************************
;
.equ pLedO = PORTB ; Led output port
.equ pLedD = DDRB ; Led direction port
.equ bLedO = PORTB0 ; Led output portpin
.equ bLedD = DDB0 ; Led direction portpin
;
; **********************************
;   A D J U S T A B L E   C O N S T
; **********************************
;
.equ clock=1200000 ; Define clock frequency
.equ cLedMin = 10 ; Minimum light intensity
;
; **********************************
;  F I X  &  D E R I V.  C O N S T
; **********************************
;
.equ cTc0Clk = clock / 256 ; Define from clock
;
;
; **********************************
;           T I M I N G
; **********************************
;
; LED-PWM:
;  Clock frequency  = 1,200,000 Hz
;  Prescaler        =        64
;  8-Bit PWM        =       256
;  PWM-Frequency    =        73.2 Hz
;  PWM cycle        =        13.65 ms
;
; AD conversion:
;  AD clock prescaler   = 128
;  AD conversion cycles =  13
;  AD summation         =  64
;  AD channels          =   2
;  Complete measurement =   5.63 Hz
;  Complete cycle       = 177 ms
;  Number of PWM cycles =  13.0
;
; Sleep share       = 99.1%
;
; **********************************
;       R E G I S T E R S
; **********************************
;
; free: R0 to R11
.def rAdcA = R12 ; Channel A MSB
.def rAdcL = R13 ; AD summation, LSB
.def rAdcH = R14 ; dto., MSB
.def rSreg = R15 ; Save/Restore status port
.def rmp = R16 ; Define multipurpose register
.def rimp = R17 ; Multipurpose inside ints
.def rFlag = R18 ; Flag register
  .equ bAdcCc = 0 ; ADC cycle complete
  .equ bAdcCh = 1 ; ADC cycle channel
.def rAdcCtr = R19 ; ADC measurement counter
; free: R20 to R29
; used: Z = R31:R30 for multiplication
;
; **********************************
;           S R A M
; **********************************
;
.dseg
.org SRAM_START
sLabel1:
.byte 16 ; Reserve 16 bytes
;
; **********************************
;         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
	reti ; OVF0
	reti ; ERDY
	reti ; ACI
	reti ; OC0A
	reti ; OC0B
	reti ; WDT
	rjmp AdcIsr ; ADCC
;
; **********************************
;  I N T - S E R V I C E   R O U T .
; **********************************
;
; AD conversion complete interrupt
AdcIsr:
  in rSreg,SREG ; Save SREG
  in rimp,ADCL ; Read LSB conversion result
  add rAdcL,rimp ; Add LSB to sum
  in rimp,ADCH ; dto., MSB
  adc rAdcH,rimp ; Add MSB to sum
  dec rAdcCtr ; Decrease counter
  brne AdcIsr1 ; Not zero
  ; ADC measurement counter at zero
  sbr rFlag,1<<bAdcCc ; Set conversion complete flag
  out SREG,rSreg ; Restore SREG
  reti
AdcIsr1:
  ldi rimp,(1<<ADEN)|(1<<ADSC)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0) ; Restart ADC
  out ADCSRA,rimp ; in control port A
  out SREG,rSreg ; Restore SREG
  reti
;
; **********************************
;  M A I N   P R O G R A M   I N I T
; **********************************
;
Main:
	ldi rmp,Low(RAMEND)
	out SPL,rmp ; Init LSB stack pointer
; Init the LED output port
  cbi pLedO,bLedO ; LEDs off
  sbi pLedD,bLedD ; LED pin = output
; Init Timer TC0 as PWM
  ldi rmp,0xff ; Half PWM
  out OCR0A,rmp
  ldi rmp,(1<<COM0A1)|(1<<WGM01)|(1<<WGM00) ; Fast PWM
  out TCCR0A,rmp ; To TC0 control port A
  ldi rmp,(1<<CS01)|(1<<CS00) ; Prescaler = 64
  out TCCR0B,rmp ; To TC0 control port B
; Start Adc
  ldi rmp,High(cTrim1) ; Simulate trimmer value
  mov rAdcA,rmp
  ldi rmp,High(cOpto1) ; Simulate fototransistor value
  mov rAdcH,rmp
  sbr rFlag,1<<bAdcCh ; Force multiplication
  rcall AdcCc ; Start ADC cycle
; Init Sleep and interrupts
  ldi rmp,1<<SE ; Sleep enable
  out MCUCR,rmp ; in Master control port
	sei ; Enable interrupts
;
; **********************************
;    P R O G R A M   L O O P
; **********************************
;
Loop:
  sleep ; Go to sleep
  nop ; Wake up by ADC int
  sbrc rFlag,bAdcCc ; Conversion complete flag?
  rcall AdcCc ; Call conversion complete
  rjmp Loop ; and return to sleep
;
; ADC cycle complete
AdcCc:
  cbr rFlag,1<<bAdcCc
  sbrc rFlag,bAdcCh ; Next channel?
  rjmp AdcCcCalc ; Channels complete, calculate
  sbr rFlag,1<<bAdcCh ; Set next channel
  .if Debug_trim == Yes
    out OCR0A,rAdcH ; Write result to PWM
	.endif
  mov rAdcA,rAdcH ; Copy MSB result
  ldi rmp,(1<<MUX1)|(1<<MUX0) ; Measure channel ADC3
  out ADMUX,rmp
  rjmp AdcCcRestart
AdcCcCalc:
  ; End of second cycle, calculate new PWM value
  .if Debug_opto == Yes
    out OCR0A,rAdcH
	.endif
  mov rmp,rAdcH ; Copy MSB
  neg rmp ; Fototransistor input, difference to 256
  cpi rmp,cLedMin ; Less than minimum light?
  brcc AdcCcCalc1 ; No
  ldi rmp,cLedMin ; Set to minimum light
AdcCcCalc1:
  clr ZL ; Clear multiplication result, LSB
  clr ZH ; dto., MSB
  mov rAdcL,rAdcH ; MSB to LSB
  clr rAdcH ; MSB = 0
AdcCcCalc2:
  tst rmp ; End of multiplication?
  breq AdcCcCalc4
  lsr rmp ; Next bit
  brcc AdcCcCalc3 ; 0, do not add
  add ZL,rAdcL ; Add LSB
  adc ZH,rAdcH ; and MSB
AdcCcCalc3:
  lsl rAdcL ; Multiply by 2, LSB
  rol rAdcH ; dto., MSB
  rjmp AdcCcCalc2 ; Continue multiplication
AdcCcCalc4:
  .if (Debug_pwm != Yes) && (Debug_trim != Yes) && (Debug_opto != Yes)
    out OCR0A,ZH ; Set new PWM value to MSB result
	.endif
  cbr rFlag,1<<bAdcCh
  ldi rmp,(1<<MUX1) ; Measure channel ADC2
  out ADMUX,rmp
AdcCcRestart:
  clr rAdcL ; Clear sum, LSB
  clr rAdcH ; dto., MSB
  ldi rAdcCtr,64 ; Start next 64 measurements
  ldi rmp,(1<<ADEN)|(1<<ADSC)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0) ; Restart ADC
  out ADCSRA,rmp ; in control port A
  ret
;
; End of source code
;



Lob, Tadel, Fehlermeldungen, Genöle und Geschimpfe oder Spam bitte über das Kommentarformular an mich.

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