frekans ve duty ayarlı pwm sinyali

Başlatan huseyin0579, 30 Ekim 2016, 00:40:23

huseyin0579

Hocam hazır bir programı değiştirmek istedim. Amacım programdaki frekans ayarını 100hz ile 300hz arasında değiştirmek ve bunu şuan alt değer olarak 100hz görüyorum üst değer 2083hz bu değeri 500hz'e indiremedim. Hocam duty ayarında butona basılı tutunca sayım devam ediyor "while wend" işlemi bu frekans içinde aynı şekilde olacak yardımcı olabilir'misiniz. Orjinal dosyaları ekliyorum.
Orjinal kod;
'****************************************************************
'*  Name    : HPWM.BAS                                      *
'*  Author  : [Ferhat YOL]                                      *
'*  Notice  : Copyright (c) 2011 [Mucit23]                      *
'*          : All Rights Reserved                               *
'*  Date    : 03.04.2011                                        *
'*  Version : 1.0                                               *
'*  Notes   :                                                   *
'*          :                                                   *
'****************************************************************
DEFINE OSC 4
@ DEVICE pic16F876
@ DEVICE pic16F876, WDT_OFF
@ DEVICE pic16F876, PWRT_On
@ DEVICE pic16F876, PROTECT_OFF

TRISA=%11111111
TRISB=%00000000
TRISC=%00000000
PORTA=0
PORTB=0
PORTC=0

DEFINE LCD_DREG   PORTB
DEFINE LCD_DBIT   4
DEFINE LCD_RSREG  PORTB
DEFINE LCD_RSBIT  2
DEFINE LCD_EREG   PORTB
DEFINE LCD_EBIT   3
DEFINE LCD_BITS   4
DEFINE LCD_LINES  2

DEFINE CCP1_REG   PORTC
DEFINE CCP1_BIT   2

ON INTERRUPT GoTo KESME
ADCON1 = 7
OPTION_REG=%10000010   
INTCON=%10100001 
TMR0=0
T2CON = %00000110
PR2=124

SYMBOL YUKARI=PORTA.0
SYMBOL  ASAGI=PORTA.1
SYMBOL ARTTIR=PORTA.2
SYMBOL  AZALT=PORTA.3
SYMBOL    JOG=PORTA.4
SYMBOL    DUR=PORTA.5

ROLE  VAR PORTC.3
LED1  VAR PORTC.1
LED2  VAR PORTC.0

MODS     VAR BIT
YON      VAR BIT
U        VAR BYTE
W        VAR BYTE
ADR      VAR BYTE
SAYIH    VAR BYTE
SAYIL    VAR BYTE
SON      VAR BYTE
SYC      VAR BYTE
SNY      VAR BYTE
SAYAC    VAR BYTE
DUTY     VAR BYTE
I        VAR WORD
PERYOT   VAR WORD
HAM_DUTY VAR WORD
FREKANS  VAR WORD

PAUSE 200
LCDOUT $FE,1
GIRIS:
LCDOUT $FE,$83,"PWM MOTOR"
LCDOUT $FE,$C4,"KONTROL"
PAUSE 1500
LCDOUT $FE,1

DUTY=0:LED1=0:LED2=1

GOSUB FREKANS_HESAP
GOSUB EKRAN
GOSUB DUTY_YAZ
GOSUB PWM_ON

BASLA:
IF DUTY>0 THEN
IF JOG=0 AND YON=0 THEN
  YON=1
  SON=DUTY
  GOTO SAG
ENDIF

IF JOG=0 AND YON=1 THEN
YON=0
SON=DUTY
GOTO SOL
ENDIF
ENDIF

IF DUR=0 and duty>0 THEN
GOTO DURDUR
ENDIF

GOSUB FREKANS_HESAP
GOSUB DUTY_KONTROL
GOSUB FREKANS_KONTROL

GOTO BASLA

FREKANS_KONTROL:

IF ARTTIR=0 THEN
WHILE ARTTIR=0:WEND
PR2=PR2-1
gosub DUTY_YAZ
IF PR2<5 THEN PR2=5

ENDIF

