Ultrasonic Driver Assembly Yardım?

Başlatan mas, 10 Aralık 2012, 01:11:35

mas

Merhaba arkadaşlar. aşağıdaki kod üzerinde bir kaç değişiklik yapmam gerekiyor. Kısaca konudan bahsedeyim. şu linkteki cihazı yapıp çalıştırdım.

http://www.siliconchip.com.au/cms/A_112107/article.html



cihaz sorunsuz çalışıyor ama benim yapmak istediğim değişken frekansları sabit 40 khz civarında tutup transdüser den devamlı ultrasonik tirreşim almak.
program üzerinde sequence yazan kısımdaki tanımlamaların hepsini D'213' şeklinde değiştirdim. cihaz artık benim istediğim gibi sadece 40 khz civarında bir sinyal üretiyor ancak bu sinyaller kesik kesik yani saniyede 2 kez vuruş yapıyor. ben bunun devamlı olmasını istiyorum. sürekli kesintisiz 40 khz. kısaca elimdeki devreyi 50 watt lık transdüseri sürecek bir devreye dönüştürmem gerekiyor. assembly den de pek anladığım söylenemez. programdaki nop komutlarını silerek bir deneme daha yaptım bu seferde sinyal tamamen kayboldu ama trafonun çalıştığına dair çıt çıt sesleri geliyordu. orjinal kod aşağıda hangi satırları silmem veya değiştirmem gerekiyor? şimdiden teşekkürler..



; Ultrasonic driver for anti fouling of boats


   ERRORLEVEL -302
   ERRORLEVEL -306

   list P=12F675
   #include P12F675.inc

;Program Configuration Register
      __CONFIG    _CPD_OFF & _CP_OFF & _BODEN_OFF& _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _HS_OSC   

; bank 0 RAM

STORE1         equ   H'22'   ; delay counter   
STORE2         equ   H'23'   ; delay counter
STORE3         equ   H'24'   ; delay counter
FREQ_SET      equ   H'25'   ; frequency set value
STATE         equ   H'26'   ; push pull port output selector
CYCLE1         equ   H'27'   ; cycle counter ms
CYCLE2         equ   H'28'   ; cycle counter ls   
SWEEP_STEP      equ   H'29'   ; sweep steps counter
SWEEP_BAND      equ   H'2A'   ; sweep bands
DEAD_TIME      equ   H'2B'   ; dead time counter   
GAP            equ   H'2C'   ; gap flag
      
; ******************************************************************

; start at memory 0

   org      0         ; reset vector
   goto   MAIN
   nop
   nop
   nop      ;
   org     4         ; interrupt vector
   nop

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

;lookup table for frequency sweep including overlapping

SWEEP
   addwf   PCL,f      ; add w to program counter

; 14 bands as per this table. Values are for timer 1 counter. Within each band are
; 12 frequencies at 200ns apart.                            
; one sequence
   retlw   D'148'      ; 19.08 to 20.0kHz ~83Hz spacing
   retlw   D'173'      ; 23.58 to 25.00kHz
   retlw   D'158'      ; 20.66 to 21.7kHz ~94Hz spacings
   retlw   D'168'      ; 22.5 to 23.8kHz ~118Hz spacings
   retlw   D'213'      ; 37.87 to 41.66kHz ~344Hz
   retlw   D'163'      ; 21.55 to 22.7kHz
   retlw   D'208'      ; 35.21 to 38.46kHz
   retlw   D'178'      ; 24.75 to 26.31kHz ~141Hz spacings
   retlw   D'183'      ; 26.04 to 27.77kHz
   retlw   D'153'      ; 19.8 to 20.8kHz
   retlw   D'213'      ; 37.87 to 41.66kHz ~344Hz
   retlw   D'188'      ; 27.47 to 29.41kHz ~175Hz spacings
   retlw   D'193'      ; 29.06 to 31.25kHz
   retlw   D'198'      ; 30.86 to 33.33kHz ~224Hz
   retlw   D'203'      ; 32.89 to 35.71kHz ~256Hz
   retlw   D'208'      ; 35.21 to 38.46kHz
