Path: Home => AVR overview => Applications => DCF77 receivers => AM rectifier => Source code   Diese Seite in Deutsch: Flag DE
DCF77 receiver logo Applications of
AVR single chip controllers AT90S, ATtiny, ATmega and ATxmega
Source code for the DCF77 AM rectifier with ATtiny25
Logo

7.3 Source code for the DCF77 AM rectifier with ATtiny25

The original source code for the ATtiny25 rectifier is here. This is only a HTML formatted listing.

;
; ******************************
; * AM rectifier with ATtiny25 *
; * (C)2020 by DG4FAC          *
; ******************************
;
.nolist
.include "tn25def.inc" ; Define device ATtiny25
.list
;
; **********************************
;       P R O P E R T I E S
; **********************************
;
.equ Duoled = 1 ; 1 if Duo-LED attached
.if DuoLed == 1
  .equ DuoledSpeed = 2 ; Speed factor for Duo-LED
    ; 1: 30.5 Hz
    ; 2: 122.1 Hz
    ; 3: 488 Hz
    ; 4: 3.91 kHz
    ; 5: 31.25 kHz (use this when simulating)
  ; Test the Duo-LED only
  .equ LedOnly = 0 ; Display red/green only
  .if LedOnly == 1 ; Define colors
     ; The intensities of the LED colors
     .equ cLedOnlyColor = 0x20 ; Green=0x20, red=0xC0
	 .endif 
  .endif
.equ MaxAverage = 8 ; Number of maxima to be averaged, 2..128
.equ cMaxCnt = 32 ; Count of measurements for detecting maximum
;
; Error checking
.if (MaxAverage<2) || (MaxAverage>128)
  .error "Illegal MaxAverage value selected!"
  .endif
.if (2<<(LOG2(MaxAverage)-1)) != MaxAverage
  .error "MaxAverage has to be a power of 2!"
  .endif
.if (MaxAverage*cMaxCnt)>1024
  .message "Warning: Averaging too long for DCF77!"
  .endif
.if cMaxCnt<16
  .message "Warning: Too few countings for max detection!"
  .endif
.if cMaxCnt>255
  .error "Too many counting events for max detection!"
  .endif
.if (DuoLedSpeed<1)||(DuoLedSpeed>5)
  .error "Wrong DuoLedSpeed setting!"
  .endif
;
; **********************************
;        H A R D W A R E
; **********************************
;
; Device: ATtiny25, Package: 8-pin-PDIP_SOIC
;
;             _________
;          1 /         |8
;  RESET o--|RESET  VCC|--o VCC, +5V
;  AM-IN o--|PB3    PB2|--o SCK
; DC-OUT o--|PB4    PB1|--o Red Anode, MISO
; 0V GND o--|GND    PB0|--o Green Anode, MOSI
;         4 |__________|5
;
;
; **********************************
;  P O R T S   A N D   P I N S
; **********************************
;
.equ pOutLedD = DDRB ; Portregister of LED
.if DuoLed==1
  .equ bOutLedD = (1<<PORTB0)|(1<<PORTB1)|(1<<PORTB4) ; DC output pin and Duo-Led
  .else
  .equ bOutLedD = 1<< PORTB4 ; Only the DC output for PWM
  .endif
;
; **********************************
;   A D J U S T A B L E   C O N S T
; **********************************
;
;
; **********************************
;  F I X  &  D E R I V.  C O N S T
; **********************************
;
.set cTc0Presc = (1<<CS02)|(1<<CS00)
.if DuoLedSpeed == 2
  .set cTc0Presc = 1<<CS02
  .endif
.if DuoLedSpeed == 3
  .set cTc0Presc = (1<<CS01)|(1<<CS00)
  .endif
.if DuoLedSpeed == 4
  .set cTc0Presc = 1<<CS01
  .endif
.if DuoLedSpeed == 5
  .set cTc0Presc = 1<<CS00
  .endif
;
; **********************************
;        T I M I N G
; **********************************
;
; Clock = 8000000
; ADC prescaler = 2
; ADC conversion steps = 13
; ADC conversion frequency = 307.69 kHz
; ADC conversion time = 3.25 us
; Measurements per sine wave
;   at 77.5 kHz = 3.97
;   at 32.768 kHz = 9.39
;
; Maximum detection
;   Number of measurements = 32
;   Sampling time = 832 us
;   Sine waves measured
;     at 77.5 kHz = 64.48
;     at 32.768 kHz = 27.28
;
; Averaging maximums
;   Averaging = 16
;   Averaging time = 13.82 ms
;
; **********************************
;       R E G I S T E R S
; **********************************
;
; free: R0 to R8
.def rAvgL = R9 ; Average sum, LSB
.def rAvgH = R10 ; dto., MSB
.def rInL = R11 ; Maximum detected, LSB
.def rInH = R12 ; dto., MSB
.def rMaxL = R13 ; Maximum LSB
.def rMaxH = R14 ; dto., MSB
.def rSreg = R15 ; Save/Restore status port
.def rmp = R16 ; Define multipurpose register
.def rMaxCnt = R17 ; Maximum counter
.def rAvgCnt = R18 ; Average counter
.def rAdcL = R19 ; ADC value read, LSB
.def rAdcH = R20 ; dto., MSB
; free: R22 to R31
;
; **********************************
;           S R A M
; **********************************
;
.dseg
.org SRAM_START
; No SRAM used (only for stack)
;
; **********************************
;         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 ; OC1A
	reti ; OVF1
	reti ; OVF0
	reti ; ERDY
	reti ; ACI
	rjmp AdccIsr ; ADCC interrupt
	reti ; OC1B
	reti ; OC0A
	reti ; OC0B
	reti ; WDT
	reti ; USI_START
	reti ; USI_OVF
