Announcement

Collapse
No announcement yet.

IB Metal Detector Project, Part 26

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • IB Metal Detector Project, Part 26

    More code. This is the A/D routine and the 16 bit median filter. Together with the timer 2 interrupt these make up the high speed part of the detector code. The timer 2 interrupt occurs 26,400 times per second. It calls the A/D routine 8800 times per second, and it in turn calls the median filter 4400 times per second. The timer 2 interrupt also calls count2200 2200 times per second, but the only thing it does at that rate is update a counter. Count2200 does other things at 60 or 30 times per second.

    Robert Hoolko

    AD: ; Read A/D converter, filter, and accumulate data.
    ; Enter with address of data struct in Z
    ; Flag T determines whether this sample is added to or
    ; subtracted from the accumulator
    ; r16 r17 r18 are free

    sbi portd,4 ; debug, scope strobe
    in r16,ADCL ; get previous A/D results
    in r17,ADCH
    sbi ADCSR,4 ;Clear ADC INT SAFE
    sbi ADCSR,4 ;Clear ADC INT
    sbi ADCSR,6 ; start next conversion
    andi r17,00000011b ; mask off unused bits
    brtc ADaccum ; add or sub?
    st Z+,r16 ; save this sample for next time
    st Z,r17
    rjmp ADexit

    ADaccum:
    ld r18,Z+ ; sub saved sample from this one
    sub r16,r18
    ld r18,Z+
    sbc r17,r18
    lds r18,debug ; debug flags
    sbrc r18,0 ; debug, skip if no flag
    rcall putcirc ; debug,
    lds r18,fflag ; filter flag
    sbrc r18,1 ; skip if flag clear
    adiw ZL,4 ; mfilt does this
    sbrs r18,1 ; skip if flag set
    rcall mfilt16 ; median filter
    ld r18,Z ; accumulate data as 24 bits
    add r18,r16 ; low byte
    st Z+,r18
    ld r18,Z
    adc r18,r17 ; middle byte
    st Z+,r18
    clr r16 ; extend sign
    sbrc r17,7 ; test sign
    ser r16
    ld r18,Z
    adc r18,r16 ; high byte
    st Z+,r18 ;

    ADexit:
    cbi portd,4 ; debug, scope strobe
    ret

    ;************************************************* **********************
    ;*
    ;* "mfilt16"
    ;* 3 point median filter for 16 bit signed data
    ;*
    ;* Number of words :
    ;* Number of cycles : 72 + 12 in modified version
    ;* Low registers used :0
    ;* High registers used :7 (r16-r22)
    ;* Pointers used :Y,Z
    ;*
    ;************************************************* **********************

    ;***** Subroutine Register Variables

    #define al r16
    #define ah r17
    #define bl r18
    #define bh r19
    #define cl r20
    #define ch r21
    #define temp r22
    #define mflag r28

    mfilt16:
    ;***** Enter with new data in A (r16,r17)
    ; and address of filter data in Z
    ; Exit with filtered data in r16,r17
    ; and Z incremented by 4
    ; Instructions marked with * are a modification
    ; that allows 1 bit of noise through

    push YH
    push YL
    push r22
    push r21
    push r20
    push r19
    push r18
    clr mflag ; clear flags
    clr YH
    ld bl,Z ; get filter data b
    ldd bh,Z+1
    ldd cl,Z+2 ; get filter data c
    ldd ch,Z+3
    cp bl,al ; compare a and b
    cpc bh,ah
    brge bgea ;
    ori mflag,4 ; set if b is less than a
    bgea:
    cp al,cl
    cpc ah,ch ; compare c and a
    brge agec ;
    ori mflag,2 ; set if a is less than c
    agec:
    cp cl,bl
    cpc ch,bh ; compare b and c
    brge cgeb ;
    ori mflag,1 ; set if c is less than b
    cgeb:
    ldi temp,7 ;
    sbrc mflag,2 ; test msb of flag bits
    eor mflag,temp ; fold around 3
    breq alleq ; if 0, all were equal
    dec mflag ; else reduce 1,2,3 to 0,1,2
    alleq: add mflag,mflag ; compute offset to median, mflag is YL
    ori mflag,16 ; address of r16

    ; We do not need c any more
    ; Shift a and b to b and c
    ; We will need these the next time the filter is called

    st Z+,al ; store filter data b
    st Z+,ah
    st Z+,bl ; store filter data c
    st Z+,bh ;
    ld temp,Y ;*was there any noise?
    cp temp,al ;*
    ldd temp,Y+1 ;*
    cpc temp,ah ;*
    ld r16,Y+ ; get median
    ld r17,Y
    breq nonoise ;*no noise
    brlt posnoise ;*
    subi r16,1 ;*if neg noise, subtract 1 from median
    sbci r17,0 ;*
    rjmp nonoise ;*
    posnoise: ;*
    subi r16,-1 ;*if pos noise, add 1 to median
    sbci r17,-1 ;*
    nonoise: ;*
    pop r18
    pop r19
    pop r20
    pop r21
    pop r22
    pop YL
    pop YH
    ret

    ;************************************************* **************************

    ; Data

    #dseg
    ;struct
    Itemp: ds 2
    Imfilt: ds 4 ;must follow Itemp
    Iaccum: ds 3 ;must follow Imfilt

    ;struct
    Qtemp: ds 2
    Qmfilt: ds 4 ;must follow Qtemp
    Qaccum: ds 3 ;must follow Qmfilt

    #define IQhold 6
    #define IQair 9
    #define IQchan 12
    ;struct
    Idcmfilt: ds 6
    Ihold: ds 3
    Iair: ds 3
    Ichan: ds 1

    ;struct
    Qdcmfilt: ds 6
    Qhold: ds 3
    Qair: ds 3
    Qchan: ds 1

    ; struct
    ; The following data must be in pairs I,Q or cos,sin or x,y
    Idc: ds 3
    Qdc: ds 3
    calcos: ds 2
    calsin: ds 2
    #define NDELAY 11
    Xcal: ds 3 ;12 most recient samples
    Ycal: ds 3 ;12 most recient samples
    ds 6*NDELAY; x,y delay line
    XF: ds 3 ; filterd
    YF: ds 3
    Xcap: ds 3 ; captured
    Ycap: ds 3
    ; end of pairs

    c2200: ds 1
    c60: ds 1
    csec: ds 1
    flag60: ds 1
    fflag: ds 1
    debug: ds 1
    pw2: ds 1
    gndcos: ds 2
    gndsin: ds 2
    fthreshuf: ds 1
    fthresh: ds 3
    fthreshtc: ds 1
    coilon: ds 1
    coiloff: ds 1
    drvangle: ds 1
Working...
X