IF AZALT=0 THEN
WHILE AZALT=0:WEND
PR2=PR2+1
gosub DUTY_YAZ
IF PR2>124 THEN PR2=124
ENDIF
GOSUB EKRAN
RETURN

DUTY_KONTROL:
IF YUKARI=0 THEN
sayac=0
DUTY=DUTY+1
IF DUTY=101 THEN DUTY=100
gosub DUTY_YAZ:GOSUB EKRAN
WHILE YUKARI=0
W=1
IF SAYAC=>50 THEN
   W=0:SAYAC=50
   DUTY=DUTY+1:GOSUB DELAY
   IF DUTY=101 THEN DUTY=100
ENDIF
GOSUB DUTY_YAZ
GOSUB EKRAN
WEND
W=0:SAYAC=0
ELSE
W=0:SAYAC=0
ENDIF

IF ASAGI=0 THEN
sayac=0
DUTY=DUTY-1
IF DUTY=255 THEN DUTY=0
GOSUB DUTY_YAZ
GOSUB EKRAN
WHILE ASAGI=0
W=1
IF SAYAC=>30 THEN
   W=0:SAYAC=30
   DUTY=DUTY-1:GOSUB DELAY
   IF DUTY=255 THEN DUTY=0
ENDIF
GOSUB DUTY_YAZ
GOSUB EKRAN
WEND
W=0
ELSE
W=0:SAYAC=0
ENDIF
 
RETURN

SAG:
DUTY=DUTY-1:GOSUB DELAY
IF DUTY>100 THEN
ROLE=1:LED1=1:LED2=0
GOTO DUTY_ARTTIR
ENDIF
GOSUB DUTY_YAZ:GOSUB EKRAN
GOTO SAG

DUTY_ARTTIR:
DUTY=DUTY+1:GOSUB DELAY
GOSUB DUTY_YAZ:GOSUB EKRAN
IF DUTY=SON THEN
GOTO BASLA
ENDIF
GOTO DUTY_ARTTIR

DURDUR:
DUTY=DUTY-1:GOSUB DELAY
GOSUB DUTY_YAZ:GOSUB EKRAN
IF DUTY=0 THEN
GOTO BASLA
ENDIF
GOTO DURDUR

SOL:
DUTY=DUTY-1:GOSUB DELAY
IF DUTY>100 THEN
ROLE=0:LED1=0:LED2=1
GOTO DUTY_ARTTIR
ENDIF
GOSUB DUTY_YAZ:GOSUB EKRAN
GOTO SOL


DELAY: 'gecıkme
  FOR I=0 TO 255:NEXT
RETURN
DELAY1:
  FOR I=0 TO 150:NEXT
RETURN

FREKANS_HESAP:
FREKANS=62500/(PR2+1)
RETURN

DUTY_YAZ:
HAM_DUTY=(PR2+1)*DUTY/25
CCP1CON.4=ham_DUTY.0
CCP1CON.5=HAM_DUTY.1
CCPR1L=HAM_DUTY>>2
return

PWM_ON:
CCP1CON.2=1
CCP1CON.3=1
RETURN

PWM_OFF:
CCP1CON.2=0
CCP1CON.3=0
RETURN

EKRAN:
LCDOUT $FE,$80,"Duty %",#DUTY
IF DUTY<100 THEN
GOSUB HANE_AL1
LCDOUT $FE,ADR,$20
ENDIF
lcdout $fe,$C0,"FREKANS=",#FREKANS
GOSUB HANE_AL2
RETURN

HANE_AL1:
IF DUTY<100 OR DUTY>9 THEN ADR=$88
IF DUTY<10 THEN ADR=$87
RETURN
HANE_AL2:
IF FREKANS>10000 THEN LCDOUT $FE,$CD,"Hz"
IF FREKANS<10000 AND FREKANS>999 THEN LCDOUT $FE,$CC,"Hz "
IF FREKANS<1000 THEN LCDOUT $FE,$CB,"Hz "
RETURN

DISABLE
KESME:
IF W=1 THEN
      SAYAC=SAYAC+1
      IF SAYAC=101 THEN SAYAC=0    