;
; **********************************
;  I N T - S E R V I C E   R O U T .
; **********************************
;
AdccIsr:
  in rSreg,SREG ; Save SREG
  in rAdcL,ADCL ; Read ADC LSB
  in rAdcH,ADCH ; dto., MSB
  subi rAdcH,0x02 ;
  brcc AdcIsr1 ; No carry
  neg rAdcL ; Negative LSB
  com rAdcH ; dto., MSB
AdcIsr1:
  cp rAdcL,rMaxL ; Compare with maximum
  cpc rAdcH,rMaxH
  brcs AdcIsr2 ; Smaller
  mov rMaxL,rAdcL
  mov rMaxH,rAdcH
AdcIsr2:
  dec rMaxCnt ; Count measurements
  brne AdcIsr3
  ldi rMaxCnt,cMaxCnt ; Restart counter
  mov rInL,rMaxL ; Copy maximum, LSB
  mov rInH,rMaxH ; dto., MSB
  clr rMaxL ; Restart maximum, LSB
  clr rMaxH ; dto., MSB
  out SREG,rSreg ; Restore SREG
  set ; Set input flag
  reti
AdcIsr3:
  out SREG,rSreg ; Restore SREG
  reti
;
; **********************************
;  M A I N   P R O G R A M   I N I T
; **********************************
;
Main:
.ifdef SPH ; If an ATtiny85 is used
  ldi rmp,High(RAMEND)
  out SPH,rmp ; Init MSB stack pointer
  .endif
	ldi rmp,Low(RAMEND)
	out SPL,rmp ; Init LSB stack pointer
; Increase clock to 8 MHz
  ldi rmp,1<<CLKPCE ; Enable CLKPR change
  out CLKPR,rmp ; in CLKPR
  clr rmp ; No prescaler
  out CLKPR,rmp ; in CLKPR
; Start values
  clt ; Input flag off
  clr rMaxL ; Maximum clear, LSB
  clr rMaxH ; dto., MSB
  clr rMaxCnt ; One full cycle max detection
  ldi rAvgCnt,MaxAverage ; Average over values
; Output pins as output
  ldi rmp,bOutLedD ; Output pins as output
  out pOutLedD,rmp ; in direction port
; Start Duo-LED
.if DuoLed == 1
  ldi rmp,0x80 ; Set both compare values to zero (LED half)
  out OCR0A,rmp ; Compare A
  out OCR0B,rmp ; Compare B
  ldi rmp,(1<<COM0A1)|(1<<COM0B1)|(1<<COM0B0)|(1<<WGM01)|(1<<WGM00) ; Clear OCR on match, Fast PWM mode
  out TCCR0A,rmp ; To timer control port A
  ldi rmp,cTc0Presc ; Set prescaler
  out TCCR0B,rmp ; in timer control port
  .endif
; Start PWM on TC1
  clr rmp ; Compare A and B to zero
  out OCR1A,rmp
  out OCR1B,rmp ; To compare port B
  ldi rmp,0xFF ; 8-bit PWM
  out OCR1C,rmp ; in compare port C
  ldi rmp,(1<<PWM1B)|(1<<COM1B1) ; PWM on OC1B
  out GTCCR,rmp ; in control port GTCCR
  ldi rmp,(1<<CS10) ; Prescaler=1, resolution in OCR1C
  out TCCR1,rmp ; in control port 1
; Init ADC
  ldi rmp,(1<<MUX0)|(1<<MUX1) ; Channel ADC3
  out ADMUX,rmp ; To ADC mux
  ldi rmp,0 ; ADC free running mode
  out ADCSRB,rmp ; in control port B
  ldi rmp,(1<<ADEN)|(1<<ADSC)|(1<<ADATE)|(1<<ADIE)
  out ADCSRA,rmp ; Start first conversion in control port A
; Enable interrupts
	sei ; Enable interrupts
;
; **********************************
;    P R O G R A M   L O O P
; **********************************
;
Loop:
  brtc Loop ; Input bit not set
;
; Input the next maximum
Input:
  clt ; Clear input flag
.if (DuoLed==1)&&(LedOnly==1)
  ldi rmp,cLedOnlyColor ; Set color
  out OCR0A,rmp
  out OCR0B,rmp
  .else
  add rAvgL,rInL ; Add result, LSB
  adc rAvgH,rInH ; dto., MSB
  dec rAvgCnt ; Decrease counter
  brne Loop ; If not zero, continue
   ; Calculate average
  ldi rmp,LOG2(MaxAverage)+1
Input0:
  lsr rAvgH ; Divide average by 2
  ror rAvgL
  dec rmp ; Count down
  brne Input0 ; Continue dividing
; Set PWM value
  out OCR1B,rAvgL ; Set PWM compare B
  .if DuoLed==1
    out OCR0A,rAvgL
    out OCR0B,rAvgL
    .endif ; 
  .endif
InputOut:
  ldi rAvgCnt,MaxAverage ; Restart counter
  clr rAvgL ; Clear average sum
  clr rAvgH
  rjmp Loop
;
; End of source code
;
; (Add Copyright information here, e.g.
; .db "(C)2020 by Gerhard Schmidt  " ; Source code readable
; .db "C(2)20 0ybG reahdrS hcimtd  " ; Machine code format
;



To the top of that page

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