Zum Funktionstest schnell aufgebaut
Zitate:http://www.elektronik-labor.de/AVR/Filter.html
'negative pulse detector Pdet2.bas
'
'running average to establish Avgvalue, threshold and trigger
'Trigpulse when triggerd
'Ledpulse turned on 100 ms
'Ledindic turned on 10 sec
'1 ms sampling time
'
'***************************************************************************
'
' Pinout ATtiny13/ATtiny13V 8-PDIP/SOIC
'
' (PCINT5/RESET/ADC0/dW) PB5 VCC
' (PCINT3/CLKI/ADC3) PB3 PB2 (SCK/ADC1/T0/PCINT2)
' (PCINT4/ADC2) PB4 PB1 (MISO/AIN1/OC0B/INT0/PCINT1)
' GND PB0 (MOSI/AIN0/OC0A/PCINT0)
'
'***************************************************************************
' PB0 output pulse IRQ
' PB1 output Ledpulse, hi
' PB2 output Ledindic, hi
' PB4 output Trigpulse
' PB3 input ADC channel 3
'***************************************************************************
$regfile = "attiny13.dat"
$crystal = 1200000
'$crystal = 9600000
$hwstack = 8
$swstack = 8
$framesize = 4
Ipulse Alias Portb.0
Ledpulse Alias Portb.1
Ledindic Alias Portb.2
Trigpulse Alias Portb.4
Const C_value = 150 - 1 ' Compare Match IRQ 1 ms
' Const C_value = 189 - 1 Compare Match IRQ 10 ms, 53 x 189
' C_value = 94 for 5 ms w Presc 64
' C_value = 150 for 1 ms w Presc 8
Const Threshval = 8 'Threshold 12.5%
Dim Currentvalue As Word , Avgvalue As Word
Dim Trig As Word , Icnt As Word
Dim Dcnt As Byte , Alarmflag As Byte , Thresh As Byte
Portb = &B00000000
Ddrb = &B00010111
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Didr0.adc3d = 1
Start Adc
Config Timer0 = Timer , Prescale = 8
Ocr0a = C_value ' value for 1.2 MHz
Tccr0a = &B00000010 ' ctc
Timsk0.ocie0a = 1
On Oc0a Tim0_compa
Start Timer0
'CLKPR = &B10000000 'Clock Prescaler Change Enable
'CLKPR = &B00000000 'Clock Division Factor=0, 9.6MHz
Acsr.acd = 0 ' switch off analog comparator
'Open "comb.4:38400,8,n,1,INVERTED" For Output As #1
Enable Interrupts
Avgvalue = 1000
Do
If Icnt > 10000 Then
Ledindic = 0 'show longer '
Icnt = 0
End If
Loop
'***************************************************************************
'Tim0_compa Interrupt 1 ms
'***************************************************************************
Tim0_compa: '1 ms
Ipulse = 1
Incr Icnt
Currentvalue = Getadc(3)
Avgvalue = Avgvalue * 15 ' (Avgvalue*15 + Currentvalue)/16
Avgvalue = Avgvalue + Currentvalue
Shift Avgvalue , Right , 4 'running average
Thresh = Avgvalue / Threshval 'Threshold %
Trig = Avgvalue - Thresh
If Currentvalue < Trig Then
Alarmflag = 1
Trigpulse = 1 'pulse detected
Else
Trigpulse = 0
End If
If Alarmflag = 1 Then 'sw monoflop
Ledpulse = 1 ' Led on
Ledindic = 1
Incr Dcnt
If Dcnt > 99 Then 'reset sw monoflop
Ledpulse = 0
Alarmflag = 0
Dcnt = 0
End If
End If 'if Alarmflag = 1
Ipulse = 0
Return
End
'Motion detector with LDR or BPW34 MotDet2.bas
'
'running average to establish Avglight, threshold and trigger
'Ledalarm turned on 100 ms
'Lednight turned on when low light
'10 ms sampling time
'
'+5V -LDR- PB3 -10k- -GND
'
'***************************************************************************
'
' Pinout ATtiny13/ATtiny13V 8-PDIP/SOIC
'
' (PCINT5/RESET/ADC0/dW) PB5 VCC
' (PCINT3/CLKI/ADC3) PB3 PB2 (SCK/ADC1/T0/PCINT2)
' (PCINT4/ADC2) PB4 PB1 (MISO/AIN1/OC0B/INT0/PCINT1)
' GND PB0 (MOSI/AIN0/OC0A/PCINT0)
'
'***************************************************************************
' PB0 output Ipulse (calibrate 100 Hz)
' PB1 output Ledalarm hi
' PB2 output Lednight hi
' PB4 output COM1
' PB3 input ADC channel 3 LDR or BPW34
'***************************************************************************
$regfile = "attiny13.dat"
$crystal = 1200000
$hwstack = 8
$swstack = 8
$framesize = 4
Const C_value = 189 - 1 ' Compare Match IRQ 10 ms, 53 x 189
' C_value = 94 for 5 ms w Presc 64
' C_value = 150 for 1 ms w Presc 8
Const Threshval = 32 'Avglight divide by Threshval
Const Lolight = 40 'turn on Lednight
Const Hilight = 60 'turn off Lednight
Ipulse Alias Portb.0
Ledalarm Alias Portb.1
Lednight Alias Portb.2
Dim Currentlight As Word , Avglight As Word
Dim Thresh As Byte , Trig As Word
Dim Icnt As Byte , Dcnt As Byte , Alarmflag As Byte
Portb = &B00000000
Ddrb = &B00010111
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Didr0.adc3d = 1
Start Adc
Config Timer0 = Timer , Prescale = 64
Ocr0a = C_value ' value for 1.2 MHz
Tccr0a = &B00000010 ' ctc
Timsk0.ocie0a = 1
On Oc0a Tim0_compa
Start Timer0
Acsr.acd = 0 ' switch off analog comparator
Open "comb.4:9600,8,n,1,INVERTED" For Output As #1
Enable Interrupts
Avglight = 10
Do
If Icnt = 100 Then '1000 ms
Icnt = 0
Print #1 , Avglight
End If
Loop 'main loop
'***************************************************************************
'Tim0_compa Interrupt 10 ms IRQ needs 600us
'***************************************************************************
Tim0_compa: '10 ms
Ipulse = 1
Incr Icnt
Currentlight = Getadc(3)
Avglight = Avglight * 15 ' (Avglight*15 + Currentlight)/16
Avglight = Avglight + Currentlight
Shift Avglight , Right , 4 'running average
Thresh = Avglight / Threshval 'Threshold 3.1 %
Trig = Avglight - Thresh
If Currentlight < Trig Then
Alarmflag = 1 'Alarm on
End If
If Avglight < Lolight Then 'when low light turn on Led
Lednight = 1
Ledalarm = 0 ' Ledalarm off
Alarmflag = 0 'no alarm when dark
Elseif Avglight > Hilight Then 'turn off Led
Lednight = 0
End If
If Alarmflag = 1 Then 'sw monoflop 100 ms
Ledalarm = 1 ' Led on
Incr Dcnt
If Dcnt = 10 Then 'reset sw monoflop
Ledalarm = 0
Alarmflag = 0
Dcnt = 0
End If
End If 'if Alarmflag = 1
Ipulse = 0
Return
End
;***************************************************************************
; ATtiny15 Motion / Pulse Detector with LDR or BPW34
;
; RS232 9600 bps (inverted) sends: average+cr+lf
; binasc converts between 0,..,999
;
; running average to establish Avglight, threshold and trigger
; Ledpulse turned on 100 ms
; Lednight turned on when low light
; sampling 10ms @ 1.6 MHz
;
; GS July-2013
;
;
; This program is free software; you can redistribute it and/or
; modify it under the terms of the GNU General Public License.
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY;
;
;***************************************************************************
; The timing is adapted for 1.6 MHz
; this At15 reads OSCCAL config val=0x7E, must calibrate for RS232
;***************************************************************************
; ATtiny15 dip
; (RESET/ADC0) PB5 VCC
; (ADC3) PB4 PB2 (ADC1/SCK/T0/INT0)
; (ADC2) PB3 PB1 (AIN1/MISO/OC1A)
; GND PB0 (AIN0/AREF/MOSI)
;***************************************************************************
;
; PB4 input ADC3: + LDR PB4 10k GND
; PB3 output RS232
; PB2 output Lednight
; PB1 output Ledpulse
; PB0 output Ipulse
;
;***************************************************************************
.DEVICE ATtiny15 ;for gavrasm 3.3
;***************************************************************************
.equ Ipulse = PB0 ;
.equ Ledpulse = PB1 ;Ledpulse
.equ Lednight = PB2
.equ Txd = PB3
.equ compval = 250-1 ; 10 ms @ 1.6 MHz
.equ hilight = 60
.equ lolight = 40
;***************************************************************************
;Register Definitions
;***************************************************************************
; r0 - ASCII- Low
; r1 - ASCII- Mid
; r2 - ASCII- High
.def zero = r8
.def trg_L = r9
.def trg_H = r10
.def Adc_L = r11
.def Adc_H = r12
.def Avg_L = r13
.def Avg_H = r14
.def sr = r15
.def temp = r16
.def temp1 = r17
.def counter1 = r18
.def counter2 = r19
.def flag = r20
.def tmp_L = r22
.def tmp_H = r23
.def bitcnt = r24
.def Txbyte = r25 ;Data to be transmitted
.def delay = r26
;***************************************************************************
.cseg
.org 0
; ***** INTERRUPT VECTORS **************************************************
rjmp reset ; Reset-vector address 0000
reti ; INT0addr= 0x0001 External Interrupt 0
reti ; PCI0addr= 0x0002 External Interrupt Request 0
rjmp TIM1_cmp ; OC1addr = 0x0003 Timer/Counter1 Compare Match
reti ; OVF1addr= 0x0004 Timer/Counter1 Overflow
reti ; OVF0addr= 0x0005 Timer/Counter0 Overflow
reti ; ERDYaddr= 0x0006 EEPROM Ready
reti ; ACIaddr = 0x0007 Analog Comparator
reti ; ADCCaddr= 0x0008 ADC Conversion Ready
;***************************************************************************
; "TIM1_Cmp" - Timer/counter 1 Compare Match interrupt handler
;
; interrupts every 10 ms, calibrate, IRQ needs 120 us
;
;***************************************************************************
TIM1_cmp:
in sr,SREG ;Get Status reg
sbi PORTB,Ipulse ;
inc counter2 ; 1sec in main
sbi ADCSR, ADIF ; clear ADIF flag
sbi ADCSR, ADSC ; start conversion
TIM1_w1: ; read ADC value
sbis ADCSR, ADIF
rjmp TIM1_w1
; ADC read:
in Adc_L, ADCL ; low byte
in Adc_H, ADCH ; then high byte
mov tmp_L, Avg_L ; calculate (avg * 15 + adc)/16
mov tmp_H, Avg_H
lsl Avg_L ; * 2
rol Avg_H
lsl Avg_L ; * 4
rol Avg_H
lsl Avg_L ; * 6
rol Avg_H
lsl Avg_L ; * 16
rol Avg_H
sub Avg_L, tmp_L ; -1 => *15
sbc Avg_H, tmp_H
add Avg_L, Adc_L ; avg * 15 + adc
adc Avg_H, Adc_H
lsr Avg_H
ror Avg_L ; l/2
lsr Avg_H
ror Avg_L ; l/4
lsr Avg_H
ror Avg_L ; l/8
lsr Avg_H
ror Avg_L ; l/16
mov tmp_L, Avg_L ; calculate thresh = avg / 16
mov tmp_H, Avg_H
lsr tmp_H
ror tmp_L ; l/2
lsr tmp_H
ror tmp_L ; l/4
lsr tmp_H
ror tmp_L ; l/8
lsr tmp_H
ror tmp_L ; l/16
mov trg_L, Avg_L ; calculate trig
mov trg_H, Avg_H
sub trg_L, tmp_L ; avg - thresh
sbc trg_H, tmp_H
cp trg_L, Adc_L
cpc trg_H, Adc_H ; compare trig with avg
brlo TIM1_ck0
inc flag
TIM1_ck0:
cpi flag, 0
breq TIM1_ck1
sbi PORTB, Ledpulse
inc counter1
cpi counter1, 10 ;100ms
brne TIM1_ck1
clr counter1
clr flag
cbi PORTB, Ledpulse
TIM1_ck1:
ldi tmp_L, lolight ; check avglight
clr tmp_H
cp Avg_L, tmp_L
cpc Avg_H, tmp_H ; compare lolight with avg
brsh TIM1_ck2
sbi PORTB, Lednight
cbi PORTB, Ledpulse
TIM1_ck2:
ldi tmp_L, hilight ; check avglight
clr tmp_H
cp Avg_L, tmp_L
cpc Avg_H, tmp_H ; compare hilight with avg
brlo TIM1_ex
cbi PORTB, Lednight
TIM1_ex:
cbi PORTB, Ipulse ; off
out SREG,sr ;
reti ;
;***************************************************************************
;*
;* "putchar" mod GS for inverted
;*
;* This subroutine transmits the byte stored in the "Txbyte" register
;* The number of stop bits used is set with the sb constant
;*
;* Number of words :14 including return
;* Number of cycles :Depens on bit rate
;* Low registers used :None
;* High registers used :2 (bitcnt,Txbyte)
;* Pointers used :None
;*
;***************************************************************************
.equ sb =1 ;Number of stop bits (1, 2, ...)
.equ b =52 ;9600 bps @ 1.6 MHz 167-9 cycles delay
putchar: ldi bitcnt,9+sb ;1+8+sb (sb is # of stop bits)
com Txbyte ;Invert everything, direct
sec ;Start bit
putchar0: brcc putchar1 ;If carry set
sbi PORTB,TxD ; send a '0' 1
rjmp putchar2 ; else
putchar1: cbi PORTB,TxD ; send a '1' 0
nop
putchar2:
ldi delay,b ; no more nested subroutines in AT15
putdelay: dec delay ; 2 * delay
brne putdelay
lsr Txbyte ;Get next bit
dec bitcnt ;If not all bit sent
brne putchar0 ; send next
;else
ret ; return
;***************************************************************************
reset:
; writing calibration byte to OSCCAL Register.
ldi temp,0x7E ; config val
out OSCCAL,temp ; for the cpu clock
nop
nop
ldi temp,0b00000000
out PORTB,temp
ldi temp,0b00001111
out DDRB,temp
sbi AcsR, Acd ; Disable Comparator
; AD-Converter setup
; ADMUX: REFS1 REFS0 ADLAR – – MUX2 MUX1 MUX0
ldi temp, 0b00000011 ; ADC3 input=PB4, REFS0,1 =0 Vcc is RefVoltage, result 0 - 1023
out ADMUX, temp
; ADCSR: ADEN ADSC ADFR ADIF ADIE ADPS2 ADPS1 ADPS0
ldi temp,0b11010011 ; ADC initialise single conversion and prescaler 8:
out ADCSR, temp
; timer1 setup:
ldi temp, compval ; Timer/Counter 1 top count
out OCR1A,temp ; compare value
ldi temp,0b10001011 ; Timer/Counter 1 clocked at CK/64 = 40 us
out TCCR1,temp ;
ldi temp, 0b01000000 ; enable OCIE1A interrupt
out TIFR,temp ; clear pending Interrupt
out TIMSK,temp
sei ; enable interrupts
;***************************************************************************
Main:
cpi counter2, 100 ; 1sec
brne Main
clr counter2
mov tmp_L, Avg_L ; convert and send
mov tmp_H, Avg_H ; needs 5 ms
rcall binasc
mov Txbyte, r2
rcall putchar
mov Txbyte, r1
rcall putchar
mov Txbyte, r0
rcall putchar
ldi Txbyte, 13 ; cr lf
rcall putchar
ldi Txbyte, 10
rcall putchar
rjmp Main ; loop
; ----------------------------------------------
; Unterprogramm zur Konvertierung Binär (10 Bit)
; in ASCII (3 Zeichen)
; benutzt Register r0,r1,r2,r22,r23
; Eingang: r22 - Binärzahl low
; r23 - Binärzahl High
; Ausgang: r0 - ASCII-Zahl Low
; r1 - ASCII-Zahl Mid
; r2 - ASCII-Zahl High
; ----------------------------------------------
;
binasc: clr r0 ;0-Wert für 16-Bit Subtraktion
clr r2 ;ASCII-High löschen
bin010: mov r1,r22 ;Binärzahl zwischenspeichern L
subi r22,100 ;100 subtrahieren
sbc r23,r0 ;Übertrag subtrahieren
brcs bin020 ;war Zahl>99? nein -> weiter
inc r2 ;ASCII-High erhöhen
rjmp bin010 ;Schleife
bin020: mov r22,r1 ;letzten Binärwert L holen
clr r1 ;ASCII-Mid löschen
bin030: cpi r22,10 ;Wert>9?
brcs bin040 ;nein -> Rest auswerten
inc r1 ;sonst ASCII-Mid erhöhen
subi r22,10 ;Wert um 10 vermindern
rjmp bin030 ;Schleife
bin040: mov r0,r22 ;Rest in ASCII-Low legen
ldi r23,0x30 ;Offset zur ASCII-Wandlung
or r0,r23 ;Ergebnis in ASCII wandeln
or r1,r23
or r2,r23
ret