ENDIF
INTCON.2=0   
RESUME
ENABLE

END
           


hazırladığım kod;
'****************************************************************
'*  Name    : HPWM.BAS                                      *
'*  Author  : [Ferhat YOL]                                      *
'*  Notice  : Copyright (c) 2011 [Mucit23]                      *
'*          : All Rights Reserved                               *
'*  Date    : 03.04.2011                                        *
'*  Version : 1.0                                               *
'*  Notes   :                                                   *
'*          :                                                   *
'****************************************************************
DEFINE OSC 4
@ DEVICE pic16F876
@ DEVICE pic16F876, WDT_OFF
@ DEVICE pic16F876, PWRT_On
@ DEVICE pic16F876, PROTECT_OFF

TRISA=%11111111
TRISB=%00000000
TRISC=%00000000
PORTA=0
PORTB=0
PORTC=0

DEFINE LCD_DREG   PORTB
DEFINE LCD_DBIT   4
DEFINE LCD_RSREG  PORTB
DEFINE LCD_RSBIT  2
DEFINE LCD_EREG   PORTB
DEFINE LCD_EBIT   3
DEFINE LCD_BITS   4
DEFINE LCD_LINES  2

DEFINE CCP1_REG   PORTC
DEFINE CCP1_BIT   2

ON INTERRUPT GoTo KESME
ADCON1 = 7
OPTION_REG=%10000010   
INTCON=%10100001 
TMR0=0
T2CON = %00000110
PR2=124

SYMBOL YUKARI=PORTA.0
SYMBOL  ASAGI=PORTA.1
SYMBOL ARTTIR=PORTA.2
SYMBOL  AZALT=PORTA.3
SYMBOL    JOG=PORTA.4
SYMBOL    DUR=PORTA.5

ROLE  VAR PORTC.3
LED1  VAR PORTC.1
LED2  VAR PORTC.0

MODS     VAR BIT
YON      VAR BIT
U        VAR BYTE
W        VAR BYTE
ADR      VAR BYTE
SAYIH    VAR BYTE
SAYIL    VAR BYTE
SON      VAR BYTE
SYC      VAR BYTE
SNY      VAR BYTE
SAYAC    VAR BYTE
DUTY     VAR BYTE
I        VAR WORD
PERYOT   VAR WORD
HAM_DUTY VAR WORD
FREKANS  VAR WORD

PAUSE 200
LCDOUT $FE,1
GIRIS:
LCDOUT $FE,$83,"PWM MOTOR"
LCDOUT $FE,$C4,"KONTROL"
PAUSE 1500
LCDOUT $FE,1

DUTY=0:LED1=0:LED2=1

GOSUB FREKANS_HESAP
GOSUB EKRAN
GOSUB DUTY_YAZ
GOSUB PWM_ON

BASLA:
IF DUTY>0 THEN
IF JOG=0 AND YON=0 THEN
  YON=1
  SON=DUTY
  GOTO SAG
ENDIF

IF JOG=0 AND YON=1 THEN
YON=0
SON=DUTY
GOTO SOL
ENDIF
ENDIF

IF DUR=0 and duty>0 THEN
GOTO DURDUR
ENDIF

GOSUB FREKANS_HESAP
GOSUB DUTY_KONTROL
GOSUB FREKANS_KONTROL

GOTO BASLA

FREKANS_KONTROL:

IF ARTTIR=0 THEN
WHILE ARTTIR=0
PR2=PR2-1
gosub DUTY_YAZ
IF PR2<5 THEN PR2=5
PAUSE 300
GOSUB EKRAN
WEND

ENDIF

IF AZALT=0 THEN
WHILE AZALT=0
PR2=PR2+1
gosub DUTY_YAZ
IF PR2>124 THEN PR2=124
PAUSE 300
GOSUB EKRAN
WEND

ENDIF
RETURN

DUTY_KONTROL:
IF YUKARI=0 THEN
sayac=0
DUTY=DUTY+1
IF DUTY=101 THEN DUTY=100
gosub DUTY_YAZ:GOSUB EKRAN
WHILE YUKARI=0
W=1
IF SAYAC=>50 THEN
   W=0:SAYAC=50
   DUTY=DUTY+1:GOSUB DELAY
   IF DUTY=101 THEN DUTY=100