; two sequence   
   retlw   D'188'      ; 27.47 to 29.41kHz ~175Hz spacings
   retlw   D'193'      ; 29.06 to 31.25kHz
   retlw   D'198'      ; 30.86 to 33.33kHz ~224Hz
   retlw   D'203'      ; 32.89 to 35.71kHz ~256Hz
   retlw   D'208'      ; 35.21 to 38.46kHz
   retlw   D'213'      ; 37.87 to 41.66kHz ~344Hz
   retlw   D'168'      ; 22.5 to 23.8kHz ~118Hz spacings
   retlw   D'173'      ; 23.58 to 25.00kHz
   retlw   D'178'      ; 24.75 to 26.31kHz ~141Hz spacings
   retlw   D'208'      ; 35.21 to 38.46kHz
   retlw   D'183'      ; 26.04 to 27.77kHz
   retlw   D'148'      ; 19.08 to 20.0kHz ~83Hz spacing
   retlw   D'153'      ; 19.8 to 20.8kHz
   retlw   D'158'      ; 20.66 to 21.7kHz ~94Hz spacings
   retlw   D'163'      ; 21.55 to 22.7kHz
   retlw   D'213'      ; 37.87 to 41.66kHz ~344Hz
; Three sequence
   retlw   D'198'      ; 30.86 to 33.33kHz ~224Hz
   retlw   D'203'      ; 32.89 to 35.71kHz ~256Hz
   retlw   D'148'      ; 19.08 to 20.0kHz ~83Hz spacing
   retlw   D'183'      ; 26.04 to 27.77kHz
   retlw   D'153'      ; 19.8 to 20.8kHz
   retlw   D'208'      ; 35.21 to 38.46kHz
   retlw   D'213'      ; 37.87 to 41.66kHz ~344Hz
   retlw   D'158'      ; 20.66 to 21.7kHz ~94Hz spacings
   retlw   D'163'      ; 21.55 to 22.7kHz
   retlw   D'173'      ; 23.58 to 25.00kHz
   retlw   D'208'      ; 35.21 to 38.46kHz
   retlw   D'168'      ; 22.5 to 23.8kHz ~118Hz spacings
   retlw   D'213'      ; 37.87 to 41.66kHz ~344Hz
   retlw   D'178'      ; 24.75 to 26.31kHz ~141Hz spacings
   retlw   D'188'      ; 27.47 to 29.41kHz ~175Hz spacings
   retlw   D'193'      ; 29.06 to 31.25kHz
; Four sequence
   retlw   D'158'      ; 20.66 to 21.7kHz ~94Hz spacings
   retlw   D'163'      ; 21.55 to 22.7kHz
   retlw   D'168'      ; 22.5 to 23.8kHz ~118Hz spacings
   retlw   D'148'      ; 19.08 to 20.0kHz ~83Hz spacing
   retlw   D'208'      ; 35.21 to 38.46kHz
   retlw   D'213'      ; 37.87 to 41.66kHz ~344Hz
   retlw   D'213'      ; 37.87 to 41.66kHz ~344Hz
   retlw   D'183'      ; 26.04 to 27.77kHz
   retlw   D'188'      ; 27.47 to 29.41kHz ~175Hz spacings
   retlw   D'193'      ; 29.06 to 31.25kHz
   retlw   D'198'      ; 30.86 to 33.33kHz ~224Hz
   retlw   D'173'      ; 23.58 to 25.00kHz
   retlw   D'203'      ; 32.89 to 35.71kHz ~256Hz
   retlw   D'208'      ; 35.21 to 38.46kHz
   retlw   D'153'      ; 19.8 to 20.8kHz
   retlw   D'178'      ; 24.75 to 26.31kHz ~141Hz spacings

MAIN
   bcf      STATUS,RP0   ; select memory bank 0

; set inputs/outputs
   clrf   GPIO      ; outputs low
   movlw   B'00000111'   ; comparators off
   movwf   CMCON
   bsf      STATUS,RP0   ; select memory bank 1
   movlw   B'00000000'   ; pullups off
   movwf   WPU
   movlw   B'00101100'   ; outputs/inputs set
   movwf   TRISIO      ; port data direction register
   movlw   B'10000000'   ; settings (pullups disabled)
   movwf   OPTION_REG

