Pfad: Home => AVR-DE => Anwendungen => DCF77-Empfänger => AM-Gleichrichter => Quellcode   This page in English: Flag EN
DCF77 receiver logo Anwendungen von
AVR-Einchip-Mikrocontrollern AT90S, ATtiny, ATmega und ATxmega
Quellcode für den DCF77 AM-Gleichrichter mit ATtiny25
Logo

7.3 Quellcode für den DCF77 AM-Gleichrichter mit ATtiny25

Der Original-Quellcode für den ATtiny25-Gleichrichter ist hier. Dies ist nur die HTML-formatierte Version.

;
; ******************************
; * 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
;



An den Seitenanfang

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