ENDIF
GOSUB DUTY_YAZ
GOSUB EKRAN
WEND
W=0:SAYAC=0
ELSE
W=0:SAYAC=0
ENDIF

IF ASAGI=0 THEN
sayac=0
DUTY=DUTY-1
IF DUTY=255 THEN DUTY=0
GOSUB DUTY_YAZ
GOSUB EKRAN
WHILE ASAGI=0
W=1
IF SAYAC=>30 THEN
   W=0:SAYAC=30
   DUTY=DUTY-1:GOSUB DELAY
   IF DUTY=255 THEN DUTY=0
ENDIF
GOSUB DUTY_YAZ
GOSUB EKRAN
WEND
W=0
ELSE
W=0:SAYAC=0
ENDIF
 
RETURN

SAG:
DUTY=DUTY-1:GOSUB DELAY
IF DUTY>100 THEN
ROLE=1:LED1=1:LED2=0
GOTO DUTY_ARTTIR
ENDIF
GOSUB DUTY_YAZ:GOSUB EKRAN
GOTO SAG

DUTY_ARTTIR:
DUTY=DUTY+1:GOSUB DELAY
GOSUB DUTY_YAZ:GOSUB EKRAN
IF DUTY=SON THEN
GOTO BASLA
ENDIF
GOTO DUTY_ARTTIR

DURDUR:
DUTY=DUTY-1:GOSUB DELAY
GOSUB DUTY_YAZ:GOSUB EKRAN
IF DUTY=0 THEN
GOTO BASLA
ENDIF
GOTO DURDUR

SOL:
DUTY=DUTY-1:GOSUB DELAY
IF DUTY>100 THEN
ROLE=0:LED1=0:LED2=1
GOTO DUTY_ARTTIR
ENDIF
GOSUB DUTY_YAZ:GOSUB EKRAN
GOTO SOL


DELAY: 'gecıkme
  FOR I=0 TO 255:NEXT
RETURN
DELAY1:
  FOR I=0 TO 150:NEXT
RETURN

FREKANS_HESAP:
FREKANS=12500/(PR2+1)
RETURN

DUTY_YAZ:
HAM_DUTY=(PR2+1)*DUTY/25
CCP1CON.4=ham_DUTY.0
CCP1CON.5=HAM_DUTY.1
CCPR1L=HAM_DUTY>>2
return

PWM_ON:
CCP1CON.2=1
CCP1CON.3=1
RETURN

PWM_OFF:
CCP1CON.2=0
CCP1CON.3=0
RETURN

EKRAN:
LCDOUT $FE,$80,"Duty %",#DUTY
IF DUTY<100 THEN
GOSUB HANE_AL1
LCDOUT $FE,ADR,$20
ENDIF
lcdout $fe,$C0,"FREKANS=",#FREKANS
GOSUB HANE_AL2
RETURN

HANE_AL1:
IF DUTY<100 OR DUTY>9 THEN ADR=$88
IF DUTY<10 THEN ADR=$87
RETURN
HANE_AL2:
IF FREKANS>10000 THEN LCDOUT $FE,$CD,"Hz"
IF FREKANS<10000 AND FREKANS>999 THEN LCDOUT $FE,$CC,"Hz "
IF FREKANS<1000 THEN LCDOUT $FE,$CB,"Hz "
RETURN

DISABLE
KESME:
IF W=1 THEN
      SAYAC=SAYAC+1
      IF SAYAC=101 THEN SAYAC=0    
ENDIF
INTCON.2=0   
RESUME
ENABLE

END
           

huseyin0579