; analog inputs, A/D
   movlw   B'01100100'   ; AN2 analog input
   movwf   ANSEL
   bcf      STATUS,RP0   ; select memory bank 0
   movlw   B'00001000'   ; channel2 left justified, VDD ref etc
   movwf   ADCON0
   bsf      ADCON0,ADON   ; A/D on
   clrf   T1CON
   bsf      T1CON,0      ; timer 1 on
   bcf      PIR1,TMR1IF   ; clear timer 1 overflow
   
TIME_0
   bcf      INTCON,T0IF

; initial conditions
   movlw   B'00000000'   ; port low
   movwf   GPIO
   movlw   D'11'   
   movwf   SWEEP_STEP   ; sweep step counter
   movlw   D'63'
   movwf   SWEEP_BAND   ; number of frequency bands   14, used bands 16 (2 repeated) 4 sequences

; start up delay ~2s
   movlw   D'70'      ; delay extension
   movwf    STORE3
DEL_CONT
   movlw   H'FF'      ; delay routine
   call   DELAYX
   decfsz   STORE3,f   ; when delay extension is 0 exit
   goto   DEL_CONT

   bcf      PIR1,TMR1IF   ; timer 1 interrupt flag clear

; measure battery Voltage. No drive if below 11.5V
; channel 2
BATT
   call   ACQUIRE_AD
   movf   ADRESH,w   ; look at value 11.5V = 3.83V and D195
   sublw   D'195'      ; if negative then drive ok
   btfss   STATUS,C
   goto   DRIVE
NO_DRV
   bcf      GPIO,GP0
   bcf      GPIO,GP1   ; ensure drive is off
   call   DELAYms
   call   ACQUIRE_AD
   movf   ADRESH,w   ; look at value 12V = 4V and D204
   sublw   D'204'      ; if negative then drive ok
   btfsc   STATUS,C
   goto   NO_DRV      ; no output when battery low

DRIVE

; sweep cycle
   incf   SWEEP_BAND,f; frequency band
   movf   SWEEP_BAND,w
   sublw   D'63'      ; 14 bands plus two duplicated and 4 sequences
   btfsc   STATUS,C
   goto   IN_SWEEP
; if > set at 0 again
   clrf   SWEEP_BAND
IN_SWEEP
   movf   SWEEP_BAND,w
   call   SWEEP      ; lookup value (sweep is frequency range for each burst)
; Total frequency range
   movwf   FREQ_SET   ; frequency set value

; Set cycle counter for number of cycles delivered per tone burst
   movlw   H'3'      ; D1000
   movwf   CYCLE1
   movlw   H'E8'
   movwf   CYCLE2

DUTY ; duty period

   bcf      PIR1,TMR1IF   ; clear flag
; check pulse counters
   decf   CYCLE2,f
   movf   CYCLE2,f    ; check ls
   btfsc   STATUS,Z   ; if zero decrease ms byte
   decfsz   CYCLE1,f   ; if zero end of cycles
   goto   OUT_DRV      ; output driver

; check sweep steps
   movf   SWEEP_STEP,w
   btfsc   STATUS,Z   ; when zero end of bursts
   goto   END_BURST   ; end of cycle burst

; Set cycle counter for number of cycles delivered per tone burst
   movlw   H'3'      ;
   movwf   CYCLE1
   movlw   H'E8'
   movwf   CYCLE2
; count down sweep steps
   decf   SWEEP_STEP,f; next frequency
   goto   OUT_DRV      ; output driver

; end of cycle burst period
END_BURST
   movlw   D'11'      ;
   movwf   SWEEP_STEP   ; reset sweep step value
; cycle till end of frequency half period
WAIT1
   btfss   PIR1,TMR1IF   ; timer flag
   goto   WAIT1
; cycle loop

   clrf   GPIO      ; driver cleared
;
; Alternate gap or next burst
   incf   GAP,f
   btfss   GAP,0
   goto   DRIVE
               
; end of cycle burst
   movlw   D'20'      ; D20 delay extension
   movwf    STORE3
DEL_CONT1
   movlw   H'FF'      ; delay routine
   call   DELAYX
   decfsz   STORE3,f   ; when delay extension is 0 exit
   goto   DEL_CONT1
   goto   BATT

CHK_COUNT; divide into steps for a frequency sweep

; output driver
OUT_DRV
   incf   STATE,f      ; toggle output selector for GP0 or GP1 using bit 0

;**** following 14 instructions must not cross page boundary ****
; Check addresses in listing file.

INCREMENT
   movf   SWEEP_STEP,w; allows 200ns changes to frequency
   addwf   PCL,f
   goto   ONE
   goto   TWO
   goto   THREE
   goto   FOUR
   goto   FIVE
   goto   SIX
   goto   SEVEN
   goto   EIGHT
   goto   NINE
   goto   TEN
   goto   ELEVEN
   goto   TWELVE
; ** end of page boundary restriction
TWELVE
   btfss   PIR1,TMR1IF   ; timer flag
   goto   TWELVE
   nop
   nop
   nop
   nop
   nop
   clrf   GPIO      ; driver cleared after wait period
; add 'nop's for extra dead period
; set output   
   btfsc   STATE,0      ; if 0 was set set 1
   goto   SET12
   nop               ; extra frequency adjust
   nop               ; equalise dead time
; end of dead time
   goto   RESET_TIMER0
SET12
; end of dead time
   goto   RESET_TIMER1
ELEVEN
   btfss   PIR1,TMR1IF   ; timer flag
   goto   ELEVEN
   nop
   nop
   nop
   nop
   nop
   clrf   GPIO      ; driver cleared after wait period
   ; add 'nop's for extra dead period
; set output   
   btfsc   STATE,0      ; if 0 was set set 1
   goto   SET11
   nop               ; equalise dead time
; end of dead time
   goto   RESET_TIMER0
SET11
; end of dead time
   goto   RESET_TIMER1
TEN
   btfss   PIR1,TMR1IF   ; timer flag
   goto   TEN
   nop
   nop
   nop
   nop
   clrf   GPIO      ; driver cleared after wait period
   ; add 'nop's for extra dead period
; set output   
   btfsc   STATE,0      ; if 0 was set set 1
   goto   SET10
   nop               ; equalise dead time
; end of dead time
   goto   RESET_TIMER0
SET10
   nop               ; extra frequency adjust
; end of dead time
   goto   RESET_TIMER1
NINE
   btfss   PIR1,TMR1IF   ; timer flag
   goto   NINE
   nop
   nop
   nop
   nop
   clrf   GPIO      ; driver cleared after wait period
   ; add 'nop's for extra dead period
; set output   
   btfsc   STATE,0      ; if 0 was set set 1
   goto   SET9
   nop               ; equalise dead time
; end of dead time
   goto   RESET_TIMER0
SET9
; end of dead time
   goto   RESET_TIMER1
EIGHT
   btfss   PIR1,TMR1IF   ; timer flag
   goto   EIGHT
   nop
   nop
   nop
   clrf   GPIO      ; driver cleared after wait period
   ; add 'nop's for extra dead period
; set output   
   btfsc   STATE,0      ; if 0 was set set 1
   goto   SET8
   nop
   nop               ; equalise dead time
; end of dead time
   goto   RESET_TIMER0
SET8
; end of dead time
   goto   RESET_TIMER1
SEVEN
   btfss   PIR1,TMR1IF   ; timer flag
   goto   SEVEN
   nop
   nop
   nop
   clrf   GPIO      ; driver cleared after wait period
   ; add 'nop's for extra dead period
; set output   
   btfsc   STATE,0      ; if 0 was set set 1
   goto   SET7
   nop               ; equalise dead time
; end of dead time
   goto   RESET_TIMER0
SET7
; end of dead time
   goto   RESET_TIMER1
SIX
   btfss   PIR1,TMR1IF   ; timer flag
   goto   SIX
   nop
   nop
   clrf   GPIO      ; driver cleared after wait period
   ; add 'nop's for extra dead period