#1
Hocam frekans ayar bölümünde pause 300 bu gecikme komutu istediğim gibi olmadı bu komut iptal edilince artış ve azalma değerleri orantılı yani "100hz -101hz - 102hz" butona basılması ile artış ve azalma değerleri bu şekilde oluyor maksimum üst değer 2083 ve bu değer 500hz olmalı bu üst sınır değeri TMR0 ve PR2 değerleri ile ayarlamak gerekiyor galiba hocam bu ayar bölümünde duty ayarındaki gibi while wend döngüsü çalışması gerekiyor. Hocam bu frekans ayarı gerçek ortamda doğru çalışır mı daha önceki yazılarınız da bu şekilde çalışmanın zor olabileceğini yazmışsınız yani alt ve üst değerleri ayarlanabilen frekans aralığında çalışabilirmi ?

ete

Donanımsal PWM sinyal frekansı 4Mhz çalışma frekansında en düşük 245 Hz olabilir daha altına inemez.
Inmesi için çalışma frekansını düşürmeniz gerekir.
Bu gibi programları yazaken daima limitlerinizi bilmeniz gerekir. Bu limitleri bilmenin en güzel yollarından biriside PicMultiCalc.exe isimli programcık tır. Sitede ararsanız link vs bulabilirsiniz yada direk internetten de bulabilirsiniz.
Bu programı çalıştırıp PWM Calc butonuna tıklarsanız size çalışma frekansı duty değeriniz ve istediğiniz frekans değerini HZ yada KHZ olarak girebileceğiniz kutucuklar verir. Buralara gerekli bilgileri yazarsanız bölme oranlarına göre, çözünürlük, frekans, max duty değeri , PR2 değeri gibi önemli bilgiler verir.
Önce min frekansınızı girersiniz bu frekans için gerekli bölme oranı ile PR2 değerlerini not edersiniz.
Sonra maksimum frekansı girersiniz ve bu frekans için gerekli olan PR2 ve bölme oranları ile max duty değerini not edersiniz.
Görüleceği gibi frekansı değiştirmek için aynı bölme oranını (Prescaler) kullanmak şartı ile PR2 değerini değiştirmek gerektiğini anlarsınız. PR2 değeri ile frekans arasında ters orantı vardır. PR2 arttıkça frekans küçülür azaldıkça frekans büyür.
Şimdi senin sisteminde min frekans 100 olsun maksimum 300 olsun istediğine göre bunu 250-450 aralığında kullanmak belkide daha uygun olacaktır. Çünki 100 Hz e düşmek için işlemci frekansı en fazla 1Mhz olmalı.
DC Motor kontrollerinde en düşük frekans bana göre 5Khz olmalı hatta mümkünse 5-10Khz aralığında bir değer seçilmelidir. Zira düşük frekanslarda motor inleyerek çalışacaktır. Dediğim aralıkta ise sorunsuz çalışır.
Step motorlar için bu sistemi CLK kaynağı olarak kullanacaksanız ya çift işlemci kullanıp PWM işini 8 bacaklı bir işlemciye yaptıracaksınız yada dediğim gibi frekansı düşüreceksiniz. Yada motoru yarım adımlık modda çalıştırarak gerekli frekansı iki katına çıkarmak gerekir.

Ete


huseyin0579

Hocam mantıklı olurmu bilemem ama bu istenen frekans ayarını led flash şeklinde calıştırdığımız bir pini for-next döngüsü ile çalışacak şekilde alt program olsa ve bu alt program içerisinde elde edilen flash işlemi ile pwm sinyali  çıkış pini aynı pin oluyor. Hocam bu işlem sonuçta yazılımsal pwm olacak, hocam döngüye değer verilen alt programda pin 1-0 durumu değişken frekans elde edilebilecek alternatif bir teknik olabilirmi hocam bu frekans ve duty ayarlı pwm işlemi yazılımsal olarak bu şekilde yapılabilir mi?

ete

Olabilir tabiiki ama yapabilirsen. Ben yapamam doğrusu. Yapamam derken zaman zaman kestirmeden gitmek amacı ile bu mantıkla bir şeyler yapmaya çalışrıım.Ama tecrübem bana hiç bir şekilde frekans vs tutturamayacağımı söylüyor.
Insana posteki saydırır bu iş. Vaktin var ise uğraş istersen.

Ete

mehmet

#5
http://eng-serve.com/pic/pic_timer.html
http://eng-serve.com/pic/pic_pwm.html