; set output   
   btfsc   STATE,0      ; if 0 was set set 1
   goto   SET6
   nop               ; equalise dead time
; end of dead time
   goto   RESET_TIMER0
SET6
   nop               ; extra frequency adjust
   goto   RESET_TIMER1
FIVE
   btfss   PIR1,TMR1IF   ; timer flag
   goto   FIVE
   nop
   nop
   clrf   GPIO      ; driver cleared after wait period
   ; add 'nop's for extra dead period
; set output   
   btfsc   STATE,0      ; if 0 was set set 1
   goto   SET5
   nop               ; equalise dead time
; end of dead time
   goto   RESET_TIMER0
SET5
; end of dead time
   goto   RESET_TIMER1

FOUR
   btfss   PIR1,TMR1IF   ; timer flag
   goto   FOUR
   nop
   clrf   GPIO      ; driver cleared after wait period
   ; add 'nop's for extra dead period
; set output   
   btfsc   STATE,0      ; if 0 was set set 1
   goto   SET4
   nop               ; extra frequency adjust
   nop               ; equalise dead time
; end of dead time
   goto   RESET_TIMER0
SET4
; end of dead time
   goto   RESET_TIMER1

THREE
   btfss   PIR1,TMR1IF   ; timer flag
   goto   THREE
   nop
   clrf   GPIO      ; driver cleared after wait period
   ; add 'nop's for extra dead period
; set output   
   btfsc   STATE,0      ; if 0 was set set 1
   goto   SET3
   nop               ; equalise dead time
; end of dead time
   goto   RESET_TIMER0
SET3
; end of dead time
   goto   RESET_TIMER1

TWO
   btfss   PIR1,TMR1IF   ; timer flag
   goto   TWO
   clrf   GPIO      ; driver cleared after wait period
   ; add 'nop's for extra dead period
; set output   
   btfsc   STATE,0      ; if 0 was set set 1
   goto   SET2
   nop               ; equalise dead time
; end of dead time

   goto   RESET_TIMER0
SET2
   nop               ; extra frequency adjust
; end of dead time
   goto   RESET_TIMER1 ; 

ONE   btfss   PIR1,TMR1IF   ; timer flag
   goto   ONE
   clrf   GPIO      ; driver cleared after wait period
; add 'nop's for extra dead period
; set output   
   btfsc   STATE,0      ; if 0 was set set 1
   goto   SET1
   nop               ; equalise dead time
; end of dead time
   goto   RESET_TIMER0
SET1
; end of dead time
   goto   RESET_TIMER1   ; (required instruction for cycle timing)

; reset timer
RESET_TIMER0
   
   comf   TMR1H,f      ; ms byte set
   movf   FREQ_SET,w   ; ls byte set
   bcf      T1CON,0      ; timer 1 off
   movwf   TMR1L
   bsf      T1CON,0      ; timer 1 on
; add extra dead time
   movlw   D'5'
   movwf   DEAD_TIME
DEC_DEAD1
   decfsz   DEAD_TIME,f
   goto   DEC_DEAD1
   bsf      GPIO,GP0   ; set 0 output
   goto   DUTY

; reset timer
RESET_TIMER1
   
   comf   TMR1H,f      ; ms byte set
   movf   FREQ_SET,w   ; ls byte set
   bcf      T1CON,0      ; timer 1 off
   movwf   TMR1L
   bsf      T1CON,0      ; timer 1 on
; add extra dead time
   movlw   D'5'
   movwf   DEAD_TIME
DEC_DEAD2
   decfsz   DEAD_TIME,f
   goto   DEC_DEAD2
   bsf      GPIO,GP1   ; set 1 output
   goto   DUTY

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

; Subroutines

; delay loop

DELAYms
   movlw   D'23'      ; delay value
DELAYX
   movwf   STORE1      ; STORE1 is number of loops value
LOOP8   
   movlw   H'B0'
DELDSP
   movwf   STORE2      ; STORE2 is internal loop value   