Burayı inceleyiniz. Belki daha iyi anlaşılır...
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
http://www.mehmetbilgi.net.tr
CC BY

Soner Aslantepe

#6
Kolay gelsin ete hocam konuyla alakalı bir soruda ben sorayım. DC-DC Converter'a ait mosfeti sürebilmek için PIC ile pwm üretmek istiyorum ancak bu devrenin dışardan pot veyahut butonlar vasıtasıyla, 1khz ve en az 100khz arasında frekansının ayarlanması ve aynı zamanda duty cycle (doluluk oranı) da %5 %95 gibi ayarlanması gerekiyor programlamada yeni yeni kendimi geliştiriyorum. Assembly alt yapım var ancak CCS C kullanıyorum. C diline ait nasıl bir kod yazmam gerekir ? Bununla alakalı yol gösterebilirmisiniz ? (Örnek kod paylaşımı)

ete

10 Bitlik PWM elde etme yöntemine bir bakılırsa derleyici diline bakmaksızın;
- T2CON registerine verilen bölme oranı
- PR2 registerine verilen
değerler ile Frekansı ayarlayıp
- CCPxCON registerine verilecek değer ilede duty değeri ayarlandığını görebilirsiniz.
Bu gibi durumlarda genellikle PicMultiCalc programını kullanarak hangi frekans aralığında çalışacağımı tespit ederim.
Senin frekans aralığın çok fazla. Benim bildiğim DC-DC konverterlerde frekans sabittir. Duty değiştirilerek çıkış ayarlanır.
Sen ise frekans da değiştirmek istiyorsun ki bunun sebebini anlayamadım. Hadi diyelimki frekans da değiştireceksin bu durumda aynı bölme oranını kullanarak min ve max frekans bulunarak arasında PR2 registerinin alacağı değere bakmak en uygun metod olur. Örnekle açıklayayım.
1 Khz lik bir frekans için; 1/4 bölme oranı ile PR2 değerimiz 249 olmaktadır.  Max Duty ise  1000 olacaktır
10 Khz lik bir frekans için 1/4 bölme oranı ile PR2 değerimiz 24 olmaktadır. Max Duty ise 100 olacaktır.
20 Khz lik bir frekans için 1/4 bölme oranı ile PR2 değerimiz 12 olmaktadır. Max Duty ise 50 olmaktadır.
40 Khz lik bir frekans için 1/4 bölme oranı ile PR2 değerimiz  5 olmakta ve Max Duty ise  25 olmaktadır.
Bundan sonrası pek kullanışlı olmayacaktır. Çözünürlüğü artırmak için bölme oranını değiştirmek gerekir. Bu ise programın universalliğini bozar niteliktedir.

Bu durumda 1 Khz ile 40 Khz aralığında bir frekans değiimi söz konusu olduğunda en güzeeli PR2 değerini 249 dan 5 e kadar düşürmek ve buna bağlı max duty değerini hesaplayarak (derslerde var) ona uygun işlem yapmak uygun olacaktır.
100Khz lik frekanslar için daha yüksek işlemci frekanslarnda çalışmak gerekir. Benzer mantıkla bunuda yapmak mümkün olur.

Maalesef CCSC de hiç çalışmadım ve çalışmıyorum. Bu nedenle derleyici bazında akıl vermem mümkün değil ama aklın yolu birdir deyip yukarıdaki açıklamalara göre kendin bir şeyler yapabilirsin.

Ete

Soner Aslantepe

Çok teşekkür ederim hocam emeğinize sağlık. Sizin derslerinizi baştan aşağı takip edip bu işi yapabilmeyi umuyorum kolay gelsin. Saygılarımla..

murathato

selamünaleyküm
arkadaşlar bana voltaj ve frekans ayarlı lcd göstergeli yüksek amper cıkışlı PWM voltaj devresi lazım interneti alt üst ettim 555 li ve swicmod ile yapılmış devreler var elinde olan varsa paylaşabilirmi teşekkürler


murathato

bu devre gibi bir devre lazım arabam cok yakmaya başladı hidrojenle calıştırmayı düşünüyorum

Powered by EzPortal