LOOP9
   decfsz   STORE2,f
   goto   LOOP9
   decfsz   STORE1,f
   goto   LOOP8
   return

; subroutine to wait for A/D conversion
ACQUIRE_AD
   bsf      ADCON0,GO_DONE   ; GO/DONE bit start conversion
WAIT_CONV
   btfsc   ADCON0,GO_DONE   ; conversion complete when cleared ~11 cycles
   goto   WAIT_CONV
   return



   end

Kabil ATICI

bu programı senin istediğin gibi değiştirmek yeniden yazmaktan daha zor görünüyor.
Eğer beslemen sabitse örneğin adc bölümü iptal edilebilir. Buradaki sıkıntı sürekli olarak darbe frekansının kayması gibi görünüyor. Çünkü amaç o. Yani hem timer1 hem de timer0 kullanılmış. Ve de ek zamanlayıcı çevrimleri eklenmiş..

Senin için sadece timer1 veya timer 0 kullanarak 80KHz sinyal üretmek ve her kesme geldiğinde çıkışı değiştirmek.

Pic kullanmadan da yapabilirsin. 80KHz sinyali üretip örneğin bir 74LS74 veya 74LS73 entegresini kullanarak istediğini yapabilirsin. Devren biraz daha büyük olur.
ambar7

mas

Hocam cevabınız için teşekkürler. Söylediğiniz gibi frekans sürekli değişiyor. Ben daha önce jal dili kullanarak bir kaç deneme yaptım. Gecikme 1mikro saniye nin altına düşemediğinden 40 khz ilk sinyal üretemedim. Trafodan 40 khz lik ac sinyal almam için 80 khz ile mi sürmem gerekiyor? Birde yukarıdaki program hakkında bilginiz varsa biraz açıklama yapabilirmisiniz? Trafo tam olarak nasıl sürülüyor adc ne için kullanılmış vs gibi.
Filp flop kullanmayı bende düşündüm 4017 ile bir deneme yaptım. Simülasyonda çalışıyor ancak pals genişliği ayarlanamıyor. 7474 kullanmadım sanırım onda da durum aynı olur. Yazılım ile bu işi daha kolay çözebilirim gibi. Olmadı 494 gibi bir entegre kullanıcam. Tekrardan teşekkürler.

Kabil ATICI

Asm haricindeki dillerde kodların karşılığında çok fazla kod gömüldüğü için istenilen sonuca ulaşmakta bazı sorunlara neden olabiliyor.

Şemadeki Trafon Verimli bir şekilde tam dalga oluşturmak için kullanılan bir devre şeklidir. Yani sonuçta 80KHz sinyalin yarısında  diyelim ki pozitif alternaslar sürülürken(örneğin Q1) kalan yarısında da negatif alternanslar (o zaman Q2) sürülür. Bu işlem sırayla gerçekleştiğinden tam dalga oluşturulur. Yani buradaki devre ff ile sürüldüğünde (bunu doğrudan 40KHz yaptığında uygulanan  örneğin sinyalin lojik "1" olduğu zaman Q1 sürülürken sinyalin lojik "0" olduğu zaman Q2 sürülürmesi gerekir o zaman karmaşık bir sürücü devresi gerektirir. ) ff'un girişine gelen bir darbede Q1 iletime geçerken, bir sonraki darbede Q1 kapanır ve Q2 iletime geçer. Bu şekilde senin sürmede kullandığın darbelerin genişliği ne olursa olsun çıkışta eşit altenanslara sahip bir sinyal elde edersin.

Bu sistemi 40KHz ilede sürebilirsin yukarıda anlattığım gibi örneğin sinyalin lojik "1" olduğu zaman Q1 sürülürken sinyalin lojik "0" olduğu zaman Q2 sürülürmesi gerekir. İş asılda bir NOT kapısı ile de çözülebilir.

ADC içinx; measure battery Voltage. No drive if below 11.5V
; channel 2
BATT

bölümünde bu devre akü ile kullanılması durumunda besleme geriliminin düşmesi durumunda aküyü veya devreyi korumak üzere sistem çalışmasını durdurması öngörülmüş...
